1
0

drv_usart.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-08-20 Abbcc first version
  9. * 2022-12-26 luobeihai add APM2F0 series MCU support
  10. * 2023-03-27 luobeihai add APM32E1/S1 series MCU support
  11. */
  12. #include "board.h"
  13. #include "drv_usart.h"
  14. #ifdef RT_USING_SERIAL
  15. #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
  16. !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4) && \
  17. !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6)
  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. struct apm32_usart
  22. {
  23. const char *name;
  24. USART_T *usartx;
  25. IRQn_Type irq_type;
  26. struct rt_serial_device serial;
  27. };
  28. enum
  29. {
  30. #ifdef BSP_USING_UART1
  31. UART1_INDEX,
  32. #endif
  33. #ifdef BSP_USING_UART2
  34. UART2_INDEX,
  35. #endif
  36. #ifdef BSP_USING_UART3
  37. UART3_INDEX,
  38. #endif
  39. #ifdef BSP_USING_UART4
  40. UART4_INDEX,
  41. #endif
  42. #ifdef BSP_USING_UART5
  43. UART5_INDEX,
  44. #endif
  45. #ifdef BSP_USING_UART6
  46. UART6_INDEX,
  47. #endif
  48. };
  49. static struct apm32_usart usart_config[] =
  50. {
  51. #ifdef BSP_USING_UART1
  52. {
  53. "uart1",
  54. USART1,
  55. USART1_IRQn,
  56. },
  57. #endif
  58. #ifdef BSP_USING_UART2
  59. {
  60. "uart2",
  61. USART2,
  62. USART2_IRQn,
  63. },
  64. #endif
  65. #if defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
  66. || defined(SOC_SERIES_APM32F4)
  67. #ifdef BSP_USING_UART3
  68. {
  69. "uart3",
  70. USART3,
  71. USART3_IRQn,
  72. },
  73. #endif
  74. #ifdef BSP_USING_UART4
  75. {
  76. "uart4",
  77. UART4,
  78. UART4_IRQn,
  79. },
  80. #endif
  81. #ifdef BSP_USING_UART5
  82. {
  83. "uart5",
  84. UART5,
  85. UART5_IRQn,
  86. },
  87. #endif
  88. #ifdef BSP_USING_UART6
  89. {
  90. "uart6",
  91. USART6,
  92. USART6_IRQn,
  93. },
  94. #endif
  95. #endif /* SOC_SERIES_APM32F0 */
  96. };
  97. static rt_err_t apm32_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  98. {
  99. USART_Config_T USART_ConfigStruct;
  100. RT_ASSERT(serial != RT_NULL);
  101. RT_ASSERT(cfg != RT_NULL);
  102. struct apm32_usart *usart_instance = (struct apm32_usart *) serial->parent.user_data;
  103. apm32_usart_init();
  104. USART_ConfigStruct.baudRate = cfg->baud_rate;
  105. USART_ConfigStruct.mode = USART_MODE_TX_RX;
  106. USART_ConfigStruct.parity = USART_PARITY_NONE;
  107. #if defined(SOC_SERIES_APM32F0)
  108. switch (cfg->flowcontrol)
  109. {
  110. case RT_SERIAL_FLOWCONTROL_NONE:
  111. USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
  112. break;
  113. case RT_SERIAL_FLOWCONTROL_CTSRTS:
  114. USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_RTS_CTS;
  115. break;
  116. default:
  117. USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
  118. break;
  119. }
  120. #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
  121. || defined(SOC_SERIES_APM32F4)
  122. switch (cfg->flowcontrol)
  123. {
  124. case RT_SERIAL_FLOWCONTROL_NONE:
  125. USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
  126. break;
  127. case RT_SERIAL_FLOWCONTROL_CTSRTS:
  128. USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_RTS_CTS;
  129. break;
  130. default:
  131. USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
  132. break;
  133. }
  134. #endif /* SOC_SERIES_APM32F0 */
  135. switch (cfg->data_bits)
  136. {
  137. case DATA_BITS_8:
  138. if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
  139. USART_ConfigStruct.wordLength = USART_WORD_LEN_9B;
  140. else
  141. USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
  142. break;
  143. case DATA_BITS_9:
  144. USART_ConfigStruct.wordLength = USART_WORD_LEN_9B;
  145. break;
  146. default:
  147. USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
  148. break;
  149. }
  150. switch (cfg->stop_bits)
  151. {
  152. case STOP_BITS_1:
  153. USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
  154. break;
  155. case STOP_BITS_2:
  156. USART_ConfigStruct.stopBits = USART_STOP_BIT_2;
  157. break;
  158. default:
  159. USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
  160. break;
  161. }
  162. switch (cfg->parity)
  163. {
  164. case PARITY_NONE:
  165. USART_ConfigStruct.parity = USART_PARITY_NONE;
  166. break;
  167. case PARITY_ODD:
  168. USART_ConfigStruct.parity = USART_PARITY_ODD;
  169. break;
  170. case PARITY_EVEN:
  171. USART_ConfigStruct.parity = USART_PARITY_EVEN;
  172. break;
  173. default:
  174. USART_ConfigStruct.parity = USART_PARITY_NONE;
  175. break;
  176. }
  177. USART_Config(usart_instance->usartx, &USART_ConfigStruct);
  178. USART_Enable(usart_instance->usartx);
  179. return RT_EOK;
  180. }
  181. static rt_err_t apm32_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  182. {
  183. struct apm32_usart *usart;
  184. RT_ASSERT(serial != RT_NULL);
  185. usart = (struct apm32_usart *) serial->parent.user_data;
  186. RT_ASSERT(usart != RT_NULL);
  187. #if defined(SOC_SERIES_APM32F0)
  188. switch (cmd)
  189. {
  190. /* disable interrupt */
  191. case RT_DEVICE_CTRL_CLR_INT:
  192. /* disable rx irq */
  193. NVIC_DisableIRQRequest(usart->irq_type);
  194. /* disable interrupt */
  195. USART_DisableInterrupt(usart->usartx, USART_INT_RXBNEIE);
  196. break;
  197. /* enable interrupt */
  198. case RT_DEVICE_CTRL_SET_INT:
  199. /* enable rx irq */
  200. NVIC_EnableIRQRequest(usart->irq_type, 1);
  201. /* enable interrupt */
  202. USART_EnableInterrupt(usart->usartx, USART_INT_RXBNEIE);
  203. break;
  204. }
  205. #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
  206. || defined(SOC_SERIES_APM32F4)
  207. switch (cmd)
  208. {
  209. /* disable interrupt */
  210. case RT_DEVICE_CTRL_CLR_INT:
  211. /* disable rx irq */
  212. NVIC_DisableIRQRequest(usart->irq_type);
  213. /* disable interrupt */
  214. USART_DisableInterrupt(usart->usartx, USART_INT_RXBNE);
  215. break;
  216. /* enable interrupt */
  217. case RT_DEVICE_CTRL_SET_INT:
  218. /* enable rx irq */
  219. NVIC_EnableIRQRequest(usart->irq_type, 1, 0);
  220. /* enable interrupt */
  221. USART_EnableInterrupt(usart->usartx, USART_INT_RXBNE);
  222. break;
  223. }
  224. #endif /* SOC_SERIES_APM32F0 */
  225. return RT_EOK;
  226. }
  227. static int apm32_uart_putc(struct rt_serial_device *serial, char c)
  228. {
  229. struct apm32_usart *usart;
  230. RT_ASSERT(serial != RT_NULL);
  231. usart = (struct apm32_usart *) serial->parent.user_data;
  232. RT_ASSERT(usart != RT_NULL);
  233. USART_TxData(usart->usartx, (uint8_t) c);
  234. while (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXC) == RESET);
  235. return 1;
  236. }
  237. static int apm32_uart_getc(struct rt_serial_device *serial)
  238. {
  239. int ch;
  240. struct apm32_usart *usart;
  241. RT_ASSERT(serial != RT_NULL);
  242. usart = (struct apm32_usart *) serial->parent.user_data;
  243. RT_ASSERT(usart != RT_NULL);
  244. ch = -1;
  245. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET)
  246. {
  247. ch = USART_RxData(usart->usartx);
  248. }
  249. return ch;
  250. }
  251. /**
  252. * Uart common interrupt process. This need add to usart ISR.
  253. *
  254. * @param serial serial device
  255. */
  256. static void usart_isr(struct rt_serial_device *serial)
  257. {
  258. struct apm32_usart *usart;
  259. RT_ASSERT(serial != RT_NULL);
  260. usart = (struct apm32_usart *) serial->parent.user_data;
  261. RT_ASSERT(usart != RT_NULL);
  262. /* UART in mode Receiver */
  263. #if defined(SOC_SERIES_APM32F0)
  264. if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
  265. (USART_ReadIntFlag(usart->usartx, USART_INT_FLAG_RXBNE) != RESET))
  266. #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
  267. || defined(SOC_SERIES_APM32F4)
  268. if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
  269. (USART_ReadIntFlag(usart->usartx, USART_INT_RXBNE) != RESET))
  270. #endif
  271. {
  272. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  273. }
  274. else
  275. {
  276. #if defined(SOC_SERIES_APM32F0)
  277. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_OVRE) != RESET)
  278. {
  279. USART_ClearStatusFlag(usart->usartx, USART_FLAG_OVRE);
  280. }
  281. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_NEF) != RESET)
  282. {
  283. USART_ClearStatusFlag(usart->usartx, USART_FLAG_NEF);
  284. }
  285. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_FEF) != RESET)
  286. {
  287. USART_ClearStatusFlag(usart->usartx, USART_FLAG_FEF);
  288. }
  289. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_PEF) != RESET)
  290. {
  291. USART_ClearStatusFlag(usart->usartx, USART_FLAG_PEF);
  292. }
  293. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTSF) != RESET)
  294. {
  295. USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTSF);
  296. }
  297. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBDF) != RESET)
  298. {
  299. USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBDF);
  300. }
  301. #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
  302. || defined(SOC_SERIES_APM32F4)
  303. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_OVRE) != RESET)
  304. {
  305. USART_ClearStatusFlag(usart->usartx, USART_FLAG_OVRE);
  306. }
  307. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_NE) != RESET)
  308. {
  309. USART_ClearStatusFlag(usart->usartx, USART_FLAG_NE);
  310. }
  311. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_FE) != RESET)
  312. {
  313. USART_ClearStatusFlag(usart->usartx, USART_FLAG_FE);
  314. }
  315. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_PE) != RESET)
  316. {
  317. USART_ClearStatusFlag(usart->usartx, USART_FLAG_PE);
  318. }
  319. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTS) != RESET)
  320. {
  321. USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTS);
  322. }
  323. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBD) != RESET)
  324. {
  325. USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBD);
  326. }
  327. #endif /* SOC_SERIES_APM32F0 */
  328. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXBE) != RESET)
  329. {
  330. USART_ClearStatusFlag(usart->usartx, USART_FLAG_TXBE);
  331. }
  332. }
  333. }
  334. #if defined(BSP_USING_UART1)
  335. void USART1_IRQHandler(void)
  336. {
  337. /* enter interrupt */
  338. rt_interrupt_enter();
  339. usart_isr(&(usart_config[UART1_INDEX].serial));
  340. /* leave interrupt */
  341. rt_interrupt_leave();
  342. }
  343. #endif /* BSP_USING_UART1 */
  344. #if defined(BSP_USING_UART2)
  345. void USART2_IRQHandler(void)
  346. {
  347. /* enter interrupt */
  348. rt_interrupt_enter();
  349. usart_isr(&(usart_config[UART2_INDEX].serial));
  350. /* leave interrupt */
  351. rt_interrupt_leave();
  352. }
  353. #endif /* BSP_USING_UART2 */
  354. #if defined(BSP_USING_UART3)
  355. void USART3_IRQHandler(void)
  356. {
  357. /* enter interrupt */
  358. rt_interrupt_enter();
  359. usart_isr(&(usart_config[UART3_INDEX].serial));
  360. /* leave interrupt */
  361. rt_interrupt_leave();
  362. }
  363. #endif /* BSP_USING_UART3 */
  364. #if defined(BSP_USING_UART4)
  365. void UART4_IRQHandler(void)
  366. {
  367. /* enter interrupt */
  368. rt_interrupt_enter();
  369. usart_isr(&(usart_config[UART4_INDEX].serial));
  370. /* leave interrupt */
  371. rt_interrupt_leave();
  372. }
  373. #endif /* BSP_USING_UART4 */
  374. #if defined(BSP_USING_UART5)
  375. void UART5_IRQHandler(void)
  376. {
  377. /* enter interrupt */
  378. rt_interrupt_enter();
  379. usart_isr(&(usart_config[UART5_INDEX].serial));
  380. /* leave interrupt */
  381. rt_interrupt_leave();
  382. }
  383. #endif /* BSP_USING_UART5 */
  384. #if defined(BSP_USING_UART6)
  385. void USART6_IRQHandler(void)
  386. {
  387. /* enter interrupt */
  388. rt_interrupt_enter();
  389. usart_isr(&(usart_config[UART6_INDEX].serial));
  390. /* leave interrupt */
  391. rt_interrupt_leave();
  392. }
  393. #endif /* BSP_USING_UART6 */
  394. static const struct rt_uart_ops apm32_usart_ops =
  395. {
  396. .configure = apm32_uart_configure,
  397. .control = apm32_uart_control,
  398. .putc = apm32_uart_putc,
  399. .getc = apm32_uart_getc,
  400. .dma_transmit = RT_NULL
  401. };
  402. int rt_hw_usart_init(void)
  403. {
  404. rt_size_t obj_num;
  405. int index;
  406. obj_num = sizeof(usart_config) / sizeof(struct apm32_usart);
  407. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  408. rt_err_t result = 0;
  409. for (index = 0; index < obj_num; index++)
  410. {
  411. usart_config[index].serial.ops = &apm32_usart_ops;
  412. usart_config[index].serial.config = config;
  413. /* register USART device */
  414. result = rt_hw_serial_register(&usart_config[index].serial,
  415. usart_config[index].name,
  416. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX
  417. | RT_DEVICE_FLAG_INT_TX, &usart_config[index]);
  418. RT_ASSERT(result == RT_EOK);
  419. }
  420. return result;
  421. }
  422. #endif /* RT_USING_SERIAL */