drv_usart.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045
  1. /*
  2. * Copyright (c) 2006-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-08-20 BruceOu first implementation
  9. * 2025-09-29 WangShun optimize the serial driver
  10. * 2025-11-13 kurisaw general GD driver adaptation
  11. */
  12. #include "board.h"
  13. #include <stdlib.h>
  14. #include "drv_usart.h"
  15. #include "uart_config.h"
  16. #ifdef RT_USING_SERIAL
  17. #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \
  18. !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && \
  19. !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && \
  20. !defined(BSP_USING_UART6) && !defined(BSP_USING_UART7)
  21. #error "Please define at least one UARTx"
  22. #endif
  23. #if defined(SOC_SERIES_GD32E50x) || defined(SOC_SERIES_GD32F10x) || defined(SOC_SERIES_GD32F20x) || defined(SOC_SERIES_GD32F30x)
  24. #define gpio_output_options_set gpio_init
  25. #define GPIO_OTYPE GPIO_MODE_OUT_PP
  26. #define GPIO_OSPEED GPIO_OSPEED_50MHZ
  27. #elif defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  28. #define GPIO_OTYPE GPIO_OTYPE_PP
  29. #define GPIO_OSPEED GPIO_OSPEED_60MHZ
  30. #elif defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32E23x)
  31. #define GPIO_OTYPE GPIO_OTYPE_PP
  32. #define GPIO_OSPEED GPIO_OSPEED_50MHZ
  33. #endif
  34. #include <rtdevice.h>
  35. #ifdef RT_SERIAL_USING_DMA
  36. static void gd32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
  37. static void gd32_dma_tx_config(struct rt_serial_device *serial, rt_ubase_t flag);
  38. static void dma_rx_done_isr(struct rt_serial_device *serial);
  39. extern void Error_Handler(void);
  40. #endif
  41. static void GD32_UART_IRQHandler(struct rt_serial_device *serial);
  42. #if defined(BSP_USING_UART0)
  43. struct rt_serial_device serial0;
  44. #if defined(RT_SERIAL_USING_DMA)
  45. gd32_uart_dma uart0_rxdma = {
  46. DMA0,
  47. DMA_CH0,
  48. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  49. DMA_REQUEST_USART0_RX,
  50. #endif
  51. DMA_INTF_FTFIF,
  52. DMA0_Channel0_IRQn,
  53. 0,
  54. };
  55. gd32_uart_dma uart0_txdma = {
  56. DMA1,
  57. DMA_CH0,
  58. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  59. DMA_REQUEST_USART0_TX,
  60. #endif
  61. DMA_INTF_FTFIF,
  62. DMA1_Channel0_IRQn,
  63. 0,
  64. };
  65. void DMA0_Channel0_IRQHandler(void)
  66. {
  67. /* enter interrupt */
  68. rt_interrupt_enter();
  69. dma_rx_done_isr(&serial0);
  70. /* leave interrupt */
  71. rt_interrupt_leave();
  72. }
  73. void DMA1_Channel0_IRQHandler(void)
  74. {
  75. /* enter interrupt */
  76. rt_interrupt_enter();
  77. dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_FTF);
  78. dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_HTF);
  79. dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_FEE);
  80. dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_TAE);
  81. /* leave interrupt */
  82. rt_interrupt_leave();
  83. }
  84. #endif /* RT_SERIAL_USING_DMA */
  85. void USART0_IRQHandler(void)
  86. {
  87. /* enter interrupt */
  88. rt_interrupt_enter();
  89. GD32_UART_IRQHandler(&serial0);
  90. /* leave interrupt */
  91. rt_interrupt_leave();
  92. }
  93. #endif /* BSP_USING_UART0 */
  94. #if defined(BSP_USING_UART1)
  95. struct rt_serial_device serial1;
  96. #if defined(RT_SERIAL_USING_DMA)
  97. gd32_uart_dma uart1_rxdma = {
  98. DMA0,
  99. DMA_CH1,
  100. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  101. DMA_REQUEST_USART1_RX,
  102. #endif
  103. DMA_INTF_FTFIF,
  104. DMA0_Channel1_IRQn,
  105. 0,
  106. };
  107. void DMA0_Channel1_IRQHandler(void)
  108. {
  109. /* enter interrupt */
  110. rt_interrupt_enter();
  111. dma_rx_done_isr(&serial1);
  112. /* leave interrupt */
  113. rt_interrupt_leave();
  114. }
  115. #endif /* RT_SERIAL_USING_DMA */
  116. void USART1_IRQHandler(void)
  117. {
  118. /* enter interrupt */
  119. rt_interrupt_enter();
  120. GD32_UART_IRQHandler(&serial1);
  121. /* leave interrupt */
  122. rt_interrupt_leave();
  123. }
  124. #endif /* BSP_USING_UART1 */
  125. #if defined(BSP_USING_UART2)
  126. struct rt_serial_device serial2;
  127. #if defined(RT_SERIAL_USING_DMA)
  128. gd32_uart_dma uart2_rxdma = {
  129. DMA0,
  130. DMA_CH2,
  131. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  132. DMA_REQUEST_USART2_RX,
  133. #endif
  134. DMA_INTF_FTFIF,
  135. DMA0_Channel2_IRQn,
  136. 0,
  137. };
  138. gd32_uart_dma uart2_txdma = {
  139. DMA1,
  140. DMA_CH2,
  141. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  142. DMA_REQUEST_USART2_TX,
  143. #endif
  144. DMA_INTF_FTFIF,
  145. DMA1_Channel2_IRQn,
  146. 0,
  147. };
  148. void DMA0_Channel2_IRQHandler(void)
  149. {
  150. /* enter interrupt */
  151. rt_interrupt_enter();
  152. dma_rx_done_isr(&serial2);
  153. /* leave interrupt */
  154. rt_interrupt_leave();
  155. }
  156. void DMA1_Channel2_IRQHandler(void)
  157. {
  158. /* enter interrupt */
  159. rt_interrupt_enter();
  160. dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FTF);
  161. dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_HTF);
  162. dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FEE);
  163. dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_TAE);
  164. /* leave interrupt */
  165. rt_interrupt_leave();
  166. }
  167. #endif /* RT_SERIAL_USING_DMA */
  168. void USART2_IRQHandler(void)
  169. {
  170. /* enter interrupt */
  171. rt_interrupt_enter();
  172. GD32_UART_IRQHandler(&serial2);
  173. /* leave interrupt */
  174. rt_interrupt_leave();
  175. }
  176. #endif /* BSP_USING_UART2 */
  177. #if defined(BSP_USING_UART3)
  178. struct rt_serial_device serial3;
  179. #if defined(RT_SERIAL_USING_DMA)
  180. gd32_uart_dma uart3_rxdma = {
  181. DMA0,
  182. DMA_CH3,
  183. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  184. DMA_REQUEST_UART3_RX,
  185. #endif
  186. DMA_INTF_FTFIF,
  187. DMA0_Channel3_IRQn,
  188. 0,
  189. };
  190. void DMA0_Channel3_IRQHandler(void)
  191. {
  192. /* enter interrupt */
  193. rt_interrupt_enter();
  194. dma_rx_done_isr(&serial3);
  195. /* leave interrupt */
  196. rt_interrupt_leave();
  197. }
  198. #endif /* RT_SERIAL_USING_DMA */
  199. void UART3_IRQHandler(void)
  200. {
  201. /* enter interrupt */
  202. rt_interrupt_enter();
  203. GD32_UART_IRQHandler(&serial3);
  204. /* leave interrupt */
  205. rt_interrupt_leave();
  206. }
  207. #endif /* BSP_USING_UART3 */
  208. #if defined(BSP_USING_UART4)
  209. struct rt_serial_device serial4;
  210. #if defined(RT_SERIAL_USING_DMA)
  211. gd32_uart_dma uart4_rxdma = {
  212. DMA0,
  213. DMA_CH4,
  214. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  215. DMA_REQUEST_UART4_RX,
  216. #endif
  217. DMA_INTF_FTFIF,
  218. DMA0_Channel4_IRQn,
  219. 0,
  220. };
  221. void DMA0_Channel4_IRQHandler(void)
  222. {
  223. /* enter interrupt */
  224. rt_interrupt_enter();
  225. dma_rx_done_isr(&serial4);
  226. /* leave interrupt */
  227. rt_interrupt_leave();
  228. }
  229. #endif /* RT_SERIAL_USING_DMA */
  230. void UART4_IRQHandler(void)
  231. {
  232. /* enter interrupt */
  233. rt_interrupt_enter();
  234. GD32_UART_IRQHandler(&serial4);
  235. /* leave interrupt */
  236. rt_interrupt_leave();
  237. }
  238. #endif /* BSP_USING_UART4 */
  239. #if defined(BSP_USING_UART5)
  240. struct rt_serial_device serial5;
  241. #if defined(RT_SERIAL_USING_DMA)
  242. gd32_uart_dma uart5_rxdma = {
  243. DMA0,
  244. DMA_CH5,
  245. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  246. DMA_REQUEST_USART5_RX,
  247. #endif
  248. DMA_INTF_FTFIF,
  249. DMA0_Channel5_IRQn,
  250. 0,
  251. };
  252. void DMA0_Channel5_IRQHandler(void)
  253. {
  254. /* enter interrupt */
  255. rt_interrupt_enter();
  256. dma_rx_done_isr(&serial5);
  257. /* leave interrupt */
  258. rt_interrupt_leave();
  259. }
  260. #endif /* RT_SERIAL_USING_DMA */
  261. void USART5_IRQHandler(void)
  262. {
  263. /* enter interrupt */
  264. rt_interrupt_enter();
  265. GD32_UART_IRQHandler(&serial5);
  266. /* leave interrupt */
  267. rt_interrupt_leave();
  268. }
  269. #endif /* BSP_USING_UART5 */
  270. #if defined(BSP_USING_UART6)
  271. struct rt_serial_device serial6;
  272. #if defined(RT_SERIAL_USING_DMA)
  273. gd32_uart_dma uart6_rxdma = {
  274. DMA0,
  275. DMA_CH6,
  276. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  277. DMA_REQUEST_UART6_RX,
  278. #endif
  279. DMA_INTF_FTFIF,
  280. DMA0_Channel6_IRQn,
  281. 0,
  282. };
  283. void DMA0_Channel6_IRQHandler(void)
  284. {
  285. /* enter interrupt */
  286. rt_interrupt_enter();
  287. dma_rx_done_isr(&serial6);
  288. /* leave interrupt */
  289. rt_interrupt_leave();
  290. }
  291. #endif /* RT_SERIAL_USING_DMA */
  292. void UART6_IRQHandler(void)
  293. {
  294. /* enter interrupt */
  295. rt_interrupt_enter();
  296. GD32_UART_IRQHandler(&serial6);
  297. /* leave interrupt */
  298. rt_interrupt_leave();
  299. }
  300. #endif /* BSP_USING_UART6 */
  301. #if defined(BSP_USING_UART7)
  302. struct rt_serial_device serial7;
  303. #if defined(RT_SERIAL_USING_DMA)
  304. gd32_uart_dma uart7_rxdma = {
  305. DMA0,
  306. DMA_CH7,
  307. #if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E)
  308. DMA_REQUEST_UART7_RX,
  309. #endif
  310. DMA_INTF_FTFIF,
  311. DMA0_Channel7_IRQn,
  312. 0,
  313. };
  314. void DMA0_Channel7_IRQHandler(void)
  315. {
  316. /* enter interrupt */
  317. rt_interrupt_enter();
  318. dma_rx_done_isr(&serial7);
  319. /* leave interrupt */
  320. rt_interrupt_leave();
  321. }
  322. #endif /* RT_SERIAL_USING_DMA */
  323. void UART7_IRQHandler(void)
  324. {
  325. /* enter interrupt */
  326. rt_interrupt_enter();
  327. GD32_UART_IRQHandler(&serial7);
  328. /* leave interrupt */
  329. rt_interrupt_leave();
  330. }
  331. #endif /* BSP_USING_UART7 */
  332. static const struct gd32_uart uart_obj[] =
  333. {
  334. #ifdef BSP_USING_UART0
  335. UART0_CONFIG,
  336. #endif
  337. #ifdef BSP_USING_UART1
  338. UART1_CONFIG,
  339. #endif
  340. #ifdef BSP_USING_UART2
  341. UART2_CONFIG,
  342. #endif
  343. #ifdef BSP_USING_UART3
  344. UART3_CONFIG,
  345. #endif
  346. #ifdef BSP_USING_UART4
  347. UART4_CONFIG,
  348. #endif
  349. #ifdef BSP_USING_UART5
  350. UART5_CONFIG,
  351. #endif
  352. #ifdef BSP_USING_UART6
  353. UART6_CONFIG,
  354. #endif
  355. #ifdef BSP_USING_UART7
  356. UART7_CONFIG,
  357. #endif
  358. };
  359. /**
  360. * @brief UART MSP Initialization
  361. * This function configures the hardware resources used in this example:
  362. * - Peripheral's clock enable
  363. * - Peripheral's GPIO Configuration
  364. * - NVIC configuration for UART interrupt request enable
  365. * @param huart: UART handle pointer
  366. * @retval None
  367. */
  368. void gd32_uart_gpio_init(struct gd32_uart *uart)
  369. {
  370. rt_uint32_t tx_port, rx_port;
  371. rt_uint32_t tx_pin, rx_pin;
  372. rt_uint32_t pin_af;
  373. rcu_periph_enum tx_periph, rx_periph;
  374. if (get_pin_config(uart->tx_pin_name, &tx_port, &tx_pin, &tx_periph) != RT_EOK)
  375. {
  376. return;
  377. }
  378. if (get_pin_config(uart->rx_pin_name, &rx_port, &rx_pin, &rx_periph) != RT_EOK)
  379. {
  380. return;
  381. }
  382. pin_alternate_config(uart->alternate, &pin_af);
  383. /* enable USART clock */
  384. rcu_periph_clock_enable(tx_periph);
  385. rcu_periph_clock_enable(rx_periph);
  386. rcu_periph_clock_enable(uart->per_clk);
  387. #if !defined(SOC_SERIES_GD32E50x) && !defined(SOC_SERIES_GD32F10x) && !defined(SOC_SERIES_GD32F20x) && !defined(SOC_SERIES_GD32F30x)
  388. /* connect port to USARTx_Tx */
  389. gpio_af_set(tx_port, pin_af, tx_pin);
  390. /* connect port to USARTx_Rx */
  391. gpio_af_set(rx_port, pin_af, rx_pin);
  392. #endif
  393. /* configure USART Tx as alternate function push-pull */
  394. #if !defined(SOC_SERIES_GD32E50x) && !defined(SOC_SERIES_GD32F10x) && !defined(SOC_SERIES_GD32F20x) && !defined(SOC_SERIES_GD32F30x)
  395. gpio_mode_set(tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, tx_pin);
  396. #endif
  397. gpio_output_options_set(tx_port, GPIO_OTYPE, GPIO_OSPEED, tx_pin);
  398. /* configure USART Rx as alternate function push-pull */
  399. #if !defined(SOC_SERIES_GD32E50x) && !defined(SOC_SERIES_GD32F10x) && !defined(SOC_SERIES_GD32F20x) && !defined(SOC_SERIES_GD32F30x)
  400. gpio_mode_set(rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, rx_pin);
  401. #endif
  402. gpio_output_options_set(rx_port, GPIO_OTYPE, GPIO_OSPEED, rx_pin);
  403. NVIC_SetPriority(uart->irqn, 0);
  404. NVIC_EnableIRQ(uart->irqn);
  405. }
  406. /**
  407. * @brief uart configure
  408. * @param serial, cfg
  409. * @retval None
  410. */
  411. static rt_err_t gd32_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  412. {
  413. struct gd32_uart *uart;
  414. RT_ASSERT(serial != RT_NULL);
  415. RT_ASSERT(cfg != RT_NULL);
  416. uart = (struct gd32_uart *)serial->parent.user_data;
  417. gd32_uart_gpio_init(uart);
  418. usart_baudrate_set(uart->uart_periph, cfg->baud_rate);
  419. switch (cfg->data_bits)
  420. {
  421. case DATA_BITS_9:
  422. usart_word_length_set(uart->uart_periph, USART_WL_9BIT);
  423. break;
  424. default:
  425. usart_word_length_set(uart->uart_periph, USART_WL_8BIT);
  426. break;
  427. }
  428. switch (cfg->stop_bits)
  429. {
  430. case STOP_BITS_2:
  431. usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT);
  432. break;
  433. default:
  434. usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT);
  435. break;
  436. }
  437. switch (cfg->parity)
  438. {
  439. case PARITY_ODD:
  440. usart_parity_config(uart->uart_periph, USART_PM_ODD);
  441. break;
  442. case PARITY_EVEN:
  443. usart_parity_config(uart->uart_periph, USART_PM_EVEN);
  444. break;
  445. default:
  446. usart_parity_config(uart->uart_periph, USART_PM_NONE);
  447. break;
  448. }
  449. usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE);
  450. usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE);
  451. usart_enable(uart->uart_periph);
  452. return RT_EOK;
  453. }
  454. /**
  455. * @brief uart control
  456. * @param serial, arg
  457. * @retval None
  458. */
  459. static rt_err_t gd32_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  460. {
  461. struct gd32_uart *uart;
  462. #ifdef RT_SERIAL_USING_DMA
  463. rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
  464. #endif
  465. RT_ASSERT(serial != RT_NULL);
  466. uart = (struct gd32_uart *)serial->parent.user_data;
  467. switch (cmd)
  468. {
  469. case RT_DEVICE_CTRL_CLR_INT:
  470. /* disable rx irq */
  471. NVIC_DisableIRQ(uart->irqn);
  472. /* disable interrupt */
  473. usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE);
  474. #ifdef RT_SERIAL_USING_DMA
  475. /* disable DMA */
  476. if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX)
  477. {
  478. nvic_irq_disable(uart->uart_dma->rx_irq_ch);
  479. /* disable interrupt */
  480. usart_interrupt_disable(uart->uart_periph, USART_INT_IDLE);
  481. dma_channel_disable(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  482. usart_dma_receive_config(uart->uart_periph, USART_RECEIVE_DMA_DISABLE);
  483. dma_deinit(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  484. uart->uart_dma->last_recv_index = 0;
  485. }
  486. #ifdef RT_SERIAL_USING_TX_DMA
  487. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
  488. {
  489. nvic_irq_disable(uart->uart_tx_dma->rx_irq_ch);
  490. dma_channel_disable(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch);
  491. usart_dma_transmit_config(uart->uart_periph, USART_TRANSMIT_DMA_DISABLE);
  492. dma_deinit(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch);
  493. }
  494. #endif
  495. #endif
  496. break;
  497. case RT_DEVICE_CTRL_SET_INT:
  498. /* enable rx irq */
  499. NVIC_EnableIRQ(uart->irqn);
  500. usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE);
  501. /* enable interrupt */
  502. usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE);
  503. break;
  504. #ifdef RT_SERIAL_USING_DMA
  505. case RT_DEVICE_CTRL_CONFIG:
  506. if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX)
  507. {
  508. gd32_dma_config(serial, ctrl_arg);
  509. }
  510. #ifdef RT_SERIAL_USING_TX_DMA
  511. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
  512. {
  513. gd32_dma_tx_config(serial, ctrl_arg);
  514. }
  515. #endif
  516. break;
  517. #endif
  518. case RT_DEVICE_CTRL_CLOSE:
  519. usart_disable(uart->uart_periph);
  520. break;
  521. }
  522. return RT_EOK;
  523. }
  524. /**
  525. * @brief uart put char
  526. * @param serial, ch
  527. * @retval None
  528. */
  529. static int gd32_uart_putc(struct rt_serial_device *serial, char ch)
  530. {
  531. struct gd32_uart *uart;
  532. RT_ASSERT(serial != RT_NULL);
  533. uart = (struct gd32_uart *)serial->parent.user_data;
  534. usart_data_transmit(uart->uart_periph, ch);
  535. while((usart_flag_get(uart->uart_periph, USART_FLAG_TBE) == RESET));
  536. return RT_EOK;
  537. }
  538. /**
  539. * @brief uart get char
  540. * @param serial
  541. * @retval None
  542. */
  543. static int gd32_uart_getc(struct rt_serial_device *serial)
  544. {
  545. int ch;
  546. struct gd32_uart *uart;
  547. RT_ASSERT(serial != RT_NULL);
  548. uart = (struct gd32_uart *)serial->parent.user_data;
  549. ch = -1;
  550. if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)
  551. ch = usart_data_receive(uart->uart_periph);
  552. return ch;
  553. }
  554. #ifdef RT_SERIAL_USING_DMA
  555. static void dma_uart_config(struct rt_serial_device *serial, uint32_t setting_recv_len,
  556. void *mem_base_addr)
  557. {
  558. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  559. dma_single_data_parameter_struct dma_init_struct;
  560. /* rx dma config */
  561. uart->uart_dma->setting_recv_len = setting_recv_len;
  562. dma_deinit(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  563. dma_single_data_para_struct_init(&dma_init_struct);
  564. dma_init_struct.request = uart->uart_dma->dma_mux_req_rx;
  565. dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
  566. dma_init_struct.memory0_addr = (uint32_t)mem_base_addr;
  567. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  568. dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
  569. dma_init_struct.number = uart->uart_dma->setting_recv_len;
  570. dma_init_struct.periph_addr = (uint32_t) &(USART_RDATA(uart->uart_periph));
  571. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  572. dma_init_struct.priority = DMA_PRIORITY_HIGH;
  573. dma_single_data_mode_init(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch, &dma_init_struct);
  574. /* configure DMA mode */
  575. dma_circulation_disable(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  576. dma_flag_clear(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch, uart->uart_dma->rx_flag);
  577. dma_interrupt_enable(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch, DMA_CHXCTL_FTFIE);
  578. }
  579. static void gd32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
  580. {
  581. dma_single_data_parameter_struct dma_init_struct;
  582. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  583. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  584. /* wait IDLEF set and clear it */
  585. while(RESET == usart_flag_get(uart->uart_periph, USART_FLAG_IDLE))
  586. {
  587. rt_thread_mdelay(10);
  588. }
  589. usart_flag_clear(uart->uart_periph, USART_FLAG_IDLE);
  590. /* enable transmit idle interrupt */
  591. usart_interrupt_enable(uart->uart_periph, USART_INT_IDLE);
  592. /* DMA clock enable */
  593. if(DMA0 == uart->uart_dma->dma_periph)
  594. {
  595. rcu_periph_clock_enable(RCU_DMA0);
  596. } else if(DMA1 == uart->uart_dma->dma_periph)
  597. {
  598. rcu_periph_clock_enable(RCU_DMA1);
  599. } else {
  600. Error_Handler();
  601. }
  602. /* enable DMAMUX clock */
  603. rcu_periph_clock_enable(RCU_DMAMUX);
  604. #ifdef RT_USING_CACHE
  605. /* clean d-cache */
  606. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, rx_fifo->buffer, serial->config.bufsz);
  607. #endif
  608. /* rx dma config */
  609. dma_uart_config(serial, serial->config.bufsz, rx_fifo->buffer);
  610. usart_dma_receive_config(uart->uart_periph, USART_RECEIVE_DMA_ENABLE);
  611. dma_channel_enable(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  612. /* rx dma interrupt config */
  613. nvic_irq_enable(uart->uart_dma->rx_irq_ch, 1, 0);
  614. }
  615. #ifdef RT_SERIAL_USING_TX_DMA
  616. static void gd32_dma_tx_config(struct rt_serial_device *serial, rt_ubase_t flag)
  617. {
  618. dma_single_data_parameter_struct dma_init_struct;
  619. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  620. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  621. /* DMA clock enable */
  622. if(DMA0 == uart->uart_tx_dma->dma_periph)
  623. {
  624. rcu_periph_clock_enable(RCU_DMA0);
  625. } else if(DMA1 == uart->uart_tx_dma->dma_periph)
  626. {
  627. rcu_periph_clock_enable(RCU_DMA1);
  628. } else {
  629. Error_Handler();
  630. }
  631. /* enable DMAMUX clock */
  632. rcu_periph_clock_enable(RCU_DMAMUX);
  633. #ifdef RT_USING_CACHE
  634. /* clean d-cache */
  635. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, rx_fifo->buffer, serial->config.bufsz);
  636. #endif
  637. /* tx dma config */
  638. uart->uart_tx_dma->setting_recv_len = 0;
  639. dma_deinit(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch);
  640. dma_single_data_para_struct_init(&dma_init_struct);
  641. dma_init_struct.request = uart->uart_tx_dma->dma_mux_req_rx;
  642. dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
  643. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  644. dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
  645. dma_init_struct.periph_addr = (uint32_t) &(USART_TDATA(uart->uart_periph));
  646. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  647. dma_init_struct.priority = DMA_PRIORITY_HIGH;
  648. dma_single_data_mode_init(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch, &dma_init_struct);
  649. /* configure DMA mode */
  650. dma_circulation_disable(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch);
  651. }
  652. #ifdef RT_USING_CACHE
  653. #ifdef BSP_SCB_ENABLE_D_CACHE
  654. static uint8_t dma_buf_cache_pre_bk[32] = {0};
  655. static uint8_t dma_buf_cache_post_bk[32] = {0};
  656. #endif
  657. #endif
  658. static rt_ssize_t gd32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
  659. {
  660. struct gd32_uart *uart;
  661. RT_ASSERT(serial != RT_NULL);
  662. RT_ASSERT(buf != RT_NULL);
  663. uart = (struct gd32_uart *) serial->parent.user_data;
  664. if (size == 0)
  665. {
  666. return 0;
  667. }
  668. if (RT_SERIAL_DMA_TX == direction)
  669. {
  670. #ifdef RT_USING_CACHE
  671. #ifdef BSP_SCB_ENABLE_D_CACHE
  672. uint32_t *dma_cache_pre_ptr = NULL, *dma_cache_post_ptr = NULL;
  673. uint32_t pre_size = (rt_uint32_t)buf & (rt_uint32_t)0x1F;
  674. dma_cache_pre_ptr = (uint32_t *)((uint32_t)buf - pre_size);
  675. rt_memcpy(dma_buf_cache_pre_bk, dma_cache_pre_ptr, pre_size);
  676. dma_cache_post_ptr = (uint32_t *)((uint32_t)buf + size);
  677. rt_memcpy(dma_buf_cache_post_bk, dma_cache_post_ptr, sizeof(dma_buf_cache_post_bk));
  678. /* invalidate d-cache */
  679. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, buf, size);
  680. rt_memcpy(dma_cache_pre_ptr, dma_buf_cache_pre_bk, pre_size);
  681. rt_memcpy(dma_cache_post_ptr, dma_buf_cache_post_bk, sizeof(dma_buf_cache_post_bk));
  682. #endif
  683. #endif
  684. dma_memory_address_config(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch, DMA_MEMORY_0, (uint32_t)buf);
  685. dma_transfer_number_config(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch, size);
  686. dma_flag_clear(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch, uart->uart_tx_dma->rx_flag);
  687. dma_interrupt_enable(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch, DMA_CHXCTL_FTFIE);
  688. usart_flag_clear(uart->uart_periph, USART_FLAG_TBE);
  689. usart_flag_clear(uart->uart_periph, USART_FLAG_TC);
  690. /* enable transmit idle interrupt */
  691. usart_interrupt_enable(uart->uart_periph, USART_INT_TC);
  692. usart_dma_transmit_config(uart->uart_periph, USART_TRANSMIT_DMA_ENABLE);
  693. /* rx dma interrupt config */
  694. nvic_irq_enable(uart->uart_tx_dma->rx_irq_ch, 1, 0);
  695. dma_channel_enable(uart->uart_tx_dma->dma_periph, uart->uart_tx_dma->dma_ch);
  696. }
  697. return 0;
  698. }
  699. #endif
  700. #ifdef RT_USING_CACHE
  701. static struct rt_serial_rx_fifo rx_fifo_cahce_bk = {0};
  702. static uint8_t rx_fifo_buf_cache_bk[32] = {0};
  703. #endif
  704. /**
  705. * Serial port receive idle process. This need add to uart idle ISR.
  706. *
  707. * @param serial serial device
  708. */
  709. static void dma_uart_rx_idle_isr(struct rt_serial_device *serial)
  710. {
  711. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  712. rt_size_t recv_total_index, recv_len;
  713. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  714. #ifdef RT_USING_CACHE
  715. uint32_t *rx_fifo_end_ptr = NULL;
  716. rx_fifo_end_ptr = (uint32_t *)((uint32_t)rx_fifo->buffer + serial->config.bufsz);
  717. rt_memcpy(&rx_fifo_cahce_bk, rx_fifo, sizeof(rx_fifo_cahce_bk));
  718. rt_memcpy(rx_fifo_buf_cache_bk, rx_fifo_end_ptr, sizeof(rx_fifo_buf_cache_bk));
  719. /* invalidate d-cache */
  720. rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, rx_fifo->buffer, serial->config.bufsz);
  721. rt_memcpy(rx_fifo, &rx_fifo_cahce_bk, sizeof(rx_fifo_cahce_bk));
  722. rt_memcpy(rx_fifo_end_ptr, rx_fifo_buf_cache_bk, sizeof(rx_fifo_buf_cache_bk));
  723. #endif
  724. recv_total_index = uart->uart_dma->setting_recv_len -
  725. dma_transfer_number_get(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  726. if (recv_total_index >= uart->uart_dma->last_recv_index)
  727. {
  728. recv_len = recv_total_index - uart->uart_dma->last_recv_index;
  729. } else {
  730. recv_len = uart->uart_dma->setting_recv_len - uart->uart_dma->last_recv_index + recv_total_index;
  731. }
  732. uart->uart_dma->last_recv_index = recv_total_index;
  733. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  734. /* read a data for clear receive idle interrupt flag */
  735. usart_data_receive(uart->uart_periph);
  736. usart_flag_clear(uart->uart_periph, USART_FLAG_IDLE);
  737. }
  738. /**
  739. * DMA receive done process. This need add to DMA receive done ISR.
  740. *
  741. * @param serial serial device
  742. */
  743. static void dma_rx_done_isr(struct rt_serial_device *serial)
  744. {
  745. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  746. rt_size_t recv_total_index, recv_len;
  747. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  748. #ifdef RT_USING_CACHE
  749. uint32_t *rx_fifo_end_ptr = NULL;
  750. rx_fifo_end_ptr = (uint32_t *)((uint32_t)rx_fifo->buffer+serial->config.bufsz);
  751. rt_memcpy(&rx_fifo_cahce_bk, rx_fifo, sizeof(rx_fifo_cahce_bk));
  752. rt_memcpy(rx_fifo_buf_cache_bk, rx_fifo_end_ptr, sizeof(rx_fifo_buf_cache_bk));
  753. /* invalidate d-cache */
  754. rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, rx_fifo->buffer, serial->config.bufsz);
  755. rt_memcpy(rx_fifo, &rx_fifo_cahce_bk, sizeof(rx_fifo_cahce_bk));
  756. rt_memcpy(rx_fifo_end_ptr, rx_fifo_buf_cache_bk, sizeof(rx_fifo_buf_cache_bk));
  757. #endif
  758. if (dma_flag_get(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch, uart->uart_dma->rx_flag) != RESET)
  759. {
  760. /* disable dma, stop receive data */
  761. dma_channel_disable(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  762. recv_total_index = uart->uart_dma->setting_recv_len -
  763. dma_transfer_number_get(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  764. if (recv_total_index >= uart->uart_dma->last_recv_index)
  765. {
  766. recv_len = recv_total_index - uart->uart_dma->last_recv_index;
  767. } else {
  768. recv_len = uart->uart_dma->setting_recv_len - uart->uart_dma->last_recv_index + recv_total_index;
  769. uart->uart_dma->last_recv_index = recv_total_index;
  770. }
  771. uart->uart_dma->last_recv_index = recv_total_index;
  772. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  773. /* start receive data */
  774. dma_flag_clear(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch, uart->uart_dma->rx_flag);
  775. dma_channel_enable(uart->uart_dma->dma_periph, uart->uart_dma->dma_ch);
  776. }
  777. }
  778. #endif /* RT_SERIAL_USING_DMA */
  779. /**
  780. * Uart common interrupt process. This need add to uart ISR.
  781. *
  782. * @param serial serial device
  783. */
  784. static void GD32_UART_IRQHandler(struct rt_serial_device *serial)
  785. {
  786. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  787. RT_ASSERT(uart != RT_NULL);
  788. /* UART in mode Receiver -------------------------------------------------*/
  789. if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) &&
  790. (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET))
  791. {
  792. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  793. /* Clear RXNE interrupt flag */
  794. usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE);
  795. }
  796. #ifdef RT_SERIAL_USING_DMA
  797. if(usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_IDLE) != RESET)
  798. {
  799. dma_uart_rx_idle_isr(serial);
  800. }
  801. #endif
  802. if (usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_TC) != RESET)
  803. {
  804. /* clear interrupt */
  805. usart_flag_clear(uart->uart_periph, USART_FLAG_TC);
  806. usart_interrupt_disable(uart->uart_periph, USART_INT_TC);
  807. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE);
  808. }
  809. if (usart_flag_get(uart->uart_periph, USART_FLAG_ORERR) == SET)
  810. {
  811. usart_flag_clear(uart->uart_periph, USART_FLAG_ORERR);
  812. }
  813. }
  814. static const struct rt_uart_ops gd32_uart_ops =
  815. {
  816. .configure = gd32_uart_configure,
  817. .control = gd32_uart_control,
  818. .putc = gd32_uart_putc,
  819. .getc = gd32_uart_getc,
  820. #ifndef RT_SERIAL_USING_TX_DMA
  821. NULL,
  822. #else
  823. .dma_transmit = gd32_dma_transmit,
  824. #endif
  825. };
  826. /**
  827. * @brief uart init
  828. * @param None
  829. * @retval None
  830. */
  831. int rt_hw_usart_init(void)
  832. {
  833. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  834. int i;
  835. int result;
  836. rt_uint32_t flag = 0;
  837. for (i = 0; i < sizeof(uart_obj) / sizeof(uart_obj[0]); i++)
  838. {
  839. uart_obj[i].serial->ops = &gd32_uart_ops;
  840. uart_obj[i].serial->config = config;
  841. flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
  842. #if defined(RT_SERIAL_USING_DMA)
  843. flag |= RT_DEVICE_FLAG_DMA_RX;
  844. #if defined(RT_SERIAL_USING_TX_DMA)
  845. flag |= RT_DEVICE_FLAG_DMA_TX;
  846. #endif
  847. #endif
  848. /* register device */
  849. result = rt_hw_serial_register(uart_obj[i].serial,
  850. uart_obj[i].device_name,
  851. flag,
  852. (void *)&uart_obj[i]);
  853. RT_ASSERT(result == RT_EOK);
  854. }
  855. return result;
  856. }
  857. #endif