uart.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * File : board.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006-2011, 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. * 2011-08-08 lgnq first version
  13. */
  14. #include <rthw.h>
  15. #include <rtthread.h>
  16. #include "uart.h"
  17. /**
  18. * @addtogroup Loongson LS1B
  19. */
  20. /*@{*/
  21. #if defined(RT_USING_UART) && defined(RT_USING_DEVICE)
  22. struct rt_uart_ls1b
  23. {
  24. struct rt_device parent;
  25. rt_uint32_t hw_base;
  26. rt_uint32_t irq;
  27. /* buffer for reception */
  28. rt_uint8_t read_index, save_index;
  29. rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
  30. }uart_device;
  31. static void rt_uart_irqhandler(int irqno)
  32. {
  33. rt_ubase_t level;
  34. rt_uint8_t isr;
  35. struct rt_uart_ls1b* uart = &uart_device;
  36. /* read interrupt status and clear it */
  37. isr = UART_IIR(uart->hw_base);
  38. isr = (isr >> 1) & 0x3;
  39. if (isr & 0x02) /* receive data available */
  40. {
  41. /* Receive Data Available */
  42. while (UART_LSR(uart->hw_base) & UARTLSR_DR)
  43. {
  44. uart->rx_buffer[uart->save_index] = UART_DAT(uart->hw_base);
  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. }
  51. /* invoke callback */
  52. if(uart->parent.rx_indicate != RT_NULL)
  53. {
  54. rt_size_t length;
  55. if (uart->read_index > uart->save_index)
  56. length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
  57. else
  58. length = uart->save_index - uart->read_index;
  59. uart->parent.rx_indicate(&uart->parent, length);
  60. }
  61. }
  62. return;
  63. }
  64. static rt_err_t rt_uart_init (rt_device_t dev)
  65. {
  66. rt_uint32_t baud_div;
  67. struct rt_uart_ls1b *uart = (struct rt_uart_ls1b*)dev;
  68. RT_ASSERT(uart != RT_NULL);
  69. #if 0
  70. /* init UART Hardware */
  71. UART_IER(uart->hw_base) = 0; /* clear interrupt */
  72. UART_FCR(uart->hw_base) = 0x60; /* reset UART Rx/Tx */
  73. /* enable UART clock */
  74. /* set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
  75. UART_LCR(uart->hw_base) = 0x3;
  76. /* set baudrate */
  77. baud_div = DEV_CLK / 16 / UART_BAUDRATE;
  78. UART_LCR(uart->hw_base) |= UARTLCR_DLAB;
  79. UART_MSB(uart->hw_base) = (baud_div >> 8) & 0xff;
  80. UART_LSB(uart->hw_base) = baud_div & 0xff;
  81. UART_LCR(uart->hw_base) &= ~UARTLCR_DLAB;
  82. /* Enable UART unit, enable and clear FIFO */
  83. UART_FCR(uart->hw_base) = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS;
  84. #endif
  85. return RT_EOK;
  86. }
  87. static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
  88. {
  89. struct rt_uart_ls1b *uart = (struct rt_uart_ls1b*)dev;
  90. RT_ASSERT(uart != RT_NULL);
  91. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  92. {
  93. /* Enable the UART Interrupt */
  94. UART_IER(uart->hw_base) |= UARTIER_IRXE;
  95. /* install interrupt */
  96. rt_hw_interrupt_install(uart->irq, rt_uart_irqhandler, RT_NULL);
  97. rt_hw_interrupt_umask(uart->irq);
  98. }
  99. return RT_EOK;
  100. }
  101. static rt_err_t rt_uart_close(rt_device_t dev)
  102. {
  103. struct rt_uart_ls1b *uart = (struct rt_uart_ls1b*)dev;
  104. RT_ASSERT(uart != RT_NULL);
  105. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  106. {
  107. /* Disable the UART Interrupt */
  108. UART_IER(uart->hw_base) &= ~(UARTIER_IRXE);
  109. }
  110. return RT_EOK;
  111. }
  112. static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  113. {
  114. rt_uint8_t* ptr;
  115. struct rt_uart_ls1b *uart = (struct rt_uart_ls1b*)dev;
  116. RT_ASSERT(uart != RT_NULL);
  117. /* point to buffer */
  118. ptr = (rt_uint8_t*) buffer;
  119. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  120. {
  121. while (size)
  122. {
  123. /* interrupt receive */
  124. rt_base_t level;
  125. /* disable interrupt */
  126. level = rt_hw_interrupt_disable();
  127. if (uart->read_index != uart->save_index)
  128. {
  129. *ptr = uart->rx_buffer[uart->read_index];
  130. uart->read_index ++;
  131. if (uart->read_index >= RT_UART_RX_BUFFER_SIZE)
  132. uart->read_index = 0;
  133. }
  134. else
  135. {
  136. /* no data in rx buffer */
  137. /* enable interrupt */
  138. rt_hw_interrupt_enable(level);
  139. break;
  140. }
  141. /* enable interrupt */
  142. rt_hw_interrupt_enable(level);
  143. ptr ++;
  144. size --;
  145. }
  146. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  147. }
  148. return 0;
  149. }
  150. static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  151. {
  152. char *ptr;
  153. struct rt_uart_ls1b *uart = (struct rt_uart_ls1b*)dev;
  154. RT_ASSERT(uart != RT_NULL);
  155. ptr = (char*)buffer;
  156. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  157. {
  158. /* stream mode */
  159. while (size)
  160. {
  161. if (*ptr == '\n')
  162. {
  163. /* FIFO status, contain valid data */
  164. while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE)));
  165. /* write data */
  166. UART_DAT(uart->hw_base) = '\r';
  167. }
  168. /* FIFO status, contain valid data */
  169. while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE)));
  170. /* write data */
  171. UART_DAT(uart->hw_base) = *ptr;
  172. ptr ++;
  173. size --;
  174. }
  175. }
  176. else
  177. {
  178. while ( size != 0 )
  179. {
  180. /* FIFO status, contain valid data */
  181. while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE)));
  182. /* write data */
  183. UART_DAT(uart->hw_base) = *ptr;
  184. ptr++;
  185. size--;
  186. }
  187. }
  188. return (rt_size_t) ptr - (rt_size_t) buffer;
  189. }
  190. void rt_hw_uart_init(void)
  191. {
  192. struct rt_uart_ls1b* uart;
  193. /* get uart device */
  194. uart = &uart_device;
  195. /* device initialization */
  196. uart->parent.type = RT_Device_Class_Char;
  197. rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
  198. uart->read_index = uart->save_index = 0;
  199. #if defined(RT_USING_UART0)
  200. uart->hw_base = UART0_BASE;
  201. uart->irq = LS1B_UART0_IRQ;
  202. #elif defined(RT_USING_UART1)
  203. uart->hw_base = UART1_BASE;
  204. uart->irq = LS1B_UART1_IRQ;
  205. #endif
  206. /* device interface */
  207. uart->parent.init = rt_uart_init;
  208. uart->parent.open = rt_uart_open;
  209. uart->parent.close = rt_uart_close;
  210. uart->parent.read = rt_uart_read;
  211. uart->parent.write = rt_uart_write;
  212. uart->parent.control = RT_NULL;
  213. uart->parent.user_data = RT_NULL;
  214. rt_device_register(&uart->parent, "uart0",
  215. RT_DEVICE_FLAG_RDWR |
  216. RT_DEVICE_FLAG_STREAM |
  217. RT_DEVICE_FLAG_INT_RX);
  218. }
  219. #endif /* end of UART */
  220. /*@}*/