serial.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. ******************************************************************************
  3. * By : parai
  4. * email:parai@foxmail.com
  5. * 这并不是一个真的串口设备,只是为了能够让内核打印信息而创建
  6. ******************************************************************************
  7. */
  8. #include "rtthread.h"
  9. #define _DEBUG_SERIAL 0
  10. #include "serial.h"
  11. #include <stdio.h>
  12. struct rt_device serial_device;
  13. extern struct serial_int_rx serial_rx;
  14. /*@{*/
  15. /* RT-Thread Device Interface */
  16. /**
  17. * This function initializes serial
  18. */
  19. static rt_err_t rt_serial_init (rt_device_t dev)
  20. {
  21. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  22. {
  23. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  24. {
  25. rt_memset(serial_rx.rx_buffer, 0,
  26. sizeof(serial_rx.rx_buffer));
  27. serial_rx.read_index = 0;
  28. serial_rx.save_index = 0;
  29. }
  30. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  31. }
  32. return RT_EOK;
  33. }
  34. static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag){
  35. #if _DEBUG_SERIAL==1
  36. printf("in rt_serial_open()\n");
  37. #endif
  38. return RT_EOK;
  39. }
  40. static rt_err_t rt_serial_close(rt_device_t dev)
  41. {
  42. #if _DEBUG_SERIAL==1
  43. printf("in rt_serial_close()\n");
  44. #endif
  45. return RT_EOK;
  46. }
  47. static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  48. {
  49. rt_uint8_t* ptr;
  50. rt_err_t err_code;
  51. ptr = buffer;
  52. err_code = RT_EOK;
  53. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  54. {
  55. /* interrupt mode Rx */
  56. while (size)
  57. {
  58. rt_base_t level;
  59. /* disable interrupt */
  60. level = rt_hw_interrupt_disable();
  61. if (serial_rx.read_index != serial_rx.save_index)
  62. {
  63. /* read a character */
  64. *ptr++ = serial_rx.rx_buffer[serial_rx.read_index];
  65. size--;
  66. /* move to next position */
  67. serial_rx.read_index ++;
  68. if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
  69. serial_rx.read_index = 0;
  70. }
  71. else
  72. {
  73. /* set error code */
  74. err_code = -RT_EEMPTY;
  75. /* enable interrupt */
  76. rt_hw_interrupt_enable(level);
  77. break;
  78. }
  79. /* enable interrupt */
  80. rt_hw_interrupt_enable(level);
  81. }
  82. }
  83. /* set error code */
  84. rt_set_errno(err_code);
  85. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  86. }
  87. static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  88. {
  89. #if _DEBUG_SERIAL==1
  90. printf("in rt_serial_write()\n");
  91. #endif
  92. printf("%s",(char*)buffer);
  93. return size;
  94. }
  95. static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
  96. {
  97. RT_ASSERT(dev != RT_NULL);
  98. switch (cmd){
  99. case RT_DEVICE_CTRL_SUSPEND:
  100. /* suspend device */
  101. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  102. break;
  103. case RT_DEVICE_CTRL_RESUME:
  104. /* resume device */
  105. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  106. break;
  107. }
  108. return RT_EOK;
  109. }
  110. /*
  111. * serial register
  112. */
  113. static rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag)
  114. {
  115. RT_ASSERT(device != RT_NULL);
  116. #if _DEBUG_SERIAL==1
  117. printf("in rt_serial_register()\n");
  118. #endif
  119. device->type = RT_Device_Class_Char;
  120. device->rx_indicate = RT_NULL;
  121. device->tx_complete = RT_NULL;
  122. device->init = rt_serial_init;
  123. device->open = rt_serial_open;
  124. device->close = rt_serial_close;
  125. device->read = rt_serial_read;
  126. device->write = rt_serial_write;
  127. device->control = rt_serial_control;
  128. device->user_data = RT_NULL;
  129. /* register a character device */
  130. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  131. }
  132. rt_err_t rt_hw_serial_init(void)
  133. {
  134. return rt_hw_serial_register(&serial_device,"sci0",
  135. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
  136. }