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.

hid_parser.cpp 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Saitek X52 Arduino USB Host Shield Library.
  3. * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
  4. *
  5. * Based on the USB Host Library HID Joystick example
  6. * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
  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 "hid_parser.h"
  13. JoystickReportParser::JoystickReportParser(JoystickEvents* evt)
  14. : joyEvents(evt), oldHat(0), oldButtons(0), oldMouse(0) {
  15. for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
  16. oldPad[i] = 0;
  17. }
  18. }
  19. void JoystickReportParser::Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t* bufPart) {
  20. if (len == 8) {
  21. // First part of buffer, store and do nothing
  22. for (uint8_t i = 0; i < 8; i++) {
  23. buf[i] = bufPart[i];
  24. }
  25. return;
  26. } else {
  27. // Append second part, then evaluate
  28. for (uint8_t i = 0; i < len; i++) {
  29. buf[i + 8] = bufPart[i];
  30. }
  31. }
  32. /*
  33. Serial.println("");
  34. Serial.print("Packet: ");
  35. for (uint8_t i = 0; i < (8 + len); i++) {
  36. PrintHex<uint8_t >(buf[i], 0x80);
  37. Serial.print(" ");
  38. }
  39. Serial.println("");
  40. Serial.println("");
  41. */
  42. // Checking if there are changes in report since the method was last called
  43. bool match = true;
  44. for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
  45. if (buf[i] != oldPad[i]) {
  46. match = false;
  47. break;
  48. }
  49. }
  50. // Calling Game Pad event handler
  51. if (!match && joyEvents) {
  52. buffer.X = buf[0] | ((buf[1] & 0x07) << 8);
  53. buffer.Y = ((buf[1] & 0xF8) >> 3) | ((buf[2] & 0x3F) << 5);
  54. buffer.Rz = ((buf[2] & 0xC0) >> 6) | (buf[3] << 2);
  55. buffer.Z = buf[4];
  56. buffer.Rx = buf[5];
  57. buffer.Ry = buf[6];
  58. buffer.Slider = buf[7];
  59. joyEvents->OnGamePadChanged((const GamePadEventData*)&buffer);
  60. for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
  61. oldPad[i] = buf[i];
  62. }
  63. }
  64. // Calling Hat Switch event handler`
  65. uint8_t hat = (buf[12] & 0xF0) >> 4;
  66. if (hat != oldHat && joyEvents) {
  67. joyEvents->OnHatSwitch(hat);
  68. oldHat = hat;
  69. }
  70. uint64_t buttons = buf[12] & 0x03;
  71. buttons <<= 8;
  72. buttons |= buf[11];
  73. buttons <<= 8;
  74. buttons |= buf[10];
  75. buttons <<= 8;
  76. buttons |= buf[9];
  77. buttons <<= 8;
  78. buttons |= buf[8];
  79. // Calling Button Event Handler for every button changed
  80. uint64_t changes = (buttons ^ oldButtons);
  81. if (changes) {
  82. for (uint8_t i = 0; i < 34; i++) {
  83. uint64_t mask = (1ull << i);
  84. if ((mask & changes) && joyEvents) {
  85. if (buttons & mask) {
  86. joyEvents->OnButtonDn(i);
  87. } else {
  88. joyEvents->OnButtonUp(i);
  89. }
  90. }
  91. }
  92. oldButtons = buttons;
  93. }
  94. if (oldMouse != buf[13] && joyEvents) {
  95. oldMouse = buf[13];
  96. joyEvents->OnMouseMoved((buf[13] & 0xF0) >> 4, buf[13] & 0x0F);
  97. }
  98. }