Control drones with a proper joystick
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.

frsky.cpp 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * FrSky Telemetry Protocol Host implementation.
  3. * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
  4. *
  5. * Based on the FrSky Telemetry Protocol documentation:
  6. * http://www.frsky-rc.com/download/down.php?id=128
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation, version 2.
  11. */
  12. #include "frsky.h"
  13. //#define DEBUG_OUTPUT Serial
  14. FrSky::FrSky(Stream* s) : serial(s), dataHandler(0),
  15. alarmThresholdHandler(0), userDataHandler(0), bufferIndex(0) {
  16. for (uint8_t i = 0; i < userDataSize; i++) {
  17. userData[i] = 0;
  18. }
  19. for (uint8_t i = 0; i < bufferSize; i++) {
  20. buffer[i] = 0;
  21. }
  22. }
  23. void FrSky::poll() {
  24. if ((!serial) || (!serial->available())) {
  25. return;
  26. }
  27. uint8_t c = serial->read();
  28. if (c == delimiter) {
  29. if (bufferIndex < minPacketSize) {
  30. bufferIndex = 0;
  31. }
  32. if (bufferIndex >= bufferSize) {
  33. bufferIndex = bufferSize - 1;
  34. }
  35. buffer[bufferIndex++] = c;
  36. if (bufferIndex > minPacketSize) {
  37. handleMessage();
  38. bufferIndex = 0;
  39. }
  40. } else if ((bufferIndex > 0) && (bufferIndex < bufferSize)) {
  41. buffer[bufferIndex++] = c;
  42. }
  43. }
  44. void FrSky::pollAlarms() {
  45. serial->write(delimiter);
  46. writeEscaped(idGetAlarms);
  47. for (uint8_t i = 0; i < 8; i++) {
  48. writeEscaped(0);
  49. }
  50. serial->write(delimiter);
  51. }
  52. void FrSky::setAlarm(AlarmThreshold alarm) {
  53. uint8_t id = (alarm.id == analog1_1) ? idAlarm0
  54. : ((alarm.id == analog1_2) ? idAlarm1
  55. : ((alarm.id == analog2_1) ? idAlarm2 : idAlarm3));
  56. serial->write(delimiter);
  57. writeEscaped(id);
  58. writeEscaped(alarm.value);
  59. writeEscaped(alarm.dir);
  60. writeEscaped(alarm.level);
  61. for (uint8_t i = 0; i < 5; i++) {
  62. writeEscaped(0);
  63. }
  64. serial->write(delimiter);
  65. }
  66. void FrSky::writeEscaped(uint8_t v) {
  67. if ((v == delimiter) || (v == escape)) {
  68. v ^= key;
  69. serial->write(escape);
  70. }
  71. serial->write(v);
  72. }
  73. void FrSky::handleMessage() {
  74. #ifdef DEBUG_OUTPUT
  75. DEBUG_OUTPUT.println("FrSky::handleMessage()");
  76. for (uint8_t i = 0; i < bufferIndex; i++) {
  77. DEBUG_OUTPUT.print(buffer[i], HEX);
  78. }
  79. DEBUG_OUTPUT.println();
  80. #endif
  81. if ((buffer[0] != delimiter) || (buffer[bufferIndex - 1] != delimiter)) {
  82. #ifdef DEBUG_OUTPUT
  83. DEBUG_OUTPUT.println("invalid packet begin/end!");
  84. #endif
  85. return;
  86. }
  87. // Fix escaped bytes
  88. for (uint8_t i = 0; i < (bufferIndex - 1); i++) {
  89. if (buffer[i] == escape) {
  90. buffer[i] = buffer[i + 1] ^ key;
  91. for (uint8_t j = i + 1; j < (bufferIndex - 1); j++) {
  92. buffer[j] = buffer[j + 1];
  93. }
  94. bufferIndex--;
  95. }
  96. }
  97. if (buffer[1] == idVoltageQuality) {
  98. if (dataHandler) {
  99. dataHandler(buffer[2], buffer[3], buffer[4], buffer[5]);
  100. }
  101. } else if (buffer[1] == idUserData) {
  102. uint8_t len = buffer[2];
  103. if (len > userDataSize) {
  104. len = userDataSize;
  105. }
  106. for (uint8_t i = 0; i < len; i++) {
  107. userData[i] = buffer[i + 4];
  108. }
  109. if ((len > 0) && (userDataHandler)) {
  110. userDataHandler(userData, len);
  111. }
  112. } else if ((buffer[1] == idAlarm0) || (buffer[1] == idAlarm1)
  113. || (buffer[1] == idAlarm2) || (buffer[1] == idAlarm3)) {
  114. AnalogValue v = (buffer[1] == idAlarm0) ? analog1_1
  115. : ((buffer[1] == idAlarm1) ? analog1_2
  116. : ((buffer[1] == idAlarm2) ? analog2_1 : analog2_2));
  117. if (alarmThresholdHandler) {
  118. alarmThresholdHandler(AlarmThreshold(v, (GreaterLessThan)buffer[3],
  119. (AlarmLevel)buffer[4], buffer[2]));
  120. }
  121. } else {
  122. #ifdef DEBUG_OUTPUT
  123. DEBUG_OUTPUT.print("Unexpected ID: ");
  124. DEBUG_OUTPUT.println(buffer[1], HEX);
  125. #endif
  126. }
  127. }