serial.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * File : serial.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2013 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. * 2009-02-05 Bernard first version
  13. * 2009-10-25 Bernard fix rt_serial_read bug when there is no data
  14. * in the buffer.
  15. * 2010-03-29 Bernard cleanup code.
  16. * 2013-02-7 prife rewrite for simulator
  17. */
  18. #include <rthw.h>
  19. #include "serial.h"
  20. #include <stdio.h>
  21. #if 0
  22. static FILE *fp = RT_NULL;
  23. #endif
  24. /*@{*/
  25. int seial_save_byte(unsigned char ch, struct serial_device * serial)
  26. {
  27. /* save on rx buffer */
  28. rt_base_t level;
  29. struct rt_device * dev = RT_DEVICE(serial);
  30. /* disable interrupt */
  31. //暂时关闭中断,因为要操作uart数据结构
  32. level = rt_hw_interrupt_disable();
  33. /* save character */
  34. serial->serial_rx.rx_buffer[serial->serial_rx.save_index] = ch;
  35. serial->serial_rx.save_index ++;
  36. //下面的代码检查save_index是否已经到到缓冲区尾部,如果是则回转到头部,称为一个环形缓冲区
  37. if (serial->serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE)
  38. serial->serial_rx.save_index = 0;
  39. //这种情况表示反转后的save_index追上了read_index,则增大read_index,丢弃一个旧的数据
  40. /* if the next position is read index, discard this 'read char' */
  41. if (serial->serial_rx.save_index == serial->serial_rx.read_index)
  42. {
  43. serial->serial_rx.read_index ++;
  44. if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
  45. serial->serial_rx.read_index = 0;
  46. }
  47. /* enable interrupt */
  48. //uart数据结构已经操作完成,重新使能中断
  49. rt_hw_interrupt_enable(level);
  50. /* invoke callback */
  51. if (dev->rx_indicate != RT_NULL)
  52. {
  53. rt_size_t rx_length;
  54. /* get rx length */
  55. rx_length = serial->serial_rx.read_index > serial->serial_rx.save_index ?
  56. SERIAL_RX_BUFFER_SIZE - serial->serial_rx.read_index + serial->serial_rx.save_index :
  57. serial->serial_rx.save_index - serial->serial_rx.read_index;
  58. dev->rx_indicate(dev, rx_length);
  59. }
  60. return 0;
  61. }
  62. /* RT-Thread Device Interface */
  63. /**
  64. * This function initializes serial
  65. */
  66. static rt_err_t rt_serial_init(rt_device_t dev)
  67. {
  68. struct serial_device * serial = SERIAL_DEVICE(dev);
  69. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  70. {
  71. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  72. {
  73. rt_memset(serial->serial_rx.rx_buffer, 0,
  74. sizeof(serial->serial_rx.rx_buffer));
  75. serial->serial_rx.read_index = 0;
  76. serial->serial_rx.save_index = 0;
  77. }
  78. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  79. }
  80. return RT_EOK;
  81. }
  82. static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
  83. {
  84. return RT_EOK;
  85. }
  86. static rt_err_t rt_serial_close(rt_device_t dev)
  87. {
  88. return RT_EOK;
  89. }
  90. static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  91. {
  92. rt_uint8_t *ptr;
  93. rt_err_t err_code;
  94. struct serial_device * serial = SERIAL_DEVICE(dev);
  95. ptr = buffer;
  96. err_code = RT_EOK;
  97. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  98. {
  99. /* interrupt mode Rx */
  100. while (size)
  101. {
  102. rt_base_t level;
  103. /* disable interrupt */
  104. level = rt_hw_interrupt_disable();
  105. if (serial->serial_rx.read_index != serial->serial_rx.save_index)
  106. {
  107. /* read a character */
  108. *ptr++ = serial->serial_rx.rx_buffer[serial->serial_rx.read_index];
  109. size--;
  110. /* move to next position */
  111. serial->serial_rx.read_index ++;
  112. if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
  113. serial->serial_rx.read_index = 0;
  114. }
  115. else
  116. {
  117. /* set error code */
  118. err_code = -RT_EEMPTY;
  119. /* enable interrupt */
  120. rt_hw_interrupt_enable(level);
  121. break;
  122. }
  123. /* enable interrupt */
  124. rt_hw_interrupt_enable(level);
  125. }
  126. }
  127. /* set error code */
  128. rt_set_errno(err_code);
  129. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  130. }
  131. static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  132. {
  133. int level;
  134. #if 0
  135. if (fp == NULL)
  136. fp = fopen("log.txt", "wb+");
  137. if (fp != NULL)
  138. fwrite(buffer, size, 1, fp);
  139. #endif
  140. level = rt_hw_interrupt_disable();
  141. fwrite(buffer, size, 1, stdout);
  142. fflush(stdout);
  143. rt_hw_interrupt_enable(level);
  144. return size;
  145. }
  146. static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  147. {
  148. RT_ASSERT(dev != RT_NULL);
  149. switch (cmd)
  150. {
  151. case RT_DEVICE_CTRL_SUSPEND:
  152. /* suspend device */
  153. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  154. break;
  155. case RT_DEVICE_CTRL_RESUME:
  156. /* resume device */
  157. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  158. break;
  159. }
  160. return RT_EOK;
  161. }
  162. /*
  163. * serial register
  164. */
  165. rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_uint32_t flag)
  166. {
  167. RT_ASSERT(device != RT_NULL);
  168. device->type = RT_Device_Class_Char;
  169. device->rx_indicate = RT_NULL;
  170. device->tx_complete = RT_NULL;
  171. device->init = rt_serial_init;
  172. device->open = rt_serial_open;
  173. device->close = rt_serial_close;
  174. device->read = rt_serial_read;
  175. device->write = rt_serial_write;
  176. device->control = rt_serial_control;
  177. device->user_data = RT_NULL;
  178. /* register a character device */
  179. return rt_device_register(device, name, (rt_uint16_t)(RT_DEVICE_FLAG_RDWR | flag));
  180. }
  181. rt_err_t rt_hw_serial_init(struct serial_device * serial, char * name)
  182. {
  183. return rt_hw_serial_register(RT_DEVICE(serial), name,
  184. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
  185. }