PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 line
3.4KB

  1. #include "SLIPEncodedSerial.h"
  2. /*
  3. CONSTRUCTOR
  4. */
  5. //instantiate with the tranmission layer
  6. //use HardwareSerial
  7. SLIPEncodedSerial::SLIPEncodedSerial(HardwareSerial &s){
  8. serial = &s;
  9. rstate = CHAR;
  10. }
  11. static const uint8_t eot = 0300;
  12. static const uint8_t slipesc = 0333;
  13. static const uint8_t slipescend = 0334;
  14. static const uint8_t slipescesc = 0335;
  15. /*
  16. SERIAL METHODS
  17. */
  18. bool SLIPEncodedSerial::endofPacket()
  19. {
  20. if(rstate == SECONDEOT)
  21. {
  22. rstate = CHAR;
  23. return true;
  24. }
  25. if (rstate==FIRSTEOT)
  26. {
  27. if(serial->available())
  28. {
  29. uint8_t c =serial->peek();
  30. if(c==eot)
  31. {
  32. serial->read(); // throw it on the floor
  33. }
  34. }
  35. rstate = CHAR;
  36. return true;
  37. }
  38. return false;
  39. }
  40. int SLIPEncodedSerial::available(){
  41. back:
  42. int cnt = serial->available();
  43. if(cnt==0)
  44. return 0;
  45. if(rstate==CHAR)
  46. {
  47. uint8_t c =serial->peek();
  48. if(c==slipesc)
  49. {
  50. rstate = SLIPESC;
  51. serial->read(); // throw it on the floor
  52. goto back;
  53. }
  54. else if( c==eot)
  55. {
  56. rstate = FIRSTEOT;
  57. serial->read(); // throw it on the floor
  58. goto back;
  59. }
  60. return 1; // we may have more but this is the only sure bet
  61. }
  62. else if(rstate==SLIPESC)
  63. return 1;
  64. else if(rstate==FIRSTEOT)
  65. {
  66. if(serial->peek()==eot)
  67. {
  68. rstate = SECONDEOT;
  69. serial->read(); // throw it on the floor
  70. return 0;
  71. }
  72. rstate = CHAR;
  73. }else if (rstate==SECONDEOT) {
  74. rstate = CHAR;
  75. }
  76. return 0;
  77. }
  78. //reads a byte from the buffer
  79. int SLIPEncodedSerial::read(){
  80. back:
  81. uint8_t c = serial->read();
  82. if(rstate==CHAR)
  83. {
  84. if(c==slipesc)
  85. {
  86. rstate=SLIPESC;
  87. goto back;
  88. }
  89. else if(c==eot){
  90. return -1; // xxx this is an error
  91. }
  92. return c;
  93. }
  94. else
  95. if(rstate==SLIPESC)
  96. {
  97. rstate=CHAR;
  98. if(c==slipescend)
  99. return eot;
  100. else if(c==slipescesc)
  101. return slipesc;
  102. else {
  103. // insert some error code here
  104. return -1;
  105. }
  106. }
  107. else
  108. return -1;
  109. }
  110. // as close as we can get to correct behavior
  111. int SLIPEncodedSerial::peek(){
  112. uint8_t c = serial->peek();
  113. if(rstate==SLIPESC)
  114. {
  115. if(c==slipescend)
  116. return eot;
  117. else if(c==slipescesc)
  118. return slipesc;
  119. }
  120. return c;
  121. }
  122. //the arduino and wiring libraries have different return types for the write function
  123. #if defined(WIRING) || defined(BOARD_DEFS_H)
  124. //encode SLIP
  125. void SLIPEncodedSerial::write(uint8_t b){
  126. if(b == eot){
  127. serial->write(slipesc);
  128. return serial->write(slipescend);
  129. } else if(b==slipesc) {
  130. serial->write(slipesc);
  131. return serial->write(slipescesc);
  132. } else {
  133. return serial->write(b);
  134. }
  135. }
  136. void SLIPEncodedSerial::write(const uint8_t *buffer, size_t size) { while(size--) write(*buffer++); }
  137. #else
  138. //encode SLIP
  139. size_t SLIPEncodedSerial::write(uint8_t b){
  140. if(b == eot){
  141. serial->write(slipesc);
  142. return serial->write(slipescend);
  143. } else if(b==slipesc) {
  144. serial->write(slipesc);
  145. return serial->write(slipescesc);
  146. } else {
  147. return serial->write(b);
  148. }
  149. }
  150. size_t SLIPEncodedSerial::write(const uint8_t *buffer, size_t size) { size_t result=0; while(size--) result = write(*buffer++); return result; }
  151. #endif
  152. void SLIPEncodedSerial::begin(unsigned long baudrate){
  153. serial->begin(baudrate);
  154. }
  155. //SLIP specific method which begins a transmitted packet
  156. void SLIPEncodedSerial::beginPacket() { serial->write(eot); }
  157. //signify the end of the packet with an EOT
  158. void SLIPEncodedSerial::endPacket(){
  159. serial->write(eot);
  160. }
  161. void SLIPEncodedSerial::flush(){
  162. serial->flush();
  163. }