From 24dba853963e26d7b376e636ec498284485e4271 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Thu, 19 Mar 2015 22:54:39 -0500 Subject: [PATCH 1/9] Added Joystick support to Arduino Leonardo & Micro Added a USB joystick to the Arduino Leonardo & Micro. Currently class is very simple, but I plan on enhancing it in future versions. --- hardware/arduino/avr/cores/arduino/HID.cpp | 122 ++++++++++++++++++++ hardware/arduino/avr/cores/arduino/USBAPI.h | 32 +++++ 2 files changed, 154 insertions(+) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index 75c37b24b2f..f2fc2dabf3c 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -22,11 +22,13 @@ #ifdef HID_ENABLED //#define RAWHID_ENABLED +#define JOYHID_ENABLED // Singletons for mouse and keyboard Mouse_ Mouse; Keyboard_ Keyboard; +Joystick_ Joystick; //================================================================================ //================================================================================ @@ -124,6 +126,84 @@ const u8 _hidReportDescriptor[] = { 0x91, 0x02, // Output (array) 0xC0 // end collection #endif + +#ifdef JOYHID_ENABLED + // *** Here is where the RAW_HID has been converted to a Joystick device + // *** Inspired by helmpcb.com/electronics/usb-joystick + // *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID + // *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32) + + // 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis) + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x04, // USAGE (Joystick) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x03, // REPORT_ID (3) (This is important when HID_SendReport() is called) + + //Buttons: + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x20, // USAGE_MAXIMUM (Button 32) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x20, // REPORT_COUNT (32) + 0x55, 0x00, // UNIT_EXPONENT (0) + 0x65, 0x00, // UNIT (None) + 0x81, 0x02, // INPUT (Data,Var,Abs) + + // 8 bit Throttle and Steering + 0x05, 0x02, // USAGE_PAGE (Simulation Controls) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0xA1, 0x00, // COLLECTION (Physical) + 0x09, 0xBB, // USAGE (Throttle) + 0x09, 0xBA, // USAGE (Steering) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x02, // REPORT_COUNT (2) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + + // Two Hat switches + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x39, // USAGE (Hat switch) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x07, // LOGICAL_MAXIMUM (7) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315) + 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) + 0x75, 0x04, // REPORT_SIZE (4) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + + 0x09, 0x39, // USAGE (Hat switch) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x07, // LOGICAL_MAXIMUM (7) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315) + 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) + 0x75, 0x04, // REPORT_SIZE (4) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + + 0x09, 0x01, // USAGE (Pointer) + 0xA1, 0x00, // COLLECTION (Physical) + 0x09, 0x30, // USAGE (x) + 0x09, 0x31, // USAGE (y) + 0x09, 0x32, // USAGE (z) + 0x09, 0x33, // USAGE (rx) + 0x09, 0x34, // USAGE (ry) + 0x09, 0x35, // USAGE (rz) + 0x95, 0x06, // REPORT_COUNT (2) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + + 0xc0 // END_COLLECTION +#endif }; extern const HIDDescriptor _hidInterface PROGMEM; @@ -513,6 +593,48 @@ size_t Keyboard_::write(uint8_t c) return p; // just return the result of press() since release() almost always returns 1 } +//================================================================================ +//================================================================================ +// Joystick +// + +Joystick_::Joystick_() +{ +} + +#define joystickStateSize 13 + +void Joystick_::setState(JoystickState *joystickState) +{ + uint8_t data[joystickStateSize]; + uint32_t buttonTmp; + buttonTmp = joystickState->buttons; + + data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB + buttonTmp >>= 8; + data[1] = buttonTmp & 0xFF; + buttonTmp >>= 8; + data[2] = buttonTmp & 0xFF; + buttonTmp >>= 8; + data[3] = buttonTmp & 0xFF; + + data[4] = joystickState->throttle; // Throttle + data[5] = joystickState->rudder; // Steering + + data[6] = (joystickState->hatSw2 << 4) | joystickState->hatSw1; // Pack hat-switch states into a single byte + + data[7] = joystickState->xAxis; // X axis + data[8] = joystickState->yAxis; // Y axis + data[9] = joystickState->zAxis; // Z axis + data[10] = joystickState->xRotAxis; // rX axis + data[11] = joystickState->yRotAxis; // rY axis + data[12] = joystickState->zRotAxis; // rZ axis + + // HID_SendReport(Report number, array of values in same order as HID descriptor, length) + HID_SendReport(3, data, joystickStateSize); + // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from +} + #endif #endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 2fab957f930..5dc187b7bc6 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -183,6 +183,38 @@ class Keyboard_ : public Print }; extern Keyboard_ Keyboard; +//================================================================================ +//================================================================================ +// Joystick (Gamepad) +typedef struct +{ + uint8_t xAxis; + uint8_t yAxis; + uint8_t zAxis; + + uint8_t xRotAxis; + uint8_t yRotAxis; + uint8_t zRotAxis; + + uint8_t throttle; + uint8_t rudder; + + uint8_t hatSw1; // 0-7 correspond to 0-315� in 45� steps. 8 means the hat-switch is centered + uint8_t hatSw2; // All other values are invalid + + uint32_t buttons; // 32 general buttons - each bit corresponds to a separate button + +} JoystickState; + +class Joystick_ +{ +public: + Joystick_(); + + void setState(JoystickState *joystickState); +}; +extern Joystick_ Joystick; + //================================================================================ //================================================================================ // Low level API From ede64517730f2160b81a58cccaabd720b418ccf4 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Wed, 25 Mar 2015 23:06:30 -0500 Subject: [PATCH 2/9] Buttons, X, Y, Z, Throttle, and Rudder Added button, throttle, rudder, x, y, and z axis methods. Still need to do x, y, and z axis rotation and hat values. --- hardware/arduino/avr/cores/arduino/HID.cpp | 80 ++++++++++++++++++++- hardware/arduino/avr/cores/arduino/USBAPI.h | 23 ++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index f2fc2dabf3c..e67f4c87e81 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -598,11 +598,89 @@ size_t Keyboard_::write(uint8_t c) // Joystick // +#define joystickStateSize 13 + Joystick_::Joystick_() { } -#define joystickStateSize 13 +void Joystick_::begin() +{ + buttons = 0; + throttle = 0; + rudder = 0; + xAxis = 0; + yAxis = 0; + zAxis = 0; + sendState(); +} + +void Joystick_::end() +{ +} + +void Joystick_::pressButton(byte button) +{ + bitSet(buttons, button); +} + +void Joystick_::releaseButton(byte button) +{ + bitClear(buttons, button); +} + +void Joystick_::setThrottle(uint8_t value) +{ + throttle = value; +} +void Joystick_::setRudder(uint8_t value) +{ + rudder = value; +} + +void Joystick_::setXAxis(int8_t value) +{ + xAxis = value; +} +void Joystick_::setYAxis(int8_t value) +{ + yAxis = value; +} +void Joystick_::setZAxis(int8_t value) +{ + zAxis = value; +} + +void Joystick_::sendState() +{ + uint8_t data[joystickStateSize]; + uint32_t buttonTmp = buttons; + + data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB + buttonTmp >>= 8; + data[1] = buttonTmp & 0xFF; + buttonTmp >>= 8; + data[2] = buttonTmp & 0xFF; + buttonTmp >>= 8; + data[3] = buttonTmp & 0xFF; + + data[4] = throttle; + data[5] = rudder; + /* + data[6] = (joystickState->hatSw2 << 4) | joystickState->hatSw1; // Pack hat-switch states into a single byte + */ + data[7] = xAxis + 127; + data[8] = yAxis + 127; + data[9] = zAxis + 127; + /* + data[10] = joystickState->xRotAxis; // rX axis + data[11] = joystickState->yRotAxis; // rY axis + data[12] = joystickState->zRotAxis; // rZ axis + */ + // HID_SendReport(Report number, array of values in same order as HID descriptor, length) + HID_SendReport(3, data, joystickStateSize); + // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from +} void Joystick_::setState(JoystickState *joystickState) { diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 5dc187b7bc6..1d722ced125 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -208,9 +208,32 @@ typedef struct class Joystick_ { +private: + int8_t xAxis; + int8_t yAxis; + int8_t zAxis; + uint32_t buttons; + uint8_t throttle; + uint8_t rudder; + public: Joystick_(); + void begin(); + void end(); + + void setXAxis(int8_t value); + void setYAxis(int8_t value); + void setZAxis(int8_t value); + + void pressButton(uint8_t button); + void releaseButton(uint8_t button); + + void setThrottle(uint8_t value); + void setRudder(uint8_t value); + + void sendState(); + void setState(JoystickState *joystickState); }; extern Joystick_ Joystick; From bc4f591814b577bac405d61cf435100ccd9fbbc5 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Fri, 27 Mar 2015 21:57:23 -0500 Subject: [PATCH 3/9] Added setHatSwitch. Added the setHatSwitch function. --- hardware/arduino/avr/cores/arduino/HID.cpp | 17 +++++++++++++---- hardware/arduino/avr/cores/arduino/USBAPI.h | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index e67f4c87e81..93786efbfe9 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -612,6 +612,8 @@ void Joystick_::begin() xAxis = 0; yAxis = 0; zAxis = 0; + hatSw[0] = -1; + hatSw[1] = -1; sendState(); } @@ -651,12 +653,18 @@ void Joystick_::setZAxis(int8_t value) zAxis = value; } +void Joystick_::setHatSwitch(int8_t hatSwitch, int8_t value) +{ + hatSw[hatSwitch % 2] = value; +} + void Joystick_::sendState() { uint8_t data[joystickStateSize]; uint32_t buttonTmp = buttons; - data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB + // Break 32 bit button-state out into 4 bytes, to send over USB + data[0] = buttonTmp & 0xFF; buttonTmp >>= 8; data[1] = buttonTmp & 0xFF; buttonTmp >>= 8; @@ -666,9 +674,10 @@ void Joystick_::sendState() data[4] = throttle; data[5] = rudder; - /* - data[6] = (joystickState->hatSw2 << 4) | joystickState->hatSw1; // Pack hat-switch states into a single byte - */ + + // Pack hat-switch states into a single byte + data[6] = (hatSw[1] << 4) | (B00001111 & hatSw[0]); + data[7] = xAxis + 127; data[8] = yAxis + 127; data[9] = zAxis + 127; diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 1d722ced125..d71cc13887e 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -215,6 +215,7 @@ class Joystick_ uint32_t buttons; uint8_t throttle; uint8_t rudder; + int8_t hatSw[2]; public: Joystick_(); @@ -232,6 +233,8 @@ class Joystick_ void setThrottle(uint8_t value); void setRudder(uint8_t value); + void setHatSwitch(int8_t hatSwitch, int8_t value); + void sendState(); void setState(JoystickState *joystickState); From 9db49f450ff2f6346899b5caf2f05b5a396f1141 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Sat, 28 Mar 2015 14:41:04 -0500 Subject: [PATCH 4/9] Added X, Y, and Z axis rotation. Added X, Y, and Z axis rotation methods. --- hardware/arduino/avr/cores/arduino/HID.cpp | 95 ++++++++++----------- hardware/arduino/avr/cores/arduino/USBAPI.h | 33 ++----- 2 files changed, 55 insertions(+), 73 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index 93786efbfe9..91e30d84655 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -42,6 +42,7 @@ Joystick_ Joystick; #define RAWHID_USAGE 0x0C00 #define RAWHID_TX_SIZE 64 #define RAWHID_RX_SIZE 64 +#define JOYSTICK_REPORT_ID 0x03 extern const u8 _hidReportDescriptor[] PROGMEM; const u8 _hidReportDescriptor[] = { @@ -133,12 +134,10 @@ const u8 _hidReportDescriptor[] = { // *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID // *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32) - // 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis) - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x04, // USAGE (Joystick) 0xa1, 0x01, // COLLECTION (Application) - 0x85, 0x03, // REPORT_ID (3) (This is important when HID_SendReport() is called) + 0x85, JOYSTICK_REPORT_ID, // REPORT_ID (3) //Buttons: 0x05, 0x09, // USAGE_PAGE (Button) @@ -198,7 +197,7 @@ const u8 _hidReportDescriptor[] = { 0x09, 0x33, // USAGE (rx) 0x09, 0x34, // USAGE (ry) 0x09, 0x35, // USAGE (rz) - 0x95, 0x06, // REPORT_COUNT (2) + 0x95, 0x06, // REPORT_COUNT (6) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION @@ -606,14 +605,17 @@ Joystick_::Joystick_() void Joystick_::begin() { - buttons = 0; - throttle = 0; - rudder = 0; xAxis = 0; yAxis = 0; zAxis = 0; - hatSw[0] = -1; - hatSw[1] = -1; + xAxisRotation = 0; + yAxisRotation = 0; + zAxisRotation = 0; + buttons = 0; + throttle = 0; + rudder = 0; + hatSwitch[0] = -1; + hatSwitch[1] = -1; sendState(); } @@ -653,9 +655,22 @@ void Joystick_::setZAxis(int8_t value) zAxis = value; } -void Joystick_::setHatSwitch(int8_t hatSwitch, int8_t value) +void Joystick_::setXAxisRotation(int16_t value) +{ + xAxisRotation = value; +} +void Joystick_::setYAxisRotation(int16_t value) +{ + yAxisRotation = value; +} +void Joystick_::setZAxisRotation(int16_t value) +{ + zAxisRotation = value; +} + +void Joystick_::setHatSwitch(int8_t hatSwitchIndex, int16_t value) { - hatSw[hatSwitch % 2] = value; + hatSwitch[hatSwitchIndex % 2] = value; } void Joystick_::sendState() @@ -663,7 +678,7 @@ void Joystick_::sendState() uint8_t data[joystickStateSize]; uint32_t buttonTmp = buttons; - // Break 32 bit button-state out into 4 bytes, to send over USB + // Split 32 bit button-state into 4 bytes data[0] = buttonTmp & 0xFF; buttonTmp >>= 8; data[1] = buttonTmp & 0xFF; @@ -675,51 +690,33 @@ void Joystick_::sendState() data[4] = throttle; data[5] = rudder; + // Calculate hat-switch values + uint8_t convertedHatSwitch[2]; + for (int hatSwitchIndex = 0; hatSwitchIndex < 2; hatSwitchIndex++) + { + if (hatSwitch[hatSwitchIndex] < 0) + { + convertedHatSwitch[hatSwitchIndex] = 8; + } + else + { + convertedHatSwitch[hatSwitchIndex] = (hatSwitch[hatSwitchIndex] % 360) / 45; + } + } + // Pack hat-switch states into a single byte - data[6] = (hatSw[1] << 4) | (B00001111 & hatSw[0]); + data[6] = (convertedHatSwitch[1] << 4) | (B00001111 & convertedHatSwitch[0]); data[7] = xAxis + 127; data[8] = yAxis + 127; data[9] = zAxis + 127; - /* - data[10] = joystickState->xRotAxis; // rX axis - data[11] = joystickState->yRotAxis; // rY axis - data[12] = joystickState->zRotAxis; // rZ axis - */ - // HID_SendReport(Report number, array of values in same order as HID descriptor, length) - HID_SendReport(3, data, joystickStateSize); - // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from -} - -void Joystick_::setState(JoystickState *joystickState) -{ - uint8_t data[joystickStateSize]; - uint32_t buttonTmp; - buttonTmp = joystickState->buttons; - - data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB - buttonTmp >>= 8; - data[1] = buttonTmp & 0xFF; - buttonTmp >>= 8; - data[2] = buttonTmp & 0xFF; - buttonTmp >>= 8; - data[3] = buttonTmp & 0xFF; - - data[4] = joystickState->throttle; // Throttle - data[5] = joystickState->rudder; // Steering - - data[6] = (joystickState->hatSw2 << 4) | joystickState->hatSw1; // Pack hat-switch states into a single byte - data[7] = joystickState->xAxis; // X axis - data[8] = joystickState->yAxis; // Y axis - data[9] = joystickState->zAxis; // Z axis - data[10] = joystickState->xRotAxis; // rX axis - data[11] = joystickState->yRotAxis; // rY axis - data[12] = joystickState->zRotAxis; // rZ axis + data[10] = (xAxisRotation % 360) * 0.708; + data[11] = (yAxisRotation % 360) * 0.708; + data[12] = (zAxisRotation % 360) * 0.708; // HID_SendReport(Report number, array of values in same order as HID descriptor, length) - HID_SendReport(3, data, joystickStateSize); - // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from + HID_SendReport(JOYSTICK_REPORT_ID, data, joystickStateSize); } #endif diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index d71cc13887e..756c4e58142 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -186,36 +186,19 @@ extern Keyboard_ Keyboard; //================================================================================ //================================================================================ // Joystick (Gamepad) -typedef struct -{ - uint8_t xAxis; - uint8_t yAxis; - uint8_t zAxis; - - uint8_t xRotAxis; - uint8_t yRotAxis; - uint8_t zRotAxis; - - uint8_t throttle; - uint8_t rudder; - - uint8_t hatSw1; // 0-7 correspond to 0-315� in 45� steps. 8 means the hat-switch is centered - uint8_t hatSw2; // All other values are invalid - - uint32_t buttons; // 32 general buttons - each bit corresponds to a separate button - -} JoystickState; - class Joystick_ { private: int8_t xAxis; int8_t yAxis; int8_t zAxis; + int16_t xAxisRotation; + int16_t yAxisRotation; + int16_t zAxisRotation; uint32_t buttons; uint8_t throttle; uint8_t rudder; - int8_t hatSw[2]; + int16_t hatSwitch[2]; public: Joystick_(); @@ -227,17 +210,19 @@ class Joystick_ void setYAxis(int8_t value); void setZAxis(int8_t value); + void setXAxisRotation(int16_t value); + void setYAxisRotation(int16_t value); + void setZAxisRotation(int16_t value); + void pressButton(uint8_t button); void releaseButton(uint8_t button); void setThrottle(uint8_t value); void setRudder(uint8_t value); - void setHatSwitch(int8_t hatSwitch, int8_t value); + void setHatSwitch(int8_t hatSwitch, int16_t value); void sendState(); - - void setState(JoystickState *joystickState); }; extern Joystick_ Joystick; From 0924cf45775cd22ad33f343cc48784be5c557df2 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Sat, 28 Mar 2015 16:00:46 -0500 Subject: [PATCH 5/9] Added setButton method Added a setButton method to make it easier to set the button state in some situations. --- hardware/arduino/avr/cores/arduino/HID.cpp | 16 +++++++++++++--- hardware/arduino/avr/cores/arduino/USBAPI.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index 91e30d84655..4dff6f860e1 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -623,12 +623,22 @@ void Joystick_::end() { } -void Joystick_::pressButton(byte button) +void Joystick_::setButton(uint8_t button, uint8_t value) +{ + if (value == 0) + { + releaseButton(button); + } + else + { + pressButton(button); + } +} +void Joystick_::pressButton(uint8_t button) { bitSet(buttons, button); } - -void Joystick_::releaseButton(byte button) +void Joystick_::releaseButton(uint8_t button) { bitClear(buttons, button); } diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 756c4e58142..7a6aeda763d 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -214,6 +214,7 @@ class Joystick_ void setYAxisRotation(int16_t value); void setZAxisRotation(int16_t value); + void setButton(uint8_t button, uint8_t value); void pressButton(uint8_t button); void releaseButton(uint8_t button); From 56cba08af613c15f49e0d0696f12435848cedfa4 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Sat, 28 Mar 2015 20:57:24 -0500 Subject: [PATCH 6/9] Added autoSendState mode Added the ability to automatically update the state of the joystick whenever anything changes. This is the new default mode. --- hardware/arduino/avr/cores/arduino/HID.cpp | 39 ++++++++++++--------- hardware/arduino/avr/cores/arduino/USBAPI.h | 3 +- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index 4dff6f860e1..e453ff3e491 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -22,9 +22,8 @@ #ifdef HID_ENABLED //#define RAWHID_ENABLED -#define JOYHID_ENABLED -// Singletons for mouse and keyboard +// Singletons for mouse, keyboard, and joystick Mouse_ Mouse; Keyboard_ Keyboard; @@ -126,20 +125,14 @@ const u8 _hidReportDescriptor[] = { 0x09, 0x02, // usage 0x91, 0x02, // Output (array) 0xC0 // end collection -#endif - -#ifdef JOYHID_ENABLED - // *** Here is where the RAW_HID has been converted to a Joystick device - // *** Inspired by helmpcb.com/electronics/usb-joystick - // *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID - // *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32) - +#else + // Joystick 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x04, // USAGE (Joystick) 0xa1, 0x01, // COLLECTION (Application) 0x85, JOYSTICK_REPORT_ID, // REPORT_ID (3) - //Buttons: + // 32 Buttons 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x20, // USAGE_MAXIMUM (Button 32) @@ -163,7 +156,7 @@ const u8 _hidReportDescriptor[] = { 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION - // Two Hat switches + // Two Hat switches (8 Positions) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x39, // USAGE (Hat switch) 0x15, 0x00, // LOGICAL_MINIMUM (0) @@ -185,10 +178,10 @@ const u8 _hidReportDescriptor[] = { 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) + // X, Y, and Z Axis 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 0x75, 0x08, // REPORT_SIZE (8) - 0x09, 0x01, // USAGE (Pointer) 0xA1, 0x00, // COLLECTION (Physical) 0x09, 0x30, // USAGE (x) @@ -600,10 +593,6 @@ size_t Keyboard_::write(uint8_t c) #define joystickStateSize 13 Joystick_::Joystick_() -{ -} - -void Joystick_::begin() { xAxis = 0; yAxis = 0; @@ -616,6 +605,11 @@ void Joystick_::begin() rudder = 0; hatSwitch[0] = -1; hatSwitch[1] = -1; +} + +void Joystick_::begin(bool initAutoSendState) +{ + autoSendState = initAutoSendState; sendState(); } @@ -637,50 +631,61 @@ void Joystick_::setButton(uint8_t button, uint8_t value) void Joystick_::pressButton(uint8_t button) { bitSet(buttons, button); + if (autoSendState) sendState(); } void Joystick_::releaseButton(uint8_t button) { bitClear(buttons, button); + if (autoSendState) sendState(); } void Joystick_::setThrottle(uint8_t value) { throttle = value; + if (autoSendState) sendState(); } void Joystick_::setRudder(uint8_t value) { rudder = value; + if (autoSendState) sendState(); } void Joystick_::setXAxis(int8_t value) { xAxis = value; + if (autoSendState) sendState(); } void Joystick_::setYAxis(int8_t value) { yAxis = value; + if (autoSendState) sendState(); } void Joystick_::setZAxis(int8_t value) { zAxis = value; + if (autoSendState) sendState(); } void Joystick_::setXAxisRotation(int16_t value) { xAxisRotation = value; + if (autoSendState) sendState(); } void Joystick_::setYAxisRotation(int16_t value) { yAxisRotation = value; + if (autoSendState) sendState(); } void Joystick_::setZAxisRotation(int16_t value) { zAxisRotation = value; + if (autoSendState) sendState(); } void Joystick_::setHatSwitch(int8_t hatSwitchIndex, int16_t value) { hatSwitch[hatSwitchIndex % 2] = value; + if (autoSendState) sendState(); } void Joystick_::sendState() diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 7a6aeda763d..0536595881d 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -189,6 +189,7 @@ extern Keyboard_ Keyboard; class Joystick_ { private: + bool autoSendState; int8_t xAxis; int8_t yAxis; int8_t zAxis; @@ -203,7 +204,7 @@ class Joystick_ public: Joystick_(); - void begin(); + void begin(bool initAutoSendState = true); void end(); void setXAxis(int8_t value); From 58579f5046f5d801ada9326e59c98229f88bb859 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Sat, 11 Apr 2015 21:54:09 -0500 Subject: [PATCH 7/9] Minor update to Joystick HID report Made a minor change to the layout of the Joystick HID report to simplify the X, Y, and Z axis values. --- hardware/arduino/avr/cores/arduino/HID.cpp | 27 ++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/hardware/arduino/avr/cores/arduino/HID.cpp index e453ff3e491..c5b1a984d90 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/hardware/arduino/avr/cores/arduino/HID.cpp @@ -179,22 +179,35 @@ const u8 _hidReportDescriptor[] = { 0x81, 0x02, // INPUT (Data,Var,Abs) // X, Y, and Z Axis - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x75, 0x08, // REPORT_SIZE (8) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Pointer) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) 0xA1, 0x00, // COLLECTION (Physical) 0x09, 0x30, // USAGE (x) 0x09, 0x31, // USAGE (y) 0x09, 0x32, // USAGE (z) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + + // X, Y, and Z Axis Rotation + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x01, // USAGE (Pointer) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0xA1, 0x00, // COLLECTION (Physical) 0x09, 0x33, // USAGE (rx) 0x09, 0x34, // USAGE (ry) 0x09, 0x35, // USAGE (rz) - 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION + #endif }; @@ -722,9 +735,9 @@ void Joystick_::sendState() // Pack hat-switch states into a single byte data[6] = (convertedHatSwitch[1] << 4) | (B00001111 & convertedHatSwitch[0]); - data[7] = xAxis + 127; - data[8] = yAxis + 127; - data[9] = zAxis + 127; + data[7] = xAxis; + data[8] = yAxis; + data[9] = zAxis; data[10] = (xAxisRotation % 360) * 0.708; data[11] = (yAxisRotation % 360) * 0.708; From b66e7071c0aac815deeb8aeddff1bfef25ded487 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Wed, 12 Aug 2015 21:15:45 -0500 Subject: [PATCH 8/9] Align with Version 1.6.5 Update to match Version 1.6.5. --- hardware/arduino/avr/cores/arduino/USBAPI.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 0536595881d..b8c4677c28a 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -59,11 +59,16 @@ extern USBDevice_ USBDevice; struct ring_buffer; +#ifndef SERIAL_BUFFER_SIZE #if (RAMEND < 1000) #define SERIAL_BUFFER_SIZE 16 #else #define SERIAL_BUFFER_SIZE 64 #endif +#endif +#if (SERIAL_BUFFER_SIZE>256) +#error Please lower the CDC Buffer size +#endif class Serial_ : public Stream { From f13111b7ab30513704383fee8806f0051c79e5f0 Mon Sep 17 00:00:00 2001 From: Matthew Heironimus Date: Wed, 12 Aug 2015 21:17:08 -0500 Subject: [PATCH 9/9] Revert "Align with Version 1.6.5" This reverts commit b66e7071c0aac815deeb8aeddff1bfef25ded487. --- hardware/arduino/avr/cores/arduino/USBAPI.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index b8c4677c28a..0536595881d 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -59,16 +59,11 @@ extern USBDevice_ USBDevice; struct ring_buffer; -#ifndef SERIAL_BUFFER_SIZE #if (RAMEND < 1000) #define SERIAL_BUFFER_SIZE 16 #else #define SERIAL_BUFFER_SIZE 64 #endif -#endif -#if (SERIAL_BUFFER_SIZE>256) -#error Please lower the CDC Buffer size -#endif class Serial_ : public Stream {