drv_usart.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-04-08 QT-one first version
  9. */
  10. #include "drv_usart.h"
  11. #ifdef RT_USING_SERIAL
  12. #if !defined(BSP_USING_USART0) && !defined(BSP_USING_USART1) && \
  13. !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \
  14. !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3)
  15. #error "Please define at least one BSP_USING_UARTx"
  16. #endif
  17. struct ht32_usart
  18. {
  19. char *name;
  20. HT_USART_TypeDef *usart_x;
  21. IRQn_Type irq;
  22. struct rt_serial_device serial;
  23. };
  24. enum
  25. {
  26. #ifdef BSP_USING_USART0
  27. USART0_INDEX,
  28. #endif
  29. #ifdef BSP_USING_USART1
  30. USART1_INDEX,
  31. #endif
  32. #ifdef BSP_USING_UART0
  33. UART0_INDEX,
  34. #endif
  35. #ifdef BSP_USING_UART1
  36. UART1_INDEX,
  37. #endif
  38. #ifdef BSP_USING_UART2
  39. UART2_INDEX,
  40. #endif
  41. #ifdef BSP_USING_UART3
  42. UART3_INDEX,
  43. #endif
  44. };
  45. static struct ht32_usart usart_config[] =
  46. {
  47. #ifdef BSP_USING_USART0
  48. {
  49. .name = BSP_USING_USART0_NAME,
  50. .usart_x = HT_USART0,
  51. .irq = USART0_IRQn,
  52. .serial = RT_NULL
  53. },
  54. #endif
  55. #ifdef BSP_USING_USART1
  56. {
  57. .name = BSP_USING_USART1_NAME,
  58. .usart_x = HT_USART1,
  59. .irq = USART1_IRQn,
  60. .serial = RT_NULL
  61. },
  62. #endif
  63. #ifdef BSP_USING_UART0
  64. {
  65. .name = BSP_USING_UART0_NAME,
  66. .usart_x = HT_UART0,
  67. .irq = UART0_IRQn,
  68. .serial = RT_NULL
  69. },
  70. #endif
  71. #ifdef BSP_USING_UART1
  72. {
  73. .name = BSP_USING_UART1_NAME,
  74. .usart_x = HT_UART1,
  75. .irq = UART1_IRQn,
  76. .serial = RT_NULL
  77. },
  78. #endif
  79. #ifdef BSP_USING_UART2
  80. {
  81. .name = BSP_USING_UART2_NAME,
  82. .usart_x = HT_UART2,
  83. .irq = UART0_UART2_IRQn,
  84. .serial = RT_NULL
  85. },
  86. #endif
  87. #ifdef BSP_USING_UART3
  88. {
  89. .name = BSP_USING_UART3_NAME,
  90. .usart_x = HT_UART3,
  91. .irq = UART1_UART3_IRQn,
  92. .serial = RT_NULL
  93. },
  94. #endif
  95. };
  96. static rt_err_t ht32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  97. {
  98. CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
  99. USART_InitTypeDef USART_InitStructure = {0};
  100. struct ht32_usart *usart_instance = (struct ht32_usart *)serial->parent.user_data;
  101. RT_ASSERT(serial != RT_NULL);
  102. RT_ASSERT(cfg != RT_NULL);
  103. CKCUClock.Bit.AFIO = 1;
  104. if ((usart_instance->usart_x) == HT_UART0)
  105. CKCUClock.Bit.UART0 = 1;
  106. #if defined(HT_USART0)
  107. else if ((usart_instance->usart_x) == HT_USART0)
  108. CKCUClock.Bit.USART0 = 1;
  109. #endif
  110. #if defined(HT_USART1)
  111. else if ((usart_instance->usart_x) == HT_USART1)
  112. CKCUClock.Bit.USART1 = 1;
  113. #endif
  114. #if defined(HT_UART1)
  115. else if ((usart_instance->usart_x) == HT_UART1)
  116. CKCUClock.Bit.UART1 = 1;
  117. #endif
  118. #if defined(HT_UART2)
  119. else if ((usart_instance->usart_x) == HT_UART2)
  120. CKCUClock.Bit.UART2 = 1;
  121. #endif
  122. #if defined(HT_UART3)
  123. else if ((usart_instance->usart_x) == HT_UART3)
  124. CKCUClock.Bit.UART3 = 1;
  125. #endif
  126. CKCU_PeripClockConfig(CKCUClock, ENABLE);
  127. /* UART gpio init */
  128. ht32_usart_gpio_init((void *)usart_instance->usart_x);
  129. /* baud rate */
  130. USART_InitStructure.USART_BaudRate = (cfg->baud_rate);
  131. /* data width */
  132. switch (cfg->data_bits)
  133. {
  134. case DATA_BITS_7:
  135. USART_InitStructure.USART_WordLength = USART_WORDLENGTH_7B;
  136. break;
  137. case DATA_BITS_8:
  138. USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
  139. break;
  140. case DATA_BITS_9:
  141. USART_InitStructure.USART_WordLength = USART_WORDLENGTH_9B;
  142. break;
  143. default:
  144. USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
  145. break;
  146. }
  147. /* stop bit */
  148. switch (cfg->stop_bits)
  149. {
  150. case STOP_BITS_1:
  151. USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
  152. break;
  153. case STOP_BITS_2:
  154. USART_InitStructure.USART_StopBits = USART_STOPBITS_2;
  155. break;
  156. default:
  157. USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
  158. break;
  159. }
  160. switch (cfg->parity)
  161. {
  162. case PARITY_NONE:
  163. USART_InitStructure.USART_Parity = USART_PARITY_NO;
  164. break;
  165. case PARITY_ODD:
  166. USART_InitStructure.USART_Parity = USART_PARITY_ODD;
  167. break;
  168. case PARITY_EVEN:
  169. USART_InitStructure.USART_Parity = USART_PARITY_EVEN;
  170. break;
  171. default:
  172. USART_InitStructure.USART_Parity = USART_PARITY_NO;
  173. break;
  174. }
  175. /* UART mode */
  176. USART_InitStructure.USART_Mode = USART_MODE_NORMAL;
  177. /* UART init */
  178. USART_Init((usart_instance->usart_x), &USART_InitStructure);
  179. /*UART enable */
  180. USART_TxCmd((usart_instance->usart_x), ENABLE);
  181. USART_RxCmd((usart_instance->usart_x), ENABLE);
  182. return RT_EOK;
  183. }
  184. static rt_err_t ht32_control(struct rt_serial_device *serial, int cmd, void *arg)
  185. {
  186. struct ht32_usart *usart;
  187. RT_ASSERT(serial != RT_NULL);
  188. usart = (struct ht32_usart *) serial->parent.user_data;
  189. RT_ASSERT(usart != RT_NULL);
  190. switch (cmd)
  191. {
  192. case RT_DEVICE_CTRL_CLR_INT:
  193. NVIC_DisableIRQ(usart->irq);
  194. USART_IntConfig(usart->usart_x, USART_INT_RXDR, DISABLE);
  195. break;
  196. case RT_DEVICE_CTRL_SET_INT:
  197. NVIC_EnableIRQ(usart->irq);
  198. USART_IntConfig(usart->usart_x, USART_INT_RXDR, ENABLE);
  199. break;
  200. }
  201. return RT_EOK;
  202. }
  203. static int ht32_putc(struct rt_serial_device *serial, char c)
  204. {
  205. struct ht32_usart *usart;
  206. RT_ASSERT(serial != RT_NULL);
  207. usart = (struct ht32_usart *) serial->parent.user_data;
  208. RT_ASSERT(usart != RT_NULL);
  209. while ((usart->usart_x->SR & USART_FLAG_TXC) == 0);
  210. usart->usart_x->DR = (u8)c;
  211. return 1;
  212. }
  213. static int ht32_getc(struct rt_serial_device *serial)
  214. {
  215. int ch;
  216. struct ht32_usart *usart;
  217. RT_ASSERT(serial != RT_NULL);
  218. usart = (struct ht32_usart *) serial->parent.user_data;
  219. RT_ASSERT(usart != RT_NULL);
  220. ch = -1;
  221. if (USART_GetFlagStatus(usart->usart_x, USART_FLAG_RXDR) != RESET)
  222. {
  223. ch = USART_ReceiveData(usart->usart_x);
  224. }
  225. return ch;
  226. }
  227. static rt_ssize_t ht32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
  228. {
  229. return -RT_ERROR;
  230. }
  231. static const struct rt_uart_ops ht32_usart_ops =
  232. {
  233. .configure = ht32_configure,
  234. .control = ht32_control,
  235. .putc = ht32_putc,
  236. .getc = ht32_getc,
  237. .dma_transmit = ht32_dma_transmit,
  238. };
  239. int rt_hw_usart_init(void)
  240. {
  241. rt_size_t obj_num;
  242. int index;
  243. obj_num = sizeof(usart_config) / sizeof(struct ht32_usart);
  244. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  245. rt_err_t result = 0;
  246. for (index = 0; index < obj_num; index++)
  247. {
  248. usart_config[index].serial.ops = &ht32_usart_ops;
  249. usart_config[index].serial.config = config;
  250. /* register uart device */
  251. result = rt_hw_serial_register(&usart_config[index].serial,
  252. usart_config[index].name,
  253. RT_DEVICE_FLAG_RDWR |
  254. RT_DEVICE_FLAG_INT_RX |
  255. RT_DEVICE_FLAG_INT_TX,
  256. &usart_config[index]);
  257. RT_ASSERT(result == RT_EOK);
  258. }
  259. return result;
  260. }
  261. INIT_BOARD_EXPORT(rt_hw_usart_init);
  262. static void usart_isr(struct rt_serial_device *serial)
  263. {
  264. struct ht32_usart *usart = (struct ht32_usart *)serial->parent.user_data;
  265. RT_ASSERT(usart != RT_NULL);
  266. if ((USART_GetFlagStatus(usart->usart_x, USART_FLAG_RXDR) != RESET) && ((usart->usart_x->IER & USART_INT_RXDR) != RESET))
  267. {
  268. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  269. }
  270. }
  271. #ifdef BSP_USING_USART0
  272. void USART0_IRQHandler(void)
  273. {
  274. /* enter interrupt */
  275. rt_interrupt_enter();
  276. usart_isr(&usart_config[USART0_INDEX].serial);
  277. /* leave interrupt */
  278. rt_interrupt_leave();
  279. }
  280. #endif
  281. #ifdef BSP_USING_USART1
  282. void USART1_IRQHandler(void)
  283. {
  284. /* enter interrupt */
  285. rt_interrupt_enter();
  286. usart_isr(&usart_config[USART1_INDEX].serial);
  287. /* leave interrupt */
  288. rt_interrupt_leave();
  289. }
  290. #endif
  291. #ifdef BSP_USING_UART0
  292. void UART0_IRQHandler(void)
  293. {
  294. /* enter interrupt */
  295. rt_interrupt_enter();
  296. usart_isr(&usart_config[UART0_INDEX].serial);
  297. /* leave interrupt */
  298. rt_interrupt_leave();
  299. }
  300. #endif
  301. #ifdef BSP_USING_UART1
  302. void UART1_IRQHandler(void)
  303. {
  304. /* enter interrupt */
  305. rt_interrupt_enter();
  306. usart_isr(&usart_config[UART1_INDEX].serial);
  307. /* leave interrupt */
  308. rt_interrupt_leave();
  309. }
  310. #endif
  311. #ifdef BSP_USING_UART2
  312. void UART2_IRQHandler(void)
  313. {
  314. /* enter interrupt */
  315. rt_interrupt_enter();
  316. usart_isr(&usart_config[UART2_INDEX].serial);
  317. /* leave interrupt */
  318. rt_interrupt_leave();
  319. }
  320. #endif
  321. #ifdef BSP_USING_UART3
  322. void UART3_IRQHandler(void)
  323. {
  324. /* enter interrupt */
  325. rt_interrupt_enter();
  326. usart_isr(&usart_config[UART3_INDEX].serial);
  327. /* leave interrupt */
  328. rt_interrupt_leave();
  329. }
  330. #endif
  331. #endif /* RT_USING_SERIAL */