SLIPEncodedUSBSerial.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "SLIPEncodedUSBSerial.h"
  2. /*
  3. CONSTRUCTOR
  4. */
  5. //instantiate with the transmission layer
  6. #if (defined(CORE_TEENSY) && defined(USB_SERIAL)) || (!defined(CORE_TEENSY) && defined(__AVR_ATmega32U4__)) || defined(__SAM3X8E__) || (defined(_USB) && defined(_USE_USB_FOR_SERIAL_)) || defined(BOARD_maple_mini) || defined(_SAMD21_) || defined(__ARM__) || (defined(__PIC32MX__) || defined(__PIC32MZ__))
  7. //USB Serials
  8. SLIPEncodedUSBSerial::SLIPEncodedUSBSerial(
  9. #if defined(CORE_TEENSY)
  10. #if defined(USB_HOST_TEENSY36)
  11. USBSerial
  12. #else
  13. usb_serial_class
  14. #endif
  15. #elif defined(__SAM3X8E__) || defined(__AVR_ATmega32U4__) || defined(_SAMD21_) || defined(__ARM__)
  16. Serial_
  17. #elif (defined(__PIC32MX__) || defined(__PIC32MZ__))
  18. CDCACM
  19. #else
  20. #error unknown platform
  21. #endif
  22. &s){
  23. serial = &s;
  24. rstate = CHAR;
  25. }
  26. static const uint8_t eot = 0300;
  27. static const uint8_t slipesc = 0333;
  28. static const uint8_t slipescend = 0334;
  29. static const uint8_t slipescesc = 0335;
  30. /*
  31. SERIAL METHODS
  32. */
  33. bool SLIPEncodedUSBSerial::endofPacket()
  34. {
  35. if(rstate == SECONDEOT)
  36. {
  37. rstate = CHAR;
  38. return true;
  39. }
  40. if (rstate==FIRSTEOT)
  41. {
  42. if(serial->available())
  43. {
  44. uint8_t c =serial->peek();
  45. if(c==eot)
  46. {
  47. serial->read(); // throw it on the floor
  48. }
  49. }
  50. rstate = CHAR;
  51. return true;
  52. }
  53. return false;
  54. }
  55. int SLIPEncodedUSBSerial::available(){
  56. back:
  57. int cnt = serial->available();
  58. if(cnt==0)
  59. return 0;
  60. if(rstate==CHAR)
  61. {
  62. uint8_t c =serial->peek();
  63. if(c==slipesc)
  64. {
  65. rstate = SLIPESC;
  66. serial->read(); // throw it on the floor
  67. goto back;
  68. }
  69. else if( c==eot)
  70. {
  71. rstate = FIRSTEOT;
  72. serial->read(); // throw it on the floor
  73. goto back;
  74. }
  75. return 1; // we may have more but this is the only sure bet
  76. }
  77. else if(rstate==SLIPESC)
  78. return 1;
  79. else if(rstate==FIRSTEOT)
  80. {
  81. if(serial->peek()==eot)
  82. {
  83. rstate = SECONDEOT;
  84. serial->read(); // throw it on the floor
  85. return 0;
  86. }
  87. rstate = CHAR;
  88. }else if (rstate==SECONDEOT) {
  89. rstate = CHAR;
  90. }
  91. return 0;
  92. }
  93. //reads a byte from the buffer
  94. int SLIPEncodedUSBSerial::read(){
  95. back:
  96. uint8_t c = serial->read();
  97. if(rstate==CHAR)
  98. {
  99. if(c==slipesc)
  100. {
  101. rstate=SLIPESC;
  102. goto back;
  103. }
  104. else if(c==eot){
  105. return -1; // xxx this is an error
  106. }
  107. return c;
  108. }
  109. else
  110. if(rstate==SLIPESC)
  111. {
  112. rstate=CHAR;
  113. if(c==slipescend)
  114. return eot;
  115. else if(c==slipescesc)
  116. return slipesc;
  117. else {
  118. // insert some error code here
  119. return -1;
  120. }
  121. }
  122. else
  123. return -1;
  124. }
  125. #ifdef FUTUREDEVELOPMENT
  126. int SLIPEncodedUSBSerial::readBytes( uint8_t *buffer, size_t size)
  127. {
  128. int count = 0;
  129. while(!endofPacket() && available() && (size>0))
  130. {
  131. int c = read();
  132. if(c>=0)
  133. {
  134. *buffer++ = c;
  135. ++count;
  136. --size;
  137. }
  138. else
  139. break;
  140. }
  141. return count;
  142. }
  143. #endif
  144. // as close as we can get to correct behavior
  145. int SLIPEncodedUSBSerial::peek(){
  146. uint8_t c = serial->peek();
  147. if(rstate==SLIPESC)
  148. {
  149. if(c==slipescend)
  150. return eot;
  151. else if(c==slipescesc)
  152. return slipesc;
  153. }
  154. return c;
  155. }
  156. //encode SLIP
  157. size_t SLIPEncodedUSBSerial::write(uint8_t b){
  158. if(b == eot){
  159. serial->write(slipesc);
  160. return serial->write(slipescend);
  161. } else if(b==slipesc) {
  162. serial->write(slipesc);
  163. return serial->write(slipescesc);
  164. } else {
  165. return serial->write(b);
  166. }
  167. }
  168. size_t SLIPEncodedUSBSerial::write(const uint8_t *buffer, size_t size)
  169. {
  170. size_t result=0;
  171. while(size--)
  172. result = write(*buffer++); return result;
  173. }
  174. void SLIPEncodedUSBSerial::begin(unsigned long baudrate){
  175. serial->begin(baudrate);
  176. //
  177. // needed on Leonardo?
  178. // while(!serial)
  179. // ;
  180. }
  181. //SLIP specific method which begins a transmitted packet
  182. void SLIPEncodedUSBSerial::beginPacket() { serial->write(eot); }
  183. //signify the end of the packet with an EOT
  184. void SLIPEncodedUSBSerial::endPacket(){
  185. serial->write(eot);
  186. #if defined(CORE_TEENSY)
  187. serial->send_now();
  188. #endif
  189. }
  190. void SLIPEncodedUSBSerial::flush(){
  191. serial->flush();
  192. }
  193. #endif