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.

hidjoystickrptparser.cpp 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "hidjoystickrptparser.h"
  2. /*
  3. * Adapted for the Saitek X52 flight controller
  4. */
  5. JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
  6. joyEvents(evt), oldHat(0), oldButtons(0), oldMouse(0) {
  7. for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++)
  8. oldPad[i] = 0;
  9. }
  10. void JoystickReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *bufPart) {
  11. if (len == 8) {
  12. // First part of buffer, store and do nothing
  13. for (uint8_t i = 0; i < 8; i++) {
  14. buf[i] = bufPart[i];
  15. }
  16. return;
  17. } else {
  18. // Append second part, then evaluate
  19. for (uint8_t i = 0; i < len; i++) {
  20. buf[i + 8] = bufPart[i];
  21. }
  22. }
  23. /*
  24. Serial.println("");
  25. Serial.print("Packet: ");
  26. for (uint8_t i = 0; i < (8 + len); i++) {
  27. PrintHex<uint8_t >(buf[i], 0x80);
  28. Serial.print(" ");
  29. }
  30. Serial.println("");
  31. Serial.println("");
  32. */
  33. // Checking if there are changes in report since the method was last called
  34. bool match = true;
  35. for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++)
  36. if (buf[i] != oldPad[i]) {
  37. match = false;
  38. break;
  39. }
  40. // Calling Game Pad event handler
  41. if (!match && joyEvents) {
  42. buffer.X = buf[0] | ((buf[1] & 0x07) << 8);
  43. buffer.Y = ((buf[1] & 0xF8) >> 3) | ((buf[2] & 0x3F) << 5);
  44. buffer.Rz = ((buf[2] & 0xC0) >> 6) | (buf[3] << 2);
  45. buffer.Z = buf[4];
  46. buffer.Rx = buf[5];
  47. buffer.Ry = buf[6];
  48. buffer.Slider = buf[7];
  49. joyEvents->OnGamePadChanged((const GamePadEventData*)&buffer);
  50. for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) oldPad[i] = buf[i];
  51. }
  52. // Calling Hat Switch event handler`
  53. uint8_t hat = (buf[12] & 0xF0) >> 4;
  54. if (hat != oldHat && joyEvents) {
  55. joyEvents->OnHatSwitch(hat);
  56. oldHat = hat;
  57. }
  58. uint64_t buttons = buf[12] & 0x03;
  59. buttons <<= 8;
  60. buttons |= buf[11];
  61. buttons <<= 8;
  62. buttons |= buf[10];
  63. buttons <<= 8;
  64. buttons |= buf[9];
  65. buttons <<= 8;
  66. buttons |= buf[8];
  67. // Calling Button Event Handler for every button changed
  68. uint64_t changes = (buttons ^ oldButtons);
  69. if (changes) {
  70. for (uint8_t i = 0; i < 34; i++) {
  71. uint64_t mask = (1ull << i);
  72. if ((mask & changes) && joyEvents) {
  73. if (buttons & mask) {
  74. joyEvents->OnButtonDn(i);
  75. } else {
  76. joyEvents->OnButtonUp(i);
  77. }
  78. }
  79. }
  80. oldButtons = buttons;
  81. }
  82. if (oldMouse != buf[13] && joyEvents) {
  83. oldMouse = buf[13];
  84. joyEvents->OnMouseMoved((buf[13] & 0xF0) >> 4, buf[13] & 0x0F);
  85. }
  86. }
  87. void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
  88. Serial.print("X: ");
  89. PrintHex<uint16_t > (evt->X, 0x80);
  90. Serial.print("\tY: ");
  91. PrintHex<uint16_t > (evt->Y, 0x80);
  92. Serial.print("\tZ: ");
  93. PrintHex<uint8_t > (evt->Z, 0x80);
  94. Serial.print("\tRx: ");
  95. PrintHex<uint8_t > (evt->Rx, 0x80);
  96. Serial.print("\tRy: ");
  97. PrintHex<uint8_t > (evt->Ry, 0x80);
  98. Serial.print("\tRz: ");
  99. PrintHex<uint16_t > (evt->Rz, 0x80);
  100. Serial.print("\tSlider: ");
  101. PrintHex<uint8_t > (evt->Slider, 0x80);
  102. Serial.println("");
  103. }
  104. void JoystickEvents::OnHatSwitch(uint8_t hat) {
  105. Serial.print("Hat Switch: ");
  106. PrintHex<uint8_t > (hat, 0x80);
  107. Serial.println("");
  108. }
  109. void JoystickEvents::OnButtonUp(uint8_t but_id) {
  110. Serial.print("Up: ");
  111. Serial.println(but_id, DEC);
  112. }
  113. void JoystickEvents::OnButtonDn(uint8_t but_id) {
  114. Serial.print("Dn: ");
  115. Serial.println(but_id, DEC);
  116. }
  117. void JoystickEvents::OnMouseMoved(uint8_t x, uint8_t y) {
  118. Serial.print("Mouse X: ");
  119. PrintHex<uint8_t >(x, 0x80);
  120. Serial.print("\tY: ");
  121. PrintHex<uint8_t >(y, 0x80);
  122. Serial.println("");
  123. }