serial.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * File : serial.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development 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://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2009-06-11 Bernard first version
  13. */
  14. #include <rthw.h>
  15. #include <rtthread.h>
  16. #include <inc/hw_types.h>
  17. #include <inc/hw_memmap.h>
  18. #include <inc/hw_uart.h>
  19. #include <inc/hw_ints.h>
  20. #include <driverlib/gpio.h>
  21. #include <driverlib/sysctl.h>
  22. #include <driverlib/interrupt.h>
  23. #include <uart.h>
  24. #include "board.h"
  25. extern void rt_hw_interrupt_thread_switch(void);
  26. #define RT_UART_RX_BUFFER_SIZE 64
  27. /* LM3S serial device */
  28. struct rt_lm3s_serial
  29. {
  30. /* inherit from device */
  31. struct rt_device parent;
  32. rt_uint32_t hw_base;
  33. rt_uint32_t baudrate;
  34. /* reception field */
  35. rt_uint16_t save_index, read_index;
  36. rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
  37. };
  38. #ifdef RT_USING_UART1
  39. struct rt_lm3s_serial serial1;
  40. #endif
  41. #ifdef RT_USING_UART2
  42. struct rt_lm3s_serial serial2;
  43. #endif
  44. void rt_hw_serial_init(void);
  45. void rt_hw_uart_isr(struct rt_lm3s_serial* serial)
  46. {
  47. rt_device_t device;
  48. rt_uint32_t status;
  49. device = (struct rt_device*)serial;
  50. status = UARTIntStatus(serial->hw_base, true);
  51. /* clear interrupt status */
  52. UARTIntClear(serial->hw_base, status);
  53. if (device->flag & RT_DEVICE_FLAG_INT_RX)
  54. {
  55. char ch;
  56. rt_base_t level;
  57. while (UARTCharsAvail(serial->hw_base))
  58. {
  59. ch = UARTCharGetNonBlocking(serial->hw_base);
  60. /* disable interrupt */
  61. level = rt_hw_interrupt_disable();
  62. /* read character */
  63. serial->rx_buffer[serial->save_index] = ch;
  64. serial->save_index ++;
  65. if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
  66. serial->save_index = 0;
  67. /* if the next position is read index, discard this 'read char' */
  68. if (serial->save_index == serial->read_index)
  69. {
  70. serial->read_index ++;
  71. if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
  72. serial->read_index = 0;
  73. }
  74. /* enable interrupt */
  75. rt_hw_interrupt_enable(level);
  76. }
  77. /* invoke callback */
  78. if(device->rx_indicate != RT_NULL)
  79. {
  80. rt_int32_t length;
  81. length = serial->save_index - serial->read_index;
  82. if (length < 0) length += RT_UART_RX_BUFFER_SIZE;
  83. device->rx_indicate(device, length);
  84. }
  85. }
  86. }
  87. #ifdef RT_USING_UART1
  88. void rt_hw_uart_isr_1(int irqno)
  89. {
  90. /* enter interrupt */
  91. rt_interrupt_enter();
  92. /* get serial device */
  93. rt_hw_uart_isr(&serial1);
  94. /* leave interrupt */
  95. rt_interrupt_leave();
  96. rt_hw_interrupt_thread_switch();
  97. }
  98. #endif
  99. #ifdef RT_USING_UART2
  100. void rt_hw_uart_isr_2(int irqno)
  101. {
  102. /* enter interrupt */
  103. rt_interrupt_enter();
  104. /* get serial device */
  105. rt_hw_uart_isr(&serial2);
  106. /* leave interrupt */
  107. rt_interrupt_leave();
  108. rt_hw_interrupt_thread_switch();
  109. }
  110. #endif
  111. /**
  112. * @addtogroup LM3S
  113. */
  114. /*@{*/
  115. static rt_err_t rt_serial_init (rt_device_t dev)
  116. {
  117. return RT_EOK;
  118. }
  119. static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
  120. {
  121. struct rt_lm3s_serial* serial;
  122. serial = (struct rt_lm3s_serial*) dev;
  123. RT_ASSERT(serial != RT_NULL);
  124. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  125. {
  126. /* enable interrupt */
  127. if (serial->hw_base == UART0_BASE)
  128. IntEnable(INT_UART0);
  129. else if (serial->hw_base == UART1_BASE)
  130. IntEnable(INT_UART1);
  131. UARTIntEnable(serial->hw_base, UART_INT_RX | UART_INT_RT);
  132. }
  133. return RT_EOK;
  134. }
  135. static rt_err_t rt_serial_close(rt_device_t dev)
  136. {
  137. struct rt_lm3s_serial* serial;
  138. serial = (struct rt_lm3s_serial*) dev;
  139. RT_ASSERT(serial != RT_NULL);
  140. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  141. {
  142. /* disable UART rx interrupt */
  143. UARTIntDisable(serial->hw_base, UART_INT_RX | UART_INT_RT);
  144. }
  145. return RT_EOK;
  146. }
  147. static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  148. {
  149. return RT_EOK;
  150. }
  151. static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  152. {
  153. rt_uint8_t* ptr;
  154. struct rt_lm3s_serial *serial = (struct rt_lm3s_serial*)dev;
  155. RT_ASSERT(serial != RT_NULL);
  156. /* point to buffer */
  157. ptr = (rt_uint8_t*) buffer;
  158. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  159. {
  160. while (size)
  161. {
  162. /* interrupt receive */
  163. rt_base_t level;
  164. /* disable interrupt */
  165. level = rt_hw_interrupt_disable();
  166. if (serial->read_index != serial->save_index)
  167. {
  168. *ptr = serial->rx_buffer[serial->read_index];
  169. serial->read_index ++;
  170. if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
  171. serial->read_index = 0;
  172. }
  173. else
  174. {
  175. /* no data in rx buffer */
  176. /* enable interrupt */
  177. rt_hw_interrupt_enable(level);
  178. break;
  179. }
  180. /* enable interrupt */
  181. rt_hw_interrupt_enable(level);
  182. ptr ++; size --;
  183. }
  184. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  185. }
  186. else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
  187. {
  188. /* not support right now */
  189. RT_ASSERT(0);
  190. }
  191. /* polling mode */
  192. while (size)
  193. {
  194. *ptr = UARTCharGetNonBlocking(serial->hw_base);
  195. ptr ++; size --;
  196. }
  197. return (rt_size_t)ptr - (rt_size_t)buffer;
  198. }
  199. static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  200. {
  201. struct rt_lm3s_serial* serial;
  202. char *ptr;
  203. serial = (struct rt_lm3s_serial*) dev;
  204. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  205. {
  206. /* not support */
  207. RT_ASSERT(0);
  208. }
  209. else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  210. {
  211. /* not support */
  212. RT_ASSERT(0);
  213. }
  214. /* polling write */
  215. ptr = (char *)buffer;
  216. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  217. {
  218. /* stream mode */
  219. while (size)
  220. {
  221. if (*ptr == '\n')
  222. while (UARTCharPutNonBlocking(serial->hw_base, '\r') == false);
  223. while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
  224. ptr ++;
  225. size --;
  226. }
  227. }
  228. else
  229. {
  230. while (size)
  231. {
  232. while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
  233. ptr ++;
  234. size --;
  235. }
  236. }
  237. return (rt_size_t) ptr - (rt_size_t) buffer;
  238. }
  239. void rt_hw_serial_init(void)
  240. {
  241. struct rt_lm3s_serial* serial;
  242. #ifdef RT_USING_UART1
  243. serial = &serial1;
  244. serial->parent.type = RT_Device_Class_Char;
  245. serial->hw_base = UART0_BASE;
  246. serial->baudrate = 115200;
  247. rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
  248. serial->read_index = serial->save_index = 0;
  249. /* enable UART0 clock */
  250. SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  251. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  252. /* set UART0 pinmux */
  253. GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
  254. /* Configure the UART for 115,200, 8-N-1 operation. */
  255. UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), serial->baudrate,
  256. (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
  257. UART_CONFIG_PAR_NONE));
  258. serial->parent.init = rt_serial_init;
  259. serial->parent.open = rt_serial_open;
  260. serial->parent.close = rt_serial_close;
  261. serial->parent.read = rt_serial_read;
  262. serial->parent.write = rt_serial_write;
  263. serial->parent.control = rt_serial_control;
  264. serial->parent.private = RT_NULL;
  265. rt_device_register(&serial->parent,
  266. "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
  267. #endif
  268. #ifdef RT_USING_UART2
  269. serial = &serial2;
  270. serial->parent.type = RT_Device_Class_Char;
  271. serial->hw_base = 0xE0010000;
  272. serial->baudrate = 115200;
  273. rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
  274. serial->read_index = serial->save_index = 0;
  275. serial->parent.init = rt_serial_init;
  276. serial->parent.open = rt_serial_open;
  277. serial->parent.close = rt_serial_close;
  278. serial->parent.read = rt_serial_read;
  279. serial->parent.write = rt_serial_write;
  280. serial->parent.control = rt_serial_control;
  281. serial->parent.private = RT_NULL;
  282. rt_device_register(&serial->parent,
  283. "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
  284. #endif
  285. }
  286. /*@}*/