drv_usart.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-03-02 FMD-AE first version
  9. */
  10. #include "board.h"
  11. #include "drv_usart.h"
  12. #include "drv_config.h"
  13. #ifdef RT_USING_SERIAL
  14. //#define DRV_DEBUG
  15. #define LOG_TAG "drv.usart"
  16. #include <drv_log.h>
  17. #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2)
  18. #error "Please define at least one BSP_USING_UARTx"
  19. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  20. #endif
  21. #ifdef RT_SERIAL_USING_DMA
  22. static void ft32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
  23. #endif
  24. enum
  25. {
  26. #ifdef BSP_USING_UART1
  27. UART1_INDEX,
  28. #endif
  29. #ifdef BSP_USING_UART2
  30. UART2_INDEX,
  31. #endif
  32. };
  33. static struct ft32_uart_config uart_config[] =
  34. {
  35. #ifdef BSP_USING_UART1
  36. UART1_CONFIG,
  37. #endif
  38. #ifdef BSP_USING_UART2
  39. UART2_CONFIG,
  40. #endif
  41. };
  42. static struct ft32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
  43. void UART_MspInit(USART_TypeDef *USARTx)
  44. {
  45. GPIO_InitTypeDef GPIO_InitStruct;
  46. if (USARTx == USART1)
  47. {
  48. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  49. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  50. /*GPIO INIT*/
  51. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  52. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  53. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  54. GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  55. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  56. GPIO_Init(GPIOA, &GPIO_InitStruct);
  57. GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
  58. GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
  59. /* USART1 interrupt Init */
  60. NVIC_SetPriority(USART1_IRQn, 5);
  61. NVIC_EnableIRQ(USART1_IRQn);
  62. }
  63. else if (USARTx == USART2)
  64. {
  65. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  66. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  67. /*GPIO INIT*/
  68. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
  69. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  70. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  71. GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  72. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  73. GPIO_Init(GPIOA, &GPIO_InitStruct);
  74. GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1);
  75. GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);
  76. /* USART2 interrupt Init */
  77. NVIC_SetPriority(USART2_IRQn, 5);
  78. NVIC_EnableIRQ(USART2_IRQn);
  79. }
  80. }
  81. static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  82. {
  83. struct ft32_uart *uart;
  84. RT_ASSERT(serial != RT_NULL);
  85. RT_ASSERT(cfg != RT_NULL);
  86. uart = rt_container_of(serial, struct ft32_uart, serial);
  87. uart->Init.USART_BaudRate = cfg->baud_rate;
  88. uart->Init.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  89. switch (cfg->flowcontrol)
  90. {
  91. case RT_SERIAL_FLOWCONTROL_NONE:
  92. uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  93. break;
  94. case RT_SERIAL_FLOWCONTROL_CTSRTS:
  95. uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
  96. break;
  97. default:
  98. uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  99. break;
  100. }
  101. switch (cfg->data_bits)
  102. {
  103. case DATA_BITS_8:
  104. if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
  105. uart->Init.USART_WordLength = USART_WordLength_9b;
  106. else
  107. uart->Init.USART_WordLength = USART_WordLength_8b;
  108. break;
  109. case DATA_BITS_9:
  110. uart->Init.USART_WordLength = USART_WordLength_9b;
  111. break;
  112. default:
  113. uart->Init.USART_WordLength = USART_WordLength_8b;
  114. break;
  115. }
  116. switch (cfg->stop_bits)
  117. {
  118. case STOP_BITS_1:
  119. uart->Init.USART_StopBits = USART_StopBits_1;
  120. break;
  121. case STOP_BITS_2:
  122. uart->Init.USART_StopBits = USART_StopBits_2;
  123. break;
  124. default:
  125. uart->Init.USART_StopBits = USART_StopBits_1;
  126. break;
  127. }
  128. switch (cfg->parity)
  129. {
  130. case PARITY_NONE:
  131. uart->Init.USART_Parity = USART_Parity_No;
  132. break;
  133. case PARITY_ODD:
  134. uart->Init.USART_Parity = USART_Parity_Odd;
  135. break;
  136. case PARITY_EVEN:
  137. uart->Init.USART_Parity = USART_Parity_Even;
  138. break;
  139. default:
  140. uart->Init.USART_Parity = USART_Parity_No;
  141. break;
  142. }
  143. #ifdef RT_SERIAL_USING_DMA
  144. uart->dma_rx.last_index = 0;
  145. #endif
  146. UART_MspInit(uart->config->Instance);
  147. USART_Init(uart->config->Instance, &(uart->Init));
  148. USART_Cmd(uart->config->Instance, ENABLE);
  149. return RT_EOK;
  150. }
  151. static rt_err_t ft32_control(struct rt_serial_device *serial, int cmd, void *arg)
  152. {
  153. struct ft32_uart *uart;
  154. #ifdef RT_SERIAL_USING_DMA
  155. rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
  156. #endif
  157. RT_ASSERT(serial != RT_NULL);
  158. uart = rt_container_of(serial, struct ft32_uart, serial);
  159. switch (cmd)
  160. {
  161. /* disable interrupt */
  162. case RT_DEVICE_CTRL_CLR_INT:
  163. /* disable rx irq */
  164. NVIC_DisableIRQ(uart->config->irq_type);
  165. /* disable interrupt */
  166. USART_ITConfig(uart->config->Instance, USART_IT_RXNE, DISABLE);
  167. #ifdef RT_SERIAL_USING_DMA
  168. /* disable DMA */
  169. if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX)
  170. {
  171. NVIC_DisableIRQ(uart->config->dma_rx->dma_irq);
  172. DMA_DeInit(uart->dma_rx.Instance);
  173. }
  174. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
  175. {
  176. NVIC_DisableIRQ(uart->config->dma_tx->dma_irq);
  177. DMA_DeInit(uart->dma_rx.Instance);
  178. }
  179. #endif
  180. break;
  181. /* enable interrupt */
  182. case RT_DEVICE_CTRL_SET_INT:
  183. /* enable rx irq */
  184. NVIC_SetPriority(uart->config->irq_type, 1);
  185. NVIC_EnableIRQ(uart->config->irq_type);
  186. /* enable interrupt */
  187. USART_ITConfig(uart->config->Instance, USART_IT_RXNE, ENABLE);
  188. break;
  189. #ifdef RT_SERIAL_USING_DMA
  190. case RT_DEVICE_CTRL_CONFIG:
  191. ft32_dma_config(serial, ctrl_arg);
  192. break;
  193. #endif
  194. case RT_DEVICE_CTRL_CLOSE:
  195. USART_DeInit(uart->config->Instance);
  196. break;
  197. }
  198. return RT_EOK;
  199. }
  200. rt_uint32_t ft32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity)
  201. {
  202. rt_uint32_t mask;
  203. if (word_length == USART_WordLength_8b)
  204. {
  205. if (parity == USART_Parity_No)
  206. {
  207. mask = 0x00FFU ;
  208. }
  209. else
  210. {
  211. mask = 0x007FU ;
  212. }
  213. }
  214. else if (word_length == USART_WordLength_9b)
  215. {
  216. if (parity == USART_Parity_No)
  217. {
  218. mask = 0x01FFU ;
  219. }
  220. else
  221. {
  222. mask = 0x00FFU ;
  223. }
  224. }
  225. else if (word_length == USART_WordLength_7b)
  226. {
  227. if (parity == USART_Parity_No)
  228. {
  229. mask = 0x007FU ;
  230. }
  231. else
  232. {
  233. mask = 0x003FU ;
  234. }
  235. }
  236. else
  237. {
  238. mask = 0x0000U;
  239. }
  240. return mask;
  241. }
  242. static int ft32_putc(struct rt_serial_device *serial, char c)
  243. {
  244. struct ft32_uart *uart;
  245. RT_ASSERT(serial != RT_NULL);
  246. uart = rt_container_of(serial, struct ft32_uart, serial);
  247. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TC);
  248. #if defined(SOC_SERIES_FT32F0)
  249. uart->config->Instance->TDR = c;
  250. #else
  251. uart->config->Instance->DR = c;
  252. #endif
  253. while (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TC) == RESET);
  254. return 1;
  255. }
  256. static int ft32_getc(struct rt_serial_device *serial)
  257. {
  258. int ch;
  259. struct ft32_uart *uart;
  260. RT_ASSERT(serial != RT_NULL);
  261. uart = rt_container_of(serial, struct ft32_uart, serial);
  262. ch = -1;
  263. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET)
  264. {
  265. #if defined(SOC_SERIES_FT32F0)
  266. ch = uart->config->Instance->RDR & ft32_uart_get_mask(uart->Init.USART_WordLength, uart->Init.USART_Parity);
  267. #else
  268. ch = uart->config->Instance->DR & ft32_uart_get_mask(uart->Init.USART_WordLength, uart->Init.USART_Parity);
  269. #endif
  270. }
  271. return ch;
  272. }
  273. static rt_size_t ft32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
  274. {
  275. RT_ASSERT(serial != RT_NULL);
  276. RT_ASSERT(buf != RT_NULL);
  277. if (size == 0)
  278. {
  279. return 0;
  280. }
  281. if (RT_SERIAL_DMA_TX == direction)
  282. {
  283. return size;
  284. }
  285. return 0;
  286. }
  287. /**
  288. * Uart common interrupt process. This need add to uart ISR.
  289. *
  290. * @param serial serial device
  291. */
  292. static void uart_isr(struct rt_serial_device *serial)
  293. {
  294. struct ft32_uart *uart;
  295. #ifdef RT_SERIAL_USING_DMA
  296. rt_size_t recv_total_index, recv_len;
  297. rt_base_t level;
  298. #endif
  299. RT_ASSERT(serial != RT_NULL);
  300. uart = rt_container_of(serial, struct ft32_uart, serial);
  301. /* UART in mode Receiver -------------------------------------------------*/
  302. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET)
  303. {
  304. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  305. }
  306. #ifdef RT_SERIAL_USING_DMA
  307. else if ((uart->uart_dma_flag) && (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET))
  308. {
  309. level = rt_hw_interrupt_disable();
  310. recv_total_index = serial->config.bufsz - DMA_GetCurrDataCounter(&(uart->dma_rx.Instance));
  311. recv_len = recv_total_index - uart->dma_rx.last_index;
  312. uart->dma_rx.last_index = recv_total_index;
  313. rt_hw_interrupt_enable(level);
  314. if (recv_len)
  315. {
  316. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  317. }
  318. USART_ClearFlag(uart->config->Instance, USART_IT_IDLE);
  319. }
  320. else if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TC) != RESET))
  321. {
  322. if ((serial->parent.open_flag & RT_DEVICE_FLAG_DMA_TX) != 0)
  323. {
  324. }
  325. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TC);
  326. }
  327. #endif
  328. else
  329. {
  330. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_ORE) != RESET)
  331. {
  332. USART_ClearFlag(uart->config->Instance, USART_FLAG_ORE);
  333. }
  334. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_NE) != RESET)
  335. {
  336. USART_ClearFlag(uart->config->Instance, USART_FLAG_NE);
  337. }
  338. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_FE) != RESET)
  339. {
  340. USART_ClearFlag(uart->config->Instance, USART_FLAG_FE);
  341. }
  342. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_PE) != RESET)
  343. {
  344. USART_ClearFlag(uart->config->Instance, USART_FLAG_PE);
  345. }
  346. #if !defined(SOC_SERIES_FT32F0)
  347. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_LBD) != RESET)
  348. {
  349. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_LBD);
  350. }
  351. #endif
  352. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_CTS) != RESET)
  353. {
  354. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_CTS);
  355. }
  356. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TXE) != RESET)
  357. {
  358. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TXE);
  359. }
  360. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TC) != RESET)
  361. {
  362. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TC);
  363. }
  364. if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET)
  365. {
  366. UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_RXNE);
  367. }
  368. }
  369. }
  370. #ifdef RT_SERIAL_USING_DMA
  371. static void dma_isr(struct rt_serial_device *serial)
  372. {
  373. struct ft32_uart *uart;
  374. rt_size_t recv_total_index, recv_len;
  375. rt_base_t level;
  376. RT_ASSERT(serial != RT_NULL);
  377. uart = rt_container_of(serial, struct ft32_uart, serial);
  378. if ((DMA_GetITStatus(uart->dma_rx.Instance, DMA_IT_TC) != RESET) ||
  379. (DMA_GetITStatus(uart->dma_rx.Instance, DMA_IT_HT) != RESET))
  380. {
  381. level = rt_hw_interrupt_disable();
  382. recv_total_index = serial->config.bufsz - DMA_GetCurrDataCounter(uart->dma_rx.Instance);
  383. if (recv_total_index == 0)
  384. {
  385. recv_len = serial->config.bufsz - uart->dma_rx.last_index;
  386. }
  387. else
  388. {
  389. recv_len = recv_total_index - uart->dma_rx.last_index;
  390. }
  391. uart->dma_rx.last_index = recv_total_index;
  392. rt_hw_interrupt_enable(level);
  393. if (recv_len)
  394. {
  395. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  396. }
  397. }
  398. }
  399. #endif
  400. #if defined(BSP_USING_UART1)
  401. void USART1_IRQHandler(void)
  402. {
  403. /* enter interrupt */
  404. rt_interrupt_enter();
  405. uart_isr(&(uart_obj[UART1_INDEX].serial));
  406. /* leave interrupt */
  407. rt_interrupt_leave();
  408. }
  409. #if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_RX_USING_DMA)
  410. void UART1_DMA_RX_IRQHandler(void)
  411. {
  412. /* enter interrupt */
  413. rt_interrupt_enter();
  414. __DMA_IRQHandler(uart_obj[UART1_INDEX].dma_rx.Instance);
  415. /* leave interrupt */
  416. rt_interrupt_leave();
  417. }
  418. #endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_RX_USING_DMA) */
  419. #if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_TX_USING_DMA)
  420. void UART1_DMA_TX_IRQHandler(void)
  421. {
  422. /* enter interrupt */
  423. rt_interrupt_enter();
  424. __DMA_IRQHandler(uart_obj[UART1_INDEX].dma_tx.Instance);
  425. /* leave interrupt */
  426. rt_interrupt_leave();
  427. }
  428. #endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_TX_USING_DMA) */
  429. #endif /* BSP_USING_UART1 */
  430. #if defined(BSP_USING_UART2)
  431. void USART2_IRQHandler(void)
  432. {
  433. /* enter interrupt */
  434. rt_interrupt_enter();
  435. uart_isr(&(uart_obj[UART2_INDEX].serial));
  436. /* leave interrupt */
  437. rt_interrupt_leave();
  438. }
  439. #if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_RX_USING_DMA)
  440. void UART2_DMA_RX_IRQHandler(void)
  441. {
  442. /* enter interrupt */
  443. rt_interrupt_enter();
  444. __DMA_IRQHandler(uart_obj[UART2_INDEX].dma_rx.Instance);
  445. /* leave interrupt */
  446. rt_interrupt_leave();
  447. }
  448. #endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_RX_USING_DMA) */
  449. #if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_TX_USING_DMA)
  450. void UART2_DMA_TX_IRQHandler(void)
  451. {
  452. /* enter interrupt */
  453. rt_interrupt_enter();
  454. __DMA_IRQHandler(uart_obj[UART2_INDEX].dma_tx.Instance);
  455. /* leave interrupt */
  456. rt_interrupt_leave();
  457. }
  458. #endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_TX_USING_DMA) */
  459. #endif /* BSP_USING_UART2 */
  460. static void ft32_uart_get_dma_config(void)
  461. {
  462. #ifdef BSP_USING_UART1
  463. uart_obj[UART1_INDEX].uart_dma_flag = 0;
  464. #ifdef BSP_UART1_RX_USING_DMA
  465. uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  466. static struct dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG;
  467. uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx;
  468. #endif
  469. #ifdef BSP_UART1_TX_USING_DMA
  470. uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  471. static struct dma_config uart1_dma_tx = UART1_DMA_TX_CONFIG;
  472. uart_config[UART1_INDEX].dma_tx = &uart1_dma_tx;
  473. #endif
  474. #endif
  475. #ifdef BSP_USING_UART2
  476. uart_obj[UART2_INDEX].uart_dma_flag = 0;
  477. #ifdef BSP_UART2_RX_USING_DMA
  478. uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  479. static struct dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG;
  480. uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx;
  481. #endif
  482. #ifdef BSP_UART2_TX_USING_DMA
  483. uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  484. static struct dma_config uart2_dma_tx = UART2_DMA_TX_CONFIG;
  485. uart_config[UART2_INDEX].dma_tx = &uart2_dma_tx;
  486. #endif
  487. #endif
  488. }
  489. #ifdef RT_SERIAL_USING_DMA
  490. static void ft32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
  491. {
  492. struct rt_serial_rx_fifo *rx_fifo;
  493. DMA_InitTypeDef Init;
  494. struct dma_config *dma_config;
  495. struct ft32_uart *uart;
  496. RT_ASSERT(serial != RT_NULL);
  497. RT_ASSERT(flag == RT_DEVICE_FLAG_DMA_TX || flag == RT_DEVICE_FLAG_DMA_RX);
  498. uart = rt_container_of(serial, struct ft32_uart, serial);
  499. if (RT_DEVICE_FLAG_DMA_RX == flag)
  500. {
  501. Init = &uart->dma_rx.Init;
  502. dma_config = uart->config->dma_rx;
  503. }
  504. else /* RT_DEVICE_FLAG_DMA_TX == flag */
  505. {
  506. Init = &uart->dma_tx.Init;
  507. dma_config = uart->config->dma_tx;
  508. }
  509. LOG_D("%s dma config start", uart->config->name);
  510. {
  511. rt_uint32_t tmpreg = 0x00U;
  512. #if defined(SOC_SERIES_FT32F0)
  513. /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
  514. SET_BIT(RCC->AHBENR, dma_config->dma_rcc);
  515. tmpreg = READ_BIT(RCC->AHBENR, dma_config->dma_rcc);
  516. #endif
  517. (void)(tmpreg); /* To avoid compiler warnings */
  518. }
  519. if (RT_DEVICE_FLAG_DMA_RX == flag)
  520. {
  521. }
  522. else if (RT_DEVICE_FLAG_DMA_TX == flag)
  523. {
  524. }
  525. Init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  526. Init.MemInc = DMA_MemoryInc_Enable;
  527. Init.PeriphDataAlignment = DMA_PeripheralDataSize_Byte;
  528. Init.MemDataAlignment = DMA_MemoryDataSize_Byte;
  529. if (RT_DEVICE_FLAG_DMA_RX == flag)
  530. {
  531. Init.Direction = DMA_DIR_PeripheralSRC;
  532. Init.Mode = DMA_Mode_Circular;
  533. }
  534. else if (RT_DEVICE_FLAG_DMA_TX == flag)
  535. {
  536. Init.Direction = DMA_DIR_PeripheralDST;
  537. Init.Mode = DMA_Mode_Normal;
  538. }
  539. Init.Priority = DMA_Priority_Medium;
  540. DMA_DeInit(dma_config->Instance);
  541. DMA_Init(dma_config->Instance);
  542. /* enable interrupt */
  543. if (flag == RT_DEVICE_FLAG_DMA_RX)
  544. {
  545. rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  546. /* Start DMA transfer */
  547. UART_Receive_DMA(uart->config->Instance, rx_fifo->buffer, serial->config.bufsz);
  548. CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE);
  549. USART_ITConfig(uart->config->Instance, USART_IT_IDLE, ENABLE);
  550. }
  551. /* DMA irq should set in DMA TX mode, or HAL_UART_TxCpltCallback function will not be called */
  552. NVIC_SetPriority(dma_config->dma_irq, 0, 0);
  553. NVIC_EnableIRQ(dma_config->dma_irq);
  554. NVIC_SetPriority(uart->config->irq_type, 1, 0);
  555. NVIC_EnableIRQ(uart->config->irq_type);
  556. LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance);
  557. LOG_D("%s dma config done", uart->config->name);
  558. }
  559. static void _dma_tx_complete(struct rt_serial_device *serial)
  560. {
  561. struct ft32_uart *uart;
  562. rt_size_t trans_total_index;
  563. rt_base_t level;
  564. RT_ASSERT(serial != RT_NULL);
  565. uart = rt_container_of(serial, struct ft32_uart, serial);
  566. level = rt_hw_interrupt_disable();
  567. trans_total_index = DMA_GetCurrDataCounter(uart->dma_tx.Instance);
  568. rt_hw_interrupt_enable(level);
  569. if (trans_total_index == 0)
  570. {
  571. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE);
  572. }
  573. }
  574. #endif /* RT_SERIAL_USING_DMA */
  575. static const struct rt_uart_ops ft32_uart_ops =
  576. {
  577. .configure = ft32_configure,
  578. .control = ft32_control,
  579. .putc = ft32_putc,
  580. .getc = ft32_getc,
  581. .dma_transmit = ft32_dma_transmit
  582. };
  583. int rt_hw_usart_init(void)
  584. {
  585. rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct ft32_uart);
  586. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  587. rt_err_t result = 0;
  588. ft32_uart_get_dma_config();
  589. for (int i = 0; i < obj_num; i++)
  590. {
  591. /* init UART object */
  592. uart_obj[i].config = &uart_config[i];
  593. uart_obj[i].serial.ops = &ft32_uart_ops;
  594. uart_obj[i].serial.config = config;
  595. /* register UART device */
  596. result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
  597. RT_DEVICE_FLAG_RDWR
  598. | RT_DEVICE_FLAG_INT_RX
  599. | RT_DEVICE_FLAG_INT_TX
  600. | uart_obj[i].uart_dma_flag
  601. , NULL);
  602. RT_ASSERT(result == RT_EOK);
  603. }
  604. return result;
  605. }
  606. #endif /* RT_USING_SERIAL */