uart.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * File : board.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006-2012, 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. * 2015-07-09 chinesebear modified for loongson 1c
  14. */
  15. #include <rthw.h>
  16. #include <rtthread.h>
  17. #include "uart.h"
  18. /**
  19. * @addtogroup Loongson LS1B
  20. */
  21. /*@{*/
  22. #if defined(RT_USING_UART) && defined(RT_USING_DEVICE)
  23. struct rt_uart_ls1c
  24. {
  25. struct rt_device parent;
  26. rt_uint32_t hw_base;
  27. rt_uint32_t irq;
  28. /* buffer for reception */
  29. rt_uint8_t read_index, save_index;
  30. rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
  31. }uart_device;
  32. static void rt_uart_irqhandler(int irqno, void *param)
  33. {
  34. rt_ubase_t level;
  35. rt_uint8_t isr;
  36. struct rt_uart_ls1c *uart = &uart_device;
  37. /* read interrupt status and clear it */
  38. isr = UART_IIR(uart->hw_base);
  39. isr = (isr >> 1) & 0x3;
  40. /* receive data available */
  41. if (isr & 0x02)
  42. {
  43. /* Receive Data Available */
  44. while (UART_LSR(uart->hw_base) & UARTLSR_DR)
  45. {
  46. uart->rx_buffer[uart->save_index] = UART_DAT(uart->hw_base);
  47. level = rt_hw_interrupt_disable();
  48. uart->save_index ++;
  49. if (uart->save_index >= RT_UART_RX_BUFFER_SIZE)
  50. uart->save_index = 0;
  51. rt_hw_interrupt_enable(level);
  52. }
  53. /* invoke callback */
  54. if (uart->parent.rx_indicate != RT_NULL)
  55. {
  56. rt_size_t length;
  57. if (uart->read_index > uart->save_index)
  58. length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
  59. else
  60. length = uart->save_index - uart->read_index;
  61. uart->parent.rx_indicate(&uart->parent, length);
  62. }
  63. }
  64. return;
  65. }
  66. static rt_err_t rt_uart_init(rt_device_t dev)
  67. {
  68. rt_uint32_t baud_div;
  69. struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev;
  70. RT_ASSERT(uart != RT_NULL);
  71. //#if 0
  72. /* init UART Hardware */
  73. UART_IER(uart->hw_base) = 0; /* clear interrupt */
  74. UART_FCR(uart->hw_base) = 0xc3; /* reset UART Rx/Tx */
  75. /* enable UART clock */
  76. /* set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
  77. UART_LCR(uart->hw_base) = 0x80;
  78. /* set baudrate */
  79. baud_div = DEV_CLK / 16 / UART_BAUDRATE /2;
  80. UART_MSB(uart->hw_base) = (baud_div >> 8) & 0xff;
  81. UART_LSB(uart->hw_base) = baud_div & 0xff;
  82. UART_LCR(uart->hw_base) = 0x03;
  83. /* Enable UART unit, enable and clear FIFO */
  84. //UART_FCR(uart->hw_base) = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS;
  85. /* enable RX interrupt */
  86. UART_IER(uart->hw_base) = UARTIER_IRXE|UARTIER_ILE;
  87. //#endif
  88. return RT_EOK;
  89. }
  90. static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
  91. {
  92. struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev;
  93. RT_ASSERT(uart != RT_NULL);
  94. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  95. {
  96. /* Enable the UART Interrupt */
  97. UART_IER(uart->hw_base) |= UARTIER_IRXE;
  98. /* install interrupt */
  99. rt_hw_interrupt_install(uart->irq, rt_uart_irqhandler, RT_NULL, "UART");
  100. rt_hw_interrupt_umask(uart->irq);
  101. }
  102. return RT_EOK;
  103. }
  104. static rt_err_t rt_uart_close(rt_device_t dev)
  105. {
  106. struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev;
  107. RT_ASSERT(uart != RT_NULL);
  108. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  109. {
  110. /* Disable the UART Interrupt */
  111. UART_IER(uart->hw_base) &= ~(UARTIER_IRXE);
  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_ls1c *uart = (struct rt_uart_ls1c *)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. struct rt_uart_ls1c *uart = (struct rt_uart_ls1c *)dev;
  157. RT_ASSERT(uart != RT_NULL);
  158. ptr = (char *)buffer;
  159. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  160. {
  161. /* stream mode */
  162. while (size)
  163. {
  164. if (*ptr == '\n')
  165. {
  166. /* FIFO status, contain valid data */
  167. while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE)));
  168. /* write data */
  169. UART_DAT(uart->hw_base) = '\r';
  170. }
  171. /* FIFO status, contain valid data */
  172. while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE)));
  173. /* write data */
  174. UART_DAT(uart->hw_base) = *ptr;
  175. ptr ++;
  176. size --;
  177. }
  178. }
  179. else
  180. {
  181. while (size != 0)
  182. {
  183. /* FIFO status, contain valid data */
  184. while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE)));
  185. /* write data */
  186. UART_DAT(uart->hw_base) = *ptr;
  187. ptr++;
  188. size--;
  189. }
  190. }
  191. return (rt_size_t)ptr - (rt_size_t)buffer;
  192. }
  193. void rt_hw_uart_init(void)
  194. {
  195. struct rt_uart_ls1c *uart;
  196. /* get uart device */
  197. uart = &uart_device;
  198. /* device initialization */
  199. uart->parent.type = RT_Device_Class_Char;
  200. rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
  201. uart->read_index = uart->save_index = 0;
  202. #if defined(RT_USING_UART0)
  203. uart->hw_base = UART0_BASE;
  204. uart->irq = LS1C_UART0_IRQ;
  205. #elif defined(RT_USING_UART2)
  206. uart->hw_base = UART2_BASE;
  207. uart->irq = LS1C_UART2_IRQ;
  208. #elif defined(RT_USING_UART3)
  209. uart->hw_base = UART3_BASE;
  210. uart->irq = LS1C_UART3_IRQ;
  211. #endif
  212. /* device interface */
  213. uart->parent.init = rt_uart_init;
  214. uart->parent.open = rt_uart_open;
  215. uart->parent.close = rt_uart_close;
  216. uart->parent.read = rt_uart_read;
  217. uart->parent.write = rt_uart_write;
  218. uart->parent.control = RT_NULL;
  219. uart->parent.user_data = RT_NULL;
  220. rt_device_register(&uart->parent, "uart2",
  221. RT_DEVICE_FLAG_RDWR |
  222. RT_DEVICE_FLAG_STREAM |
  223. RT_DEVICE_FLAG_INT_RX);
  224. }
  225. #endif /* end of UART */
  226. /*@}*/