serial.c 5.8 KB

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