uart.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. * 2010-03-08 Bernard The first version for LPC17xx
  9. * 2010-05-02 Aozima update CMSIS to 130
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include "board.h"
  14. #include "LPC177x_8x.h"
  15. #include "lpc177x_8x_uart.h"
  16. #include "lpc177x_8x_pinsel.h"
  17. /**
  18. * @addtogroup LPC11xx
  19. */
  20. /*@{*/
  21. struct rt_uart_lpc
  22. {
  23. struct rt_device parent;
  24. LPC_UART_TypeDef * UART;
  25. IRQn_Type UART_IRQn;
  26. /* buffer for reception */
  27. rt_uint8_t read_index, save_index;
  28. rt_uint8_t rx_buffer[RT_SERIAL_RB_BUFSZ];
  29. };
  30. #ifdef BSP_USING_UART0
  31. struct rt_uart_lpc uart0_device;
  32. #endif
  33. #ifdef BSP_USING_UART1
  34. struct rt_uart_lpc uart1_device;
  35. #endif
  36. #ifdef BSP_USING_UART0
  37. void UART0_IRQHandler(void)
  38. {
  39. rt_ubase_t level, iir;
  40. struct rt_uart_lpc* uart = &uart0_device;
  41. /* enter interrupt */
  42. rt_interrupt_enter();
  43. /* read IIR and clear it */
  44. iir = uart->UART->IIR;
  45. if (iir == UART_IIR_INTID_RDA) /* Receive Data Available */
  46. {
  47. /* Receive Data Available */
  48. uart->rx_buffer[uart->save_index] = uart->UART->RBR;
  49. level = rt_hw_interrupt_disable();
  50. uart->save_index ++;
  51. if (uart->save_index >= RT_SERIAL_RB_BUFSZ)
  52. uart->save_index = 0;
  53. rt_hw_interrupt_enable(level);
  54. /* invoke callback */
  55. if(uart->parent.rx_indicate != RT_NULL)
  56. {
  57. rt_size_t length;
  58. if (uart->read_index > uart->save_index)
  59. length = RT_SERIAL_RB_BUFSZ - uart->read_index + uart->save_index;
  60. else
  61. length = uart->save_index - uart->read_index;
  62. uart->parent.rx_indicate(&uart->parent, length);
  63. }
  64. }
  65. /* leave interrupt */
  66. rt_interrupt_leave();
  67. return;
  68. }
  69. #endif
  70. #ifdef BSP_USING_UART1
  71. void UART1_IRQHandler(void)
  72. {
  73. rt_ubase_t level, iir;
  74. struct rt_uart_lpc* uart = &uart1_device;
  75. /* enter interrupt */
  76. rt_interrupt_enter();
  77. /* read IIR and clear it */
  78. iir = uart->UART->IIR;
  79. if (iir == UART_IIR_INTID_RDA) /* Receive Data Available */
  80. {
  81. /* Receive Data Available */
  82. uart->rx_buffer[uart->save_index] = uart->UART->RBR;
  83. level = rt_hw_interrupt_disable();
  84. uart->save_index ++;
  85. if (uart->save_index >= RT_SERIAL_RB_BUFSZ)
  86. uart->save_index = 0;
  87. rt_hw_interrupt_enable(level);
  88. /* invoke callback */
  89. if(uart->parent.rx_indicate != RT_NULL)
  90. {
  91. rt_size_t length;
  92. if (uart->read_index > uart->save_index)
  93. length = RT_SERIAL_RB_BUFSZ - uart->read_index + uart->save_index;
  94. else
  95. length = uart->save_index - uart->read_index;
  96. uart->parent.rx_indicate(&uart->parent, length);
  97. }
  98. }
  99. /* leave interrupt */
  100. rt_interrupt_leave();
  101. return;
  102. }
  103. #endif
  104. static rt_err_t rt_uart_init (rt_device_t dev)
  105. {
  106. struct rt_uart_lpc *uart = (struct rt_uart_lpc*)dev;
  107. UART_CFG_Type UART_ConfigStruct;
  108. #ifdef BSP_USING_UART0
  109. if( uart->UART == LPC_UART0 )
  110. {
  111. /*
  112. * Initialize UART0 pin connect
  113. * P0.2: TXD
  114. * P0.3: RXD
  115. */
  116. PINSEL_ConfigPin(0, 2, 1);
  117. PINSEL_ConfigPin(0, 3, 1);
  118. UART_ConfigStruct.Baud_rate = 115200;
  119. UART_ConfigStruct.Databits = UART_DATABIT_8;
  120. UART_ConfigStruct.Parity = UART_PARITY_NONE;
  121. UART_ConfigStruct.Stopbits = UART_STOPBIT_1;
  122. UART_Init( uart->UART, &UART_ConfigStruct);
  123. // Enable UART Transmit
  124. UART_TxCmd( uart->UART, ENABLE);
  125. UART_IntConfig( uart->UART, UART_INTCFG_RBR, ENABLE);
  126. }
  127. #endif
  128. #ifdef BSP_USING_UART1
  129. if( ((LPC_UART1_TypeDef *)uart->UART) == LPC_UART1 )
  130. {
  131. /*
  132. * Initialize UART1 pin connect
  133. * P3.16: TXD
  134. * P3.17: RXD
  135. */
  136. PINSEL_ConfigPin(3, 16, 3);
  137. PINSEL_ConfigPin(3, 17, 3);
  138. UART_ConfigStruct.Baud_rate = 115200;
  139. UART_ConfigStruct.Databits = UART_DATABIT_8;
  140. UART_ConfigStruct.Parity = UART_PARITY_NONE;
  141. UART_ConfigStruct.Stopbits = UART_STOPBIT_1;
  142. UART_Init( uart->UART,&UART_ConfigStruct);
  143. // Enable UART Transmit
  144. UART_TxCmd( uart->UART, ENABLE);
  145. UART_IntConfig( uart->UART, UART_INTCFG_RBR, ENABLE);
  146. }
  147. #endif
  148. #ifdef BSP_USING_UART2
  149. if( uart->UART == LPC_UART2 )
  150. {
  151. }
  152. #endif
  153. return RT_EOK;
  154. }
  155. static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
  156. {
  157. struct rt_uart_lpc *uart = (struct rt_uart_lpc*)dev;
  158. RT_ASSERT(dev != RT_NULL);
  159. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  160. {
  161. /* Enable the UART Interrupt */
  162. NVIC_EnableIRQ( uart->UART_IRQn );
  163. }
  164. return RT_EOK;
  165. }
  166. static rt_err_t rt_uart_close(rt_device_t dev)
  167. {
  168. struct rt_uart_lpc *uart = (struct rt_uart_lpc*)dev;
  169. RT_ASSERT(dev != RT_NULL);
  170. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  171. {
  172. /* Disable the UART Interrupt */
  173. NVIC_DisableIRQ( uart->UART_IRQn );
  174. }
  175. return RT_EOK;
  176. }
  177. static rt_ssize_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  178. {
  179. rt_uint8_t* ptr;
  180. struct rt_uart_lpc *uart = (struct rt_uart_lpc*)dev;
  181. RT_ASSERT(uart != RT_NULL);
  182. /* point to buffer */
  183. ptr = (rt_uint8_t*) buffer;
  184. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  185. {
  186. while (size)
  187. {
  188. /* interrupt receive */
  189. rt_base_t level;
  190. /* disable interrupt */
  191. level = rt_hw_interrupt_disable();
  192. if (uart->read_index != uart->save_index)
  193. {
  194. *ptr = uart->rx_buffer[uart->read_index];
  195. uart->read_index ++;
  196. if (uart->read_index >= RT_SERIAL_RB_BUFSZ)
  197. uart->read_index = 0;
  198. }
  199. else
  200. {
  201. /* no data in rx buffer */
  202. /* enable interrupt */
  203. rt_hw_interrupt_enable(level);
  204. break;
  205. }
  206. /* enable interrupt */
  207. rt_hw_interrupt_enable(level);
  208. ptr ++;
  209. size --;
  210. }
  211. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  212. }
  213. return 0;
  214. }
  215. static rt_ssize_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  216. {
  217. struct rt_uart_lpc *uart = (struct rt_uart_lpc*)dev;
  218. char *ptr;
  219. ptr = (char*)buffer;
  220. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  221. {
  222. /* stream mode */
  223. while (size)
  224. {
  225. if (*ptr == '\n')
  226. {
  227. while (!(uart->UART->LSR & UART_LSR_THRE));
  228. UART_SendByte( uart->UART,'\r');
  229. }
  230. while (!(uart->UART->LSR & UART_LSR_THRE));
  231. UART_SendByte( uart->UART,*ptr);
  232. ptr ++;
  233. size --;
  234. }
  235. }
  236. else
  237. {
  238. UART_Send( uart->UART, (uint8_t *)buffer, size, BLOCKING);
  239. }
  240. return (rt_size_t) ptr - (rt_size_t) buffer;
  241. }
  242. void rt_hw_usart_init(void)
  243. {
  244. struct rt_uart_lpc* uart;
  245. #ifdef BSP_USING_UART0
  246. /* get uart device */
  247. uart = &uart0_device;
  248. uart0_device.UART = LPC_UART0;
  249. uart0_device.UART_IRQn = UART0_IRQn;
  250. /* device initialization */
  251. uart->parent.type = RT_Device_Class_Char;
  252. rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
  253. uart->read_index = uart->save_index = 0;
  254. /* device interface */
  255. uart->parent.init = rt_uart_init;
  256. uart->parent.open = rt_uart_open;
  257. uart->parent.close = rt_uart_close;
  258. uart->parent.read = rt_uart_read;
  259. uart->parent.write = rt_uart_write;
  260. uart->parent.control = RT_NULL;
  261. uart->parent.user_data = RT_NULL;
  262. rt_device_register(&uart->parent,
  263. "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
  264. #endif
  265. #ifdef BSP_USING_UART1
  266. /* get uart device */
  267. uart = &uart1_device;
  268. uart1_device.UART = (LPC_UART_TypeDef *)LPC_UART1;
  269. uart1_device.UART_IRQn = UART1_IRQn;
  270. /* device initialization */
  271. uart->parent.type = RT_Device_Class_Char;
  272. rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
  273. uart->read_index = uart->save_index = 0;
  274. /* device interface */
  275. uart->parent.init = rt_uart_init;
  276. uart->parent.open = rt_uart_open;
  277. uart->parent.close = rt_uart_close;
  278. uart->parent.read = rt_uart_read;
  279. uart->parent.write = rt_uart_write;
  280. uart->parent.control = RT_NULL;
  281. uart->parent.user_data = RT_NULL;
  282. rt_device_register(&uart->parent,
  283. "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
  284. #endif
  285. }
  286. /*@}*/