uart.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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. * 2017-09-15 Haley the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "am_mcu_apollo.h"
  13. /* USART0 */
  14. #define AM_UART0_INST 0
  15. #define UART0_GPIO_RX 2
  16. #define UART0_GPIO_CFG_RX AM_HAL_PIN_2_UART0RX
  17. #define UART0_GPIO_TX 1
  18. #define UART0_GPIO_CFG_TX AM_HAL_PIN_1_UART0TX
  19. /* USART1 */
  20. #define AM_UART1_INST 1
  21. #define UART1_GPIO_RX 9
  22. #define UART1_GPIO_CFG_RX AM_HAL_PIN_9_UART1RX
  23. #define UART1_GPIO_TX 8
  24. #define UART1_GPIO_CFG_TX AM_HAL_PIN_8_UART1TX
  25. #define UART_BUFFER_SIZE 256
  26. uint8_t UartRxBuffer[UART_BUFFER_SIZE];
  27. uint8_t UartTxBuffer[UART_BUFFER_SIZE];
  28. /* AM uart driver */
  29. struct am_uart
  30. {
  31. uint32_t uart_device;
  32. uint32_t uart_interrupt;
  33. };
  34. /**
  35. * @brief Enable the UART
  36. *
  37. * @param Uart driver
  38. *
  39. * This function is Enable the UART
  40. *
  41. * @return None.
  42. */
  43. static void rt_hw_uart_enable(struct am_uart* uart)
  44. {
  45. /* Enable the UART clock */
  46. am_hal_uart_clock_enable(uart->uart_device);
  47. /* Enable the UART */
  48. am_hal_uart_enable(uart->uart_device);
  49. #if defined(RT_USING_UART0)
  50. /* Make sure the UART RX and TX pins are enabled */
  51. am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX | AM_HAL_GPIO_PULL24K);
  52. am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL24K);
  53. #endif /* RT_USING_UART0 */
  54. #if defined(RT_USING_UART1)
  55. /* Make sure the UART RX and TX pins are enabled */
  56. am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX | AM_HAL_GPIO_PULL24K);
  57. am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL24K);
  58. #endif /* RT_USING_UART1 */
  59. }
  60. /**
  61. * @brief Disable the UART
  62. *
  63. * @param Uart driver
  64. *
  65. * This function is Disable the UART
  66. *
  67. * @return None.
  68. */
  69. static void rt_hw_uart_disable(struct am_uart* uart)
  70. {
  71. /* Clear all interrupts before sleeping as having a pending UART interrupt burns power */
  72. am_hal_uart_int_clear(uart->uart_device, 0xFFFFFFFF);
  73. /* Disable the UART */
  74. am_hal_uart_disable(uart->uart_device);
  75. #if defined(RT_USING_UART0)
  76. /* Disable the UART pins */
  77. am_hal_gpio_pin_config(UART0_GPIO_TX, AM_HAL_PIN_DISABLE);
  78. am_hal_gpio_pin_config(UART0_GPIO_RX, AM_HAL_PIN_DISABLE);
  79. #endif /* RT_USING_UART0 */
  80. #if defined(RT_USING_UART1)
  81. /* Disable the UART pins */
  82. am_hal_gpio_pin_config(UART1_GPIO_TX, AM_HAL_PIN_DISABLE);
  83. am_hal_gpio_pin_config(UART1_GPIO_RX, AM_HAL_PIN_DISABLE);
  84. #endif /* RT_USING_UART1 */
  85. /* Disable the UART clock */
  86. am_hal_uart_clock_disable(uart->uart_device);
  87. }
  88. /**
  89. * @brief UART-based string print function.
  90. *
  91. * @param Send buff
  92. *
  93. * This function is used for printing a string via the UART, which for some
  94. * MCU devices may be multi-module.
  95. *
  96. * @return None.
  97. */
  98. void rt_hw_uart_send_string(char *pcString)
  99. {
  100. am_hal_uart_string_transmit_polled(AM_UART0_INST, pcString);
  101. /* Wait until busy bit clears to make sure UART fully transmitted last byte */
  102. while ( am_hal_uart_flags_get(AM_UART0_INST) & AM_HAL_UART_FR_BUSY );
  103. }
  104. //connect am drv to rt drv.
  105. static rt_err_t am_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  106. {
  107. struct am_uart* uart;
  108. am_hal_uart_config_t uart_cfg;
  109. RT_ASSERT(serial != RT_NULL);
  110. RT_ASSERT(cfg != RT_NULL);
  111. uart = (struct am_uart *)serial->parent.user_data;
  112. RT_ASSERT(uart != RT_NULL);
  113. /* Get the configure */
  114. uart_cfg.ui32BaudRate = cfg->baud_rate;
  115. if (cfg->data_bits == DATA_BITS_5)
  116. uart_cfg.ui32DataBits = AM_HAL_UART_DATA_BITS_5;
  117. else if (cfg->data_bits == DATA_BITS_6)
  118. uart_cfg.ui32DataBits = AM_HAL_UART_DATA_BITS_6;
  119. else if (cfg->data_bits == DATA_BITS_7)
  120. uart_cfg.ui32DataBits = AM_HAL_UART_DATA_BITS_7;
  121. else if (cfg->data_bits == DATA_BITS_8)
  122. uart_cfg.ui32DataBits = AM_HAL_UART_DATA_BITS_8;
  123. if (cfg->stop_bits == STOP_BITS_1)
  124. uart_cfg.bTwoStopBits = false;
  125. else if (cfg->stop_bits == STOP_BITS_2)
  126. uart_cfg.bTwoStopBits = true;
  127. if (cfg->parity == PARITY_NONE)
  128. uart_cfg.ui32Parity = AM_HAL_UART_PARITY_NONE;
  129. else if (cfg->parity == PARITY_ODD)
  130. uart_cfg.ui32Parity = AM_HAL_UART_PARITY_ODD;
  131. else if (cfg->parity == PARITY_EVEN)
  132. uart_cfg.ui32Parity = AM_HAL_UART_PARITY_EVEN;
  133. uart_cfg.ui32FlowCtrl = AM_HAL_UART_FLOW_CTRL_NONE;
  134. /* UART Config */
  135. am_hal_uart_config(uart->uart_device, &uart_cfg);
  136. /* Enable the UART FIFO */
  137. am_hal_uart_fifo_config(uart->uart_device, AM_HAL_UART_RX_FIFO_7_8 | AM_HAL_UART_RX_FIFO_7_8);
  138. /* Initialize the UART queues */
  139. am_hal_uart_init_buffered(uart->uart_device, UartRxBuffer, UART_BUFFER_SIZE, UartTxBuffer, UART_BUFFER_SIZE);
  140. /* Enable the UART */
  141. am_hal_uart_enable(uart->uart_device);
  142. /* Enable interrupts */
  143. am_hal_uart_int_enable(uart->uart_device, AM_HAL_UART_INT_RX_TMOUT | AM_HAL_UART_INT_RX);
  144. /* Enable the uart interrupt in the NVIC */
  145. am_hal_interrupt_enable(uart->uart_interrupt);
  146. return RT_EOK;
  147. }
  148. static rt_err_t am_control(struct rt_serial_device *serial, int cmd, void *arg)
  149. {
  150. struct am_uart* uart;
  151. //rt_uint32_t ctrl_arg = (rt_uint32_t)(arg);
  152. RT_ASSERT(serial != RT_NULL);
  153. uart = (struct am_uart *)serial->parent.user_data;
  154. RT_ASSERT(uart != RT_NULL);
  155. switch (cmd)
  156. {
  157. /* disable interrupt */
  158. case RT_DEVICE_CTRL_CLR_INT:
  159. rt_hw_uart_disable(uart);
  160. break;
  161. /* enable interrupt */
  162. case RT_DEVICE_CTRL_SET_INT:
  163. rt_hw_uart_enable(uart);
  164. break;
  165. /* UART config */
  166. case RT_DEVICE_CTRL_CONFIG :
  167. break;
  168. }
  169. return RT_EOK;
  170. }
  171. static int am_putc(struct rt_serial_device *serial, char c)
  172. {
  173. uint32_t rxsize, txsize;
  174. struct am_uart* uart;
  175. RT_ASSERT(serial != RT_NULL);
  176. uart = (struct am_uart *)serial->parent.user_data;
  177. RT_ASSERT(uart != RT_NULL);
  178. am_hal_uart_get_status_buffered(uart->uart_device, &rxsize, &txsize);
  179. //if (txsize > 0)
  180. {
  181. am_hal_uart_char_transmit_buffered(uart->uart_device, c);
  182. }
  183. /* Wait until busy bit clears to make sure UART fully transmitted last byte */
  184. while ( am_hal_uart_flags_get(uart->uart_device) & AM_HAL_UART_FR_BUSY );
  185. return 1;
  186. }
  187. static int am_getc(struct rt_serial_device *serial)
  188. {
  189. char c;
  190. int ch;
  191. uint32_t rxsize, txsize;
  192. struct am_uart* uart;
  193. RT_ASSERT(serial != RT_NULL);
  194. uart = (struct am_uart *)serial->parent.user_data;
  195. RT_ASSERT(uart != RT_NULL);
  196. ch = -1;
  197. am_hal_uart_get_status_buffered(uart->uart_device, &rxsize, &txsize);
  198. if (rxsize > 0)
  199. {
  200. am_hal_uart_char_receive_buffered(uart->uart_device, &c, 1);
  201. ch = c & 0xff;
  202. }
  203. return ch;
  204. }
  205. /**
  206. * Uart common interrupt process. This need add to uart ISR.
  207. *
  208. * @param serial serial device
  209. */
  210. static void uart_isr(struct rt_serial_device *serial)
  211. {
  212. uint32_t status;
  213. struct am_uart* uart;
  214. RT_ASSERT(serial != RT_NULL);
  215. uart = (struct am_uart *) serial->parent.user_data;
  216. RT_ASSERT(uart != RT_NULL);
  217. /* Read the interrupt status */
  218. status = am_hal_uart_int_status_get(uart->uart_device, false);
  219. //rt_kprintf("status is %d\r\n", status);
  220. /* Clear the UART interrupt */
  221. am_hal_uart_int_clear(uart->uart_device, status);
  222. if (status & (AM_HAL_UART_INT_RX_TMOUT | AM_HAL_UART_INT_TX | AM_HAL_UART_INT_RX))
  223. {
  224. am_hal_uart_service_buffered_timeout_save(uart->uart_device, status);
  225. }
  226. if (status & (AM_HAL_UART_INT_RX_TMOUT))
  227. {
  228. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  229. }
  230. if (status & AM_HAL_UART_INT_RX)
  231. {
  232. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  233. }
  234. if (status & AM_HAL_UART_INT_TX)
  235. {
  236. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
  237. }
  238. }
  239. static const struct rt_uart_ops am_uart_ops =
  240. {
  241. am_configure,
  242. am_control,
  243. am_putc,
  244. am_getc,
  245. };
  246. #if defined(RT_USING_UART0)
  247. /* UART0 device driver structure */
  248. struct am_uart uart0 =
  249. {
  250. AM_UART0_INST,
  251. AM_HAL_INTERRUPT_UART0
  252. };
  253. static struct rt_serial_device serial0;
  254. void am_uart0_isr(void)
  255. {
  256. /* enter interrupt */
  257. rt_interrupt_enter();
  258. uart_isr(&serial0);
  259. /* leave interrupt */
  260. rt_interrupt_leave();
  261. }
  262. #endif /* RT_USING_UART0 */
  263. #if defined(RT_USING_UART1)
  264. /* UART1 device driver structure */
  265. struct am_uart uart1 =
  266. {
  267. AM_UART1_INST,
  268. AM_HAL_INTERRUPT_UART1
  269. };
  270. static struct rt_serial_device serial1;
  271. void am_uart1_isr(void)
  272. {
  273. /* enter interrupt */
  274. rt_interrupt_enter();
  275. uart_isr(&serial1);
  276. /* leave interrupt */
  277. rt_interrupt_leave();
  278. }
  279. #endif /* RT_USING_UART1 */
  280. static void GPIO_Configuration(void)
  281. {
  282. #if defined(RT_USING_UART0)
  283. /* Make sure the UART RX and TX pins are enabled */
  284. am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX | AM_HAL_GPIO_PULL24K);
  285. am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL24K);
  286. #endif /* RT_USING_UART0 */
  287. #if defined(RT_USING_UART1)
  288. /* Make sure the UART RX and TX pins are enabled */
  289. am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX | AM_HAL_GPIO_PULL24K);
  290. am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL24K);
  291. #endif /* RT_USING_UART1 */
  292. }
  293. static void RCC_Configuration(struct am_uart* uart)
  294. {
  295. /* Power on the selected UART */
  296. am_hal_uart_pwrctrl_enable(uart->uart_device);
  297. /* Start the UART interface, apply the desired configuration settings */
  298. am_hal_uart_clock_enable(uart->uart_device);
  299. /* Disable the UART before configuring it */
  300. am_hal_uart_disable(uart->uart_device);
  301. }
  302. /**
  303. * @brief Initialize the UART
  304. *
  305. * This function initialize the UART
  306. *
  307. * @return None.
  308. */
  309. int rt_hw_uart_init(void)
  310. {
  311. struct am_uart* uart;
  312. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  313. GPIO_Configuration();
  314. #if defined(RT_USING_UART0)
  315. uart = &uart0;
  316. config.baud_rate = BAUD_RATE_115200;
  317. RCC_Configuration(uart);
  318. serial0.ops = &am_uart_ops;
  319. serial0.config = config;
  320. /* register UART0 device */
  321. rt_hw_serial_register(&serial0, "uart0",
  322. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
  323. RT_DEVICE_FLAG_INT_TX, uart);
  324. #endif /* RT_USING_UART0 */
  325. #if defined(RT_USING_UART1)
  326. uart = &uart1;
  327. config.baud_rate = BAUD_RATE_115200;
  328. RCC_Configuration(uart);
  329. serial1.ops = &am_uart_ops;
  330. serial1.config = config;
  331. /* register UART1 device */
  332. rt_hw_serial_register(&serial1, "uart1",
  333. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
  334. RT_DEVICE_FLAG_INT_TX, uart);
  335. #endif /* RT_USING_UART1 */
  336. return 0;
  337. }
  338. /*@}*/