SLIPEncodedUSBSerial.cpp 4.5 KB

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