uart.c 9.0 KB

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