1
0

drv_usart.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * Copyright (c) 2006-2021, 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. */
  10. #include "board.h"
  11. #include "drv_usart.h"
  12. #ifdef RT_USING_SERIAL
  13. #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2)
  14. #error "Please define at least one BSP_USING_UARTx"
  15. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  16. #endif
  17. /* stm32 config class */
  18. struct apm32_usart
  19. {
  20. const char *name;
  21. USART_T *usartx;
  22. IRQn_Type irq_type;
  23. struct rt_serial_device serial;
  24. };
  25. enum
  26. {
  27. #ifdef BSP_USING_UART1
  28. UART1_INDEX,
  29. #endif
  30. #ifdef BSP_USING_UART2
  31. UART2_INDEX,
  32. #endif
  33. };
  34. static struct apm32_usart usart_config[] =
  35. {
  36. #ifdef BSP_USING_UART1
  37. {
  38. "uart1",
  39. USART1,
  40. USART1_IRQn,
  41. },
  42. #endif
  43. #ifdef BSP_USING_UART2
  44. {
  45. "uart2",
  46. USART2,
  47. USART2_IRQn,
  48. },
  49. #endif
  50. };
  51. static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  52. {
  53. USART_Config_T USART_ConfigStruct;
  54. RT_ASSERT(serial != RT_NULL);
  55. RT_ASSERT(cfg != RT_NULL);
  56. struct apm32_usart *usart_instance = (struct apm32_usart *) serial->parent.user_data;
  57. apm32_usart_init();
  58. USART_ConfigStruct.baudRate = cfg->baud_rate;;
  59. USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
  60. USART_ConfigStruct.mode = USART_MODE_TX_RX;
  61. USART_ConfigStruct.parity = USART_PARITY_NONE;
  62. switch (cfg->data_bits)
  63. {
  64. case DATA_BITS_8:
  65. if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
  66. USART_ConfigStruct.wordLength = USART_WORD_LEN_9B;
  67. else
  68. USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
  69. break;
  70. case DATA_BITS_9:
  71. USART_ConfigStruct.wordLength = USART_WORD_LEN_9B;
  72. break;
  73. default:
  74. USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
  75. break;
  76. }
  77. switch (cfg->stop_bits)
  78. {
  79. case STOP_BITS_1:
  80. USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
  81. break;
  82. case STOP_BITS_2:
  83. USART_ConfigStruct.stopBits = USART_STOP_BIT_2;
  84. break;
  85. default:
  86. USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
  87. break;
  88. }
  89. switch (cfg->parity)
  90. {
  91. case PARITY_NONE:
  92. USART_ConfigStruct.parity = USART_PARITY_NONE;
  93. break;
  94. case PARITY_ODD:
  95. USART_ConfigStruct.parity = USART_PARITY_ODD;
  96. break;
  97. case PARITY_EVEN:
  98. USART_ConfigStruct.parity = USART_PARITY_EVEN;
  99. break;
  100. default:
  101. USART_ConfigStruct.parity = USART_PARITY_NONE;
  102. break;
  103. }
  104. USART_Config(usart_instance->usartx, &USART_ConfigStruct);
  105. USART_Enable(usart_instance->usartx);
  106. return RT_EOK;
  107. }
  108. static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  109. {
  110. struct apm32_usart *usart;
  111. RT_ASSERT(serial != RT_NULL);
  112. usart = (struct apm32_usart *) serial->parent.user_data;
  113. RT_ASSERT(usart != RT_NULL);
  114. switch (cmd)
  115. {
  116. /* disable interrupt */
  117. case RT_DEVICE_CTRL_CLR_INT:
  118. /* disable rx irq */
  119. NVIC_DisableIRQRequest(usart->irq_type);
  120. /* disable interrupt */
  121. USART_DisableInterrupt(usart->usartx, USART_INT_RXBNE);
  122. break;
  123. /* enable interrupt */
  124. case RT_DEVICE_CTRL_SET_INT:
  125. /* enable rx irq */
  126. NVIC_EnableIRQRequest(usart->irq_type, 1, 0);
  127. /* enable interrupt */
  128. USART_EnableInterrupt(usart->usartx, USART_INT_RXBNE);
  129. break;
  130. }
  131. return RT_EOK;
  132. }
  133. static int _uart_putc(struct rt_serial_device *serial, char c)
  134. {
  135. struct apm32_usart *usart;
  136. RT_ASSERT(serial != RT_NULL);
  137. usart = (struct apm32_usart *) serial->parent.user_data;
  138. RT_ASSERT(usart != RT_NULL);
  139. USART_TxData(usart->usartx, (uint8_t) c);
  140. while (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXC) == RESET);
  141. return 1;
  142. }
  143. static int _uart_getc(struct rt_serial_device *serial)
  144. {
  145. int ch;
  146. struct apm32_usart *usart;
  147. RT_ASSERT(serial != RT_NULL);
  148. usart = (struct apm32_usart *) serial->parent.user_data;
  149. RT_ASSERT(usart != RT_NULL);
  150. ch = -1;
  151. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET)
  152. {
  153. ch = USART_RxData(usart->usartx);
  154. }
  155. return ch;
  156. }
  157. /**
  158. * Uart common interrupt process. This need add to usart ISR.
  159. *
  160. * @param serial serial device
  161. */
  162. static void usart_isr(struct rt_serial_device *serial)
  163. {
  164. struct apm32_usart *usart;
  165. RT_ASSERT(serial != RT_NULL);
  166. RT_ASSERT(serial != RT_NULL);
  167. usart = (struct apm32_usart *) serial->parent.user_data;
  168. RT_ASSERT(usart != RT_NULL);
  169. /* UART in mode Receiver -------------------------------------------------*/
  170. if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
  171. (USART_ReadIntFlag(usart->usartx, USART_INT_RXBNE) != RESET))
  172. {
  173. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  174. USART_ClearStatusFlag(usart->usartx, USART_FLAG_RXBNE);
  175. USART_ClearIntFlag(usart->usartx, USART_INT_RXBNE);
  176. }
  177. else
  178. {
  179. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTS) != RESET)
  180. {
  181. USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTS);
  182. }
  183. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBD) != RESET)
  184. {
  185. USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBD);
  186. }
  187. if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXBE) != RESET)
  188. {
  189. USART_ClearStatusFlag(usart->usartx, USART_FLAG_TXBE);
  190. }
  191. }
  192. }
  193. #if defined(BSP_USING_UART1)
  194. void USART1_IRQHandler(void)
  195. {
  196. /* enter interrupt */
  197. rt_interrupt_enter();
  198. usart_isr(&(usart_config[UART1_INDEX].serial));
  199. /* leave interrupt */
  200. rt_interrupt_leave();
  201. }
  202. #endif /* BSP_USING_UART1 */
  203. #if defined(BSP_USING_UART2)
  204. void USART2_IRQHandler(void)
  205. {
  206. /* enter interrupt */
  207. rt_interrupt_enter();
  208. usart_isr(&(usart_config[UART2_INDEX].serial));
  209. /* leave interrupt */
  210. rt_interrupt_leave();
  211. }
  212. #endif /* BSP_USING_UART2 */
  213. static const struct rt_uart_ops apm32_usart_ops =
  214. {
  215. .configure = _uart_configure,
  216. .control = _uart_control,
  217. .putc = _uart_putc,
  218. .getc = _uart_getc,
  219. .dma_transmit = RT_NULL
  220. };
  221. int rt_hw_usart_init(void)
  222. {
  223. rt_size_t obj_num;
  224. int index;
  225. obj_num = sizeof(usart_config) / sizeof(struct apm32_usart);
  226. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  227. rt_err_t result = 0;
  228. for (index = 0; index < obj_num; index++)
  229. {
  230. usart_config[index].serial.ops = &apm32_usart_ops;
  231. usart_config[index].serial.config = config;
  232. /* register USART device */
  233. result = rt_hw_serial_register(&usart_config[index].serial,
  234. usart_config[index].name,
  235. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX
  236. | RT_DEVICE_FLAG_INT_TX, &usart_config[index]);
  237. RT_ASSERT(result == RT_EOK);
  238. }
  239. return result;
  240. }
  241. #endif /* RT_USING_SERIAL */