drv_uart.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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. * 2019-07-15 Magicoe The first version for LPC55S6x
  9. */
  10. #include <rtthread.h>
  11. #include "drv_uart.h"
  12. #include "fsl_usart.h"
  13. #include "fsl_common.h"
  14. #include "fsl_iocon.h"
  15. #ifdef RT_USING_SERIAL
  16. #if defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL
  17. #error "Please don't define 'FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL'!"
  18. #endif
  19. #if !defined(BSP_USING_UART0) && \
  20. !defined(BSP_USING_UART1) && \
  21. !defined(BSP_USING_UART2) && \
  22. !defined(BSP_USING_UART3) && \
  23. !defined(BSP_USING_UART4) && \
  24. !defined(BSP_USING_UART5) && \
  25. !defined(BSP_USING_UART6) && \
  26. !defined(BSP_USING_UART7)
  27. #error "Please define at least one UARTx"
  28. #endif
  29. #include <rtdevice.h>
  30. /* lpc uart driver */
  31. struct lpc_uart
  32. {
  33. USART_Type *uart_base;
  34. IRQn_Type irqn;
  35. clock_name_t clock_src;
  36. struct rt_serial_device *serial;
  37. char *device_name;
  38. };
  39. static void uart_isr(struct rt_serial_device *serial);
  40. #if defined(BSP_USING_UART0)
  41. struct rt_serial_device serial0;
  42. void FLEXCOMM0_IRQHandler(void)
  43. {
  44. uart_isr(&serial0);
  45. }
  46. #endif /* BSP_USING_UART1 */
  47. #if defined(BSP_USING_UART1)
  48. struct rt_serial_device serial1;
  49. void FLEXCOMM1_IRQHandler(void)
  50. {
  51. uart_isr(&serial1);
  52. }
  53. #endif /* BSP_USING_UART1 */
  54. #if defined(BSP_USING_UART2)
  55. struct rt_serial_device serial2;
  56. void FLEXCOMM2_IRQHandler(void)
  57. {
  58. uart_isr(&serial2);
  59. }
  60. #endif /* BSP_USING_UART2 */
  61. #if defined(BSP_USING_UART3)
  62. struct rt_serial_device serial3;
  63. void FLEXCOMM3_IRQHandler(void)
  64. {
  65. uart_isr(&serial3);
  66. }
  67. #endif /* BSP_USING_UART3 */
  68. #if defined(BSP_USING_UART4)
  69. struct rt_serial_device serial4;
  70. void FLEXCOMM4_IRQHandler(void)
  71. {
  72. uart_isr(&serial4);
  73. }
  74. #endif /* BSP_USING_UART4 */
  75. #if defined(BSP_USING_UART5)
  76. struct rt_serial_device serial5;
  77. void FLEXCOMM5_IRQHandler(void)
  78. {
  79. uart_isr(&serial5);
  80. }
  81. #endif /* BSP_USING_UART5 */
  82. #if defined(BSP_USING_UART6)
  83. struct rt_serial_device serial6;
  84. void FLEXCOMM6_IRQHandler(void)
  85. {
  86. uart_isr(&serial6);
  87. }
  88. #endif /* BSP_USING_UART6 */
  89. #if defined(BSP_USING_UART7)
  90. struct rt_serial_device serial7;
  91. void FLEXCOMM7_IRQHandler(void)
  92. {
  93. uart_isr(&serial7);
  94. }
  95. #endif /* BSP_USING_UART7 */
  96. static const struct lpc_uart uarts[] =
  97. {
  98. #ifdef BSP_USING_UART0
  99. {
  100. USART0,
  101. FLEXCOMM0_IRQn,
  102. kCLOCK_Flexcomm0,
  103. &serial0,
  104. "uart0",
  105. },
  106. #endif
  107. #ifdef BSP_USING_UART1
  108. {
  109. USART1,
  110. FLEXCOMM1_IRQn,
  111. kCLOCK_Flexcomm1,
  112. &serial1,
  113. "uart1",
  114. },
  115. #endif
  116. #ifdef BSP_USING_UART2
  117. {
  118. USART2,
  119. FLEXCOMM2_IRQn,
  120. kCLOCK_Flexcomm2,
  121. &serial2,
  122. "uart2",
  123. },
  124. #endif
  125. #ifdef BSP_USING_UART3
  126. {
  127. USART3,
  128. FLEXCOMM3_IRQn,
  129. kCLOCK_Flexcomm3,
  130. &serial3,
  131. "uart3",
  132. },
  133. #endif
  134. #ifdef BSP_USING_UART4
  135. {
  136. USART4,
  137. FLEXCOMM4_IRQn,
  138. kCLOCK_Flexcomm4,
  139. &serial4,
  140. "uart4",
  141. },
  142. #endif
  143. #ifdef BSP_USING_UART5
  144. {
  145. USART5,
  146. FLEXCOMM5_IRQn,
  147. kCLOCK_Flexcomm5,
  148. &serial5,
  149. "uart5",
  150. },
  151. #endif
  152. #ifdef BSP_USING_UART6
  153. {
  154. USART6,
  155. FLEXCOMM6_IRQn,
  156. kCLOCK_Flexcomm6,
  157. &serial6,
  158. "uart6",
  159. },
  160. #endif
  161. #ifdef BSP_USING_UART7
  162. {
  163. USART7,
  164. FLEXCOMM7_IRQn,
  165. kCLOCK_Flexcomm7,
  166. &serial7,
  167. "uart7",
  168. },
  169. #endif
  170. };
  171. /**
  172. * @brief UART MSP Initialization
  173. * This function configures the hardware resources used in this example:
  174. * - Peripheral's clock enable
  175. * - Peripheral's GPIO Configuration
  176. * - NVIC configuration for UART interrupt request enable
  177. * @param huart: UART handle pointer
  178. * @retval None
  179. */
  180. void lpc_uart_gpio_init(struct lpc_uart *uart)
  181. {
  182. if (uart->uart_base != RT_NULL)
  183. {
  184. #ifdef BSP_USING_UART0
  185. /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
  186. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);
  187. #endif
  188. #ifdef BSP_USING_UART1
  189. /* attach 12 MHz clock to FLEXCOMM1 (debug console) */
  190. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM1);
  191. #endif
  192. #ifdef BSP_USING_UART2
  193. /* attach 12 MHz clock to FLEXCOMM2 (debug console) */
  194. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM2);
  195. #endif
  196. #ifdef BSP_USING_UART3
  197. /* attach 12 MHz clock to FLEXCOMM3 (debug console) */
  198. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM3);
  199. #endif
  200. #ifdef BSP_USING_UART4
  201. /* attach 12 MHz clock to FLEXCOMM4 (debug console) */
  202. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);
  203. #endif
  204. #ifdef BSP_USING_UART5
  205. /* attach 12 MHz clock to FLEXCOMM5 (debug console) */
  206. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM5);
  207. #endif
  208. #ifdef BSP_USING_UART6
  209. /* attach 12 MHz clock to FLEXCOMM6 (debug console) */
  210. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM6);
  211. #endif
  212. #ifdef BSP_USING_UART7
  213. /* attach 12 MHz clock to FLEXCOMM7 (debug console) */
  214. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM7);
  215. #endif
  216. }
  217. else
  218. {
  219. RT_ASSERT(RT_NULL);
  220. }
  221. }
  222. static rt_err_t lpc_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  223. {
  224. struct lpc_uart *uart;
  225. usart_config_t config;
  226. RT_ASSERT(serial != RT_NULL);
  227. RT_ASSERT(cfg != RT_NULL);
  228. uart = (struct lpc_uart *)serial->parent.user_data;
  229. lpc_uart_gpio_init(uart);
  230. /*
  231. * config.baudRate_Bps = 115200U;
  232. * config.parityMode = kUSART_ParityDisabled;
  233. * config.stopBitCount = kUSART_OneStopBit;
  234. * config.loopback = false;
  235. * config.enableTx = false;
  236. * config.enableRx = false;
  237. */
  238. USART_GetDefaultConfig(&config);
  239. config.baudRate_Bps = cfg->baud_rate;
  240. switch (cfg->data_bits)
  241. {
  242. case DATA_BITS_7:
  243. config.bitCountPerChar = kUSART_7BitsPerChar;
  244. break;
  245. default:
  246. config.bitCountPerChar = kUSART_8BitsPerChar;
  247. break;
  248. }
  249. switch (cfg->stop_bits)
  250. {
  251. case STOP_BITS_2:
  252. config.stopBitCount = kUSART_TwoStopBit;
  253. break;
  254. default:
  255. config.stopBitCount = kUSART_OneStopBit;
  256. break;
  257. }
  258. switch (cfg->parity)
  259. {
  260. case PARITY_ODD:
  261. config.parityMode = kUSART_ParityOdd;
  262. break;
  263. case PARITY_EVEN:
  264. config.parityMode = kUSART_ParityEven;
  265. break;
  266. default:
  267. config.parityMode = kUSART_ParityDisabled;
  268. break;
  269. }
  270. config.enableTx = true;
  271. config.enableRx = true;
  272. USART_Init(uart->uart_base, &config, CLOCK_GetFreq(uart->clock_src));
  273. return RT_EOK;
  274. }
  275. static rt_err_t lpc_control(struct rt_serial_device *serial, int cmd, void *arg)
  276. {
  277. struct lpc_uart *uart;
  278. RT_ASSERT(serial != RT_NULL);
  279. uart = (struct lpc_uart *)serial->parent.user_data;
  280. switch (cmd)
  281. {
  282. case RT_DEVICE_CTRL_CLR_INT:
  283. /* disable rx irq */
  284. USART_DisableInterrupts(uart->uart_base, kUSART_RxLevelInterruptEnable);
  285. DisableIRQ(uart->irqn);
  286. break;
  287. case RT_DEVICE_CTRL_SET_INT:
  288. /* enable rx irq */
  289. USART_EnableInterrupts(uart->uart_base, kUSART_RxLevelInterruptEnable);
  290. EnableIRQ(uart->irqn);
  291. break;
  292. }
  293. return RT_EOK;
  294. }
  295. static int lpc_putc(struct rt_serial_device *serial, char ch)
  296. {
  297. struct lpc_uart *uart;
  298. uart = (struct lpc_uart *)serial->parent.user_data;
  299. while (!(kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(uart->uart_base)));
  300. USART_WriteByte(uart->uart_base, ch);
  301. return 1;
  302. }
  303. static int lpc_getc(struct rt_serial_device *serial)
  304. {
  305. struct lpc_uart *uart;
  306. uart = (struct lpc_uart *)serial->parent.user_data;
  307. if (kUSART_RxFifoNotEmptyFlag & USART_GetStatusFlags(uart->uart_base))
  308. {
  309. return USART_ReadByte(uart->uart_base);
  310. }
  311. else
  312. {
  313. return -1;
  314. }
  315. }
  316. /**
  317. * Uart common interrupt process. This need add to uart ISR.
  318. *
  319. * @param serial serial device
  320. */
  321. static void uart_isr(struct rt_serial_device *serial)
  322. {
  323. struct lpc_uart *uart;
  324. RT_ASSERT(serial != RT_NULL);
  325. uart = (struct lpc_uart *) serial->parent.user_data;
  326. RT_ASSERT(uart != RT_NULL);
  327. /* enter interrupt */
  328. rt_interrupt_enter();
  329. /* UART in mode Receiver -------------------------------------------------*/
  330. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  331. /* leave interrupt */
  332. rt_interrupt_leave();
  333. }
  334. static const struct rt_uart_ops lpc_uart_ops =
  335. {
  336. lpc_configure,
  337. lpc_control,
  338. lpc_putc,
  339. lpc_getc,
  340. };
  341. int rt_hw_uart_init(void)
  342. {
  343. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  344. int i;
  345. for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++)
  346. {
  347. uarts[i].serial->ops = &lpc_uart_ops;
  348. uarts[i].serial->config = config;
  349. /* register UART device */
  350. rt_hw_serial_register(uarts[i].serial,
  351. uarts[i].device_name,
  352. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  353. (void *)&uarts[i]);
  354. }
  355. return 0;
  356. }
  357. INIT_BOARD_EXPORT(rt_hw_uart_init);
  358. #endif /*BSP_USING_SERIAL */