uart.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #include <CMSIS/LPC11xx.h>
  4. #define IER_RBR 0x01
  5. #define IER_THRE 0x02
  6. #define IER_RLS 0x04
  7. #define IIR_PEND 0x01
  8. #define IIR_RLS 0x03
  9. #define IIR_RDA 0x02
  10. #define IIR_CTI 0x06
  11. #define IIR_THRE 0x01
  12. #define LSR_RDR 0x01
  13. #define LSR_OE 0x02
  14. #define LSR_PE 0x04
  15. #define LSR_FE 0x08
  16. #define LSR_BI 0x10
  17. #define LSR_THRE 0x20
  18. #define LSR_TEMT 0x40
  19. #define LSR_RXFE 0x80
  20. /**
  21. * @addtogroup LPC11xx
  22. */
  23. /*@{*/
  24. #if defined(RT_USING_UART) && defined(RT_USING_DEVICE)
  25. #define UART_BAUDRATE 115200
  26. struct rt_uart_lpc
  27. {
  28. struct rt_device parent;
  29. /* buffer for reception */
  30. rt_uint8_t read_index, save_index;
  31. rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
  32. }uart_device;
  33. void UART_IRQHandler(void)
  34. {
  35. rt_ubase_t level, iir;
  36. struct rt_uart_lpc* uart = &uart_device;
  37. /* read IIR and clear it */
  38. iir = LPC_UART->IIR;
  39. iir >>= 1; /* skip pending bit in IIR */
  40. iir &= 0x07; /* check bit 1~3, interrupt identification */
  41. if (iir == IIR_RDA) /* Receive Data Available */
  42. {
  43. /* Receive Data Available */
  44. uart->rx_buffer[uart->save_index] = LPC_UART->RBR;
  45. level = rt_hw_interrupt_disable();
  46. uart->save_index ++;
  47. if (uart->save_index >= RT_UART_RX_BUFFER_SIZE)
  48. uart->save_index = 0;
  49. rt_hw_interrupt_enable(level);
  50. /* invoke callback */
  51. if(uart->parent.rx_indicate != RT_NULL)
  52. {
  53. rt_size_t length;
  54. if (uart->read_index > uart->save_index)
  55. length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
  56. else
  57. length = uart->save_index - uart->read_index;
  58. uart->parent.rx_indicate(&uart->parent, length);
  59. }
  60. }
  61. return;
  62. }
  63. static rt_err_t rt_uart_init (rt_device_t dev)
  64. {
  65. rt_uint32_t Fdiv;
  66. rt_uint32_t regVal;
  67. /* Init UART Hardware */
  68. LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */
  69. LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */
  70. LPC_IOCON->PIO1_7 &= ~0x07;
  71. LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */
  72. /* Enable UART clock */
  73. LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
  74. LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
  75. LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
  76. regVal = LPC_SYSCON->UARTCLKDIV;
  77. /* set baudrate */
  78. regVal = LPC_SYSCON->UARTCLKDIV;
  79. Fdiv = (((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/UART_BAUDRATE ;
  80. LPC_UART->DLM = Fdiv / 256;
  81. LPC_UART->DLL = Fdiv % 256;
  82. LPC_UART->LCR = 0x03; /* DLAB = 0 */
  83. LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
  84. /* Read to clear the line status. */
  85. regVal = LPC_UART->LSR;
  86. /* Ensure a clean start, no data in either TX or RX FIFO. */
  87. while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
  88. while ( LPC_UART->LSR & LSR_RDR )
  89. {
  90. regVal = LPC_UART->RBR; /* Dump data from RX FIFO */
  91. }
  92. LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */
  93. return RT_EOK;
  94. }
  95. static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
  96. {
  97. RT_ASSERT(dev != RT_NULL);
  98. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  99. {
  100. /* Enable the UART Interrupt */
  101. NVIC_EnableIRQ(UART_IRQn);
  102. }
  103. return RT_EOK;
  104. }
  105. static rt_err_t rt_uart_close(rt_device_t dev)
  106. {
  107. RT_ASSERT(dev != RT_NULL);
  108. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  109. {
  110. /* Disable the UART Interrupt */
  111. NVIC_DisableIRQ(UART_IRQn);
  112. }
  113. return RT_EOK;
  114. }
  115. static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  116. {
  117. rt_uint8_t* ptr;
  118. struct rt_uart_lpc *uart = (struct rt_uart_lpc*)dev;
  119. RT_ASSERT(uart != RT_NULL);
  120. /* point to buffer */
  121. ptr = (rt_uint8_t*) buffer;
  122. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  123. {
  124. while (size)
  125. {
  126. /* interrupt receive */
  127. rt_base_t level;
  128. /* disable interrupt */
  129. level = rt_hw_interrupt_disable();
  130. if (uart->read_index != uart->save_index)
  131. {
  132. *ptr = uart->rx_buffer[uart->read_index];
  133. uart->read_index ++;
  134. if (uart->read_index >= RT_UART_RX_BUFFER_SIZE)
  135. uart->read_index = 0;
  136. }
  137. else
  138. {
  139. /* no data in rx buffer */
  140. /* enable interrupt */
  141. rt_hw_interrupt_enable(level);
  142. break;
  143. }
  144. /* enable interrupt */
  145. rt_hw_interrupt_enable(level);
  146. ptr ++;
  147. size --;
  148. }
  149. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  150. }
  151. return 0;
  152. }
  153. static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  154. {
  155. char *ptr;
  156. ptr = (char*)buffer;
  157. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  158. {
  159. /* stream mode */
  160. while (size)
  161. {
  162. if (*ptr == '\n')
  163. {
  164. /* THRE status, contain valid data */
  165. while ( !(LPC_UART->LSR & LSR_THRE) );
  166. /* write data */
  167. LPC_UART->THR = '\r';
  168. }
  169. /* THRE status, contain valid data */
  170. while ( !(LPC_UART->LSR & LSR_THRE) );
  171. /* write data */
  172. LPC_UART->THR = *ptr;
  173. ptr ++;
  174. size --;
  175. }
  176. }
  177. else
  178. {
  179. while ( size != 0 )
  180. {
  181. /* THRE status, contain valid data */
  182. while ( !(LPC_UART->LSR & LSR_THRE) );
  183. /* write data */
  184. LPC_UART->THR = *ptr;
  185. ptr++;
  186. size--;
  187. }
  188. }
  189. return (rt_size_t) ptr - (rt_size_t) buffer;
  190. }
  191. void rt_hw_uart_init(void)
  192. {
  193. struct rt_uart_lpc* uart;
  194. /* get uart device */
  195. uart = &uart_device;
  196. /* device initialization */
  197. uart->parent.type = RT_Device_Class_Char;
  198. rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
  199. uart->read_index = uart->save_index = 0;
  200. uart->parent.rx_indicate = RT_NULL;
  201. uart->parent.tx_complete = RT_NULL;
  202. /* device interface */
  203. uart->parent.init = rt_uart_init;
  204. uart->parent.open = rt_uart_open;
  205. uart->parent.close = rt_uart_close;
  206. uart->parent.read = rt_uart_read;
  207. uart->parent.write = rt_uart_write;
  208. uart->parent.control = RT_NULL;
  209. uart->parent.user_data = RT_NULL;
  210. rt_device_register(&uart->parent,
  211. "uart", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
  212. }
  213. #endif /* end of UART */
  214. /*@}*/