diff --git a/Gamepad.cpp b/Gamepad.cpp new file mode 100644 index 0000000..4cb9fd0 --- /dev/null +++ b/Gamepad.cpp @@ -0,0 +1,27 @@ +/* +Gamepad.cpp +Copyright (c) 2005-2014 Arduino. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Gamepad.h" + +//================================================================================ +// Gamepad +//================================================================================ + +// object instance +Gamepad_ Gamepad; \ No newline at end of file diff --git a/Gamepad.h b/Gamepad.h new file mode 100644 index 0000000..e2d91a3 --- /dev/null +++ b/Gamepad.h @@ -0,0 +1,137 @@ +/* +Gamepad.h +Copyright (c) 2005-2014 Arduino. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __GAMEPADAPI__ +#define __GAMEPADAPI__ + +// to access the HID_SendReport via USBAPI.h and report number +#include "Arduino.h" + +//TODO workaround to access the weak sending function +void HID_SendReport(uint8_t id, const void* data, int len); + +//================================================================================ +// Gamepad +//================================================================================ + +// Dpad directions +#define GAMEPAD_DPAD_CENTERED 0 +#define GAMEPAD_DPAD_UP 1 +#define GAMEPAD_DPAD_UP_RIGHT 2 +#define GAMEPAD_DPAD_RIGHT 3 +#define GAMEPAD_DPAD_DOWN_RIGHT 4 +#define GAMEPAD_DPAD_DOWN 5 +#define GAMEPAD_DPAD_DOWN_LEFT 6 +#define GAMEPAD_DPAD_LEFT 7 +#define GAMEPAD_DPAD_UP_LEFT 8 + +typedef union { + // 32 Buttons, 6 Axis, 2 D-Pads + uint8_t whole8[15]; + uint16_t whole16[15 / 2]; + uint32_t whole32[15 / 4]; + uint32_t buttons; + + struct{ + uint8_t button1 : 1; + uint8_t button2 : 1; + uint8_t button3 : 1; + uint8_t button4 : 1; + uint8_t button5 : 1; + uint8_t button6 : 1; + uint8_t button7 : 1; + uint8_t button8 : 1; + + uint8_t button9 : 1; + uint8_t button10 : 1; + uint8_t button11 : 1; + uint8_t button12 : 1; + uint8_t button13 : 1; + uint8_t button14 : 1; + uint8_t button15 : 1; + uint8_t button16 : 1; + + uint8_t button17 : 1; + uint8_t button18 : 1; + uint8_t button19 : 1; + uint8_t button20 : 1; + uint8_t button21 : 1; + uint8_t button22 : 1; + uint8_t button23 : 1; + uint8_t button24 : 1; + + uint8_t button25 : 1; + uint8_t button26 : 1; + uint8_t button27 : 1; + uint8_t button28 : 1; + uint8_t button29 : 1; + uint8_t button30 : 1; + uint8_t button31 : 1; + uint8_t button32 : 1; + + int16_t xAxis; + int16_t yAxis; + + int16_t rxAxis; + int16_t ryAxis; + + int8_t zAxis; + int8_t rzAxis; + + uint8_t dPad1 : 4; + uint8_t dPad2 : 4; + }; +} HID_GamepadReport_Data_t; + +class Gamepad_{ +public: + inline Gamepad_(void){ + // empty + } + + inline void begin(void){ + // release all buttons + end(); + } + + inline void end(void){ + memset(&_report, 0, sizeof(_report)); + HID_SendReport(HID_REPORTID_GAMEPAD, &_report, sizeof(_report)); + } + + inline void write(void){ HID_SendReport(HID_REPORTID_GAMEPAD, &_report, sizeof(_report)); } + inline void press(uint8_t b){ _report.buttons |= (uint32_t)1 << (b - 1); } + inline void release(uint8_t b){ _report.buttons &= ~((uint32_t)1 << (b - 1)); } + inline void releaseAll(void){ memset(&_report, 0x00, sizeof(_report)); } + + inline void buttons(uint32_t b){ _report.buttons = b; } + inline void xAxis(int16_t a){ _report.xAxis = a; } + inline void yAxis(int16_t a){ _report.yAxis = a; } + inline void zAxis(int8_t a){ _report.zAxis = a; } + inline void rxAxis(int16_t a){ _report.rxAxis = a; } + inline void ryAxis(int16_t a){ _report.ryAxis = a; } + inline void rzAxis(int8_t a){ _report.rzAxis = a; } + inline void dPad1(int8_t d){ _report.dPad1 = d; } + inline void dPad2(int8_t d){ _report.dPad2 = d; } +private: + HID_GamepadReport_Data_t _report; +}; +extern Gamepad_ Gamepad; + +#endif \ No newline at end of file diff --git a/HID.cpp b/HID.cpp index 48e3a0e..082905d 100644 --- a/HID.cpp +++ b/HID.cpp @@ -40,6 +40,9 @@ const u8 _hidReportDescriptor[] = { //HID_REPORT_RAWHID(HID_REPORTID_RAWHID), HID_REPORT_CONSUMERCONTROL(HID_REPORTID_CONSUMERCONTROL), HID_REPORT_SYSTEMCONTROL(HID_REPORTID_SYSTEMCONTROL), + //TODO get Gamepad working with the other devices + //HID_REPORT_GAMEPAD(HID_REPORTID_GAMEPAD), + #else EXTERN_HID_REPORT #endif diff --git a/HID.h b/HID.h index 89dc0f5..74e5dc3 100644 --- a/HID.h +++ b/HID.h @@ -48,10 +48,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define HID_REPORTID_SYSTEMCONTROL 5 #endif #ifndef HID_REPORTID_GAMEPAD -#define HID_REPORTID_GAMEPAD 5 +#define HID_REPORTID_GAMEPAD 6 #endif #ifndef HID_REPORTID_MOUSE_ABSOLUTE -#define HID_REPORTID_MOUSE_ABSOLUTE 6 +#define HID_REPORTID_MOUSE_ABSOLUTE 7 #endif // HID reports @@ -227,6 +227,54 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 0xC0 /* end collection */ #endif +#ifndef HID_REPORT_GAMEPAD +#define HID_REPORT_GAMEPAD(report_id) /* Gamepad with 32 buttons and 6 axis*/ \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ + 0x09, 0x04, /* USAGE (Joystick) */ \ + 0xa1, 0x01, /* COLLECTION (Application) */ \ + 0x85, HID_REPORTID_GAMEPAD, /* REPORT_ID */ \ + /* 32 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) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + /* 4 16bit Axis */ \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ + 0xa1, 0x00, /* COLLECTION (Physical) */ \ + 0x09, 0x30, /* USAGE (X) */ \ + 0x09, 0x31, /* USAGE (Y) */ \ + 0x09, 0x33, /* USAGE (Rx) */ \ + 0x09, 0x34, /* USAGE (Ry) */ \ + 0x16, 0x00, 0x80, /* LOGICAL_MINIMUM (-32768) */ \ + 0x26, 0xFF, 0x7F, /* LOGICAL_MAXIMUM (32767) */ \ + 0x75, 0x10, /* REPORT_SIZE (16) */ \ + 0x95, 0x04, /* REPORT_COUNT (4) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + /* 2 8bit Axis */ \ + 0x09, 0x32, /* USAGE (Z) */ \ + 0x09, 0x35, /* USAGE (Rz) */ \ + 0x15, 0x80, /* LOGICAL_MINIMUM (-128) */ \ + 0x25, 0x7F, /* LOGICAL_MAXIMUM (127) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x95, 0x02, /* REPORT_COUNT (2) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + 0xc0, /* END_COLLECTION */ \ + /* 2 Hat Switches */ \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ + 0x09, 0x39, /* USAGE (Hat switch) */ \ + 0x09, 0x39, /* USAGE (Hat switch) */ \ + 0x15, 0x01, /* LOGICAL_MINIMUM (1) */ \ + 0x25, 0x08, /* LOGICAL_MAXIMUM (8) */ \ + 0x95, 0x02, /* REPORT_COUNT (2) */ \ + 0x75, 0x04, /* REPORT_SIZE (4) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + 0xc0 /* END_COLLECTION */ +#endif + // note by NicoHood: RawHID might never work with multireports, because of OS problems // therefore we have to make it a single report with no idea. No other HID device will be supported then. #define RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF diff --git a/HIDAPI.h b/HIDAPI.h index 0acabaf..8526bc5 100644 --- a/HIDAPI.h +++ b/HIDAPI.h @@ -25,5 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "Mouse.h" #include "Consumer.h" #include "System.h" +#include "Gamepad.h" #endif \ No newline at end of file diff --git a/Readme.md b/Readme.md index f02dab5..abb703c 100644 --- a/Readme.md +++ b/Readme.md @@ -9,19 +9,18 @@ more usb definitions instead of fixed values, noone understands someone has to add the keywords.txt definitions as well keyboard led move to usb function not to keyboard and from keyboard call this function? weak hidsendreport implement somewhere the prototype? -move HID-Core to a seperate folder? usb wakeup keycode/raw for keyboard magic key fix? add examples -void Recv(volatile u8* data, u8 count) static inline?? improve workaround for consumer + system weak hid send function prototype -add gamepad check keycode function again? generalize HID key definitions +separate folder for the usb core? Bugs Mouse Abs only works with system report under special circumstances. +Gamepad + Mouse Abs doesnt work ``` @@ -46,6 +45,7 @@ Mouse Abs only works with system report under special circumstances. * Removed virtual functions in Keyboard API * Added Keycode functions in Keyboard API * Inlined a lot of the HID API functions to save flash +* Added Gamepad ``` ```