diff --git a/HID.cpp b/HID.cpp index b578c4b..65d773e 100644 --- a/HID.cpp +++ b/HID.cpp @@ -36,32 +36,40 @@ Keyboard_ Keyboard; #define LSB(_x) ((_x) & 0xFF) #define MSB(_x) ((_x) >> 8) -#define RAWHID_USAGE_PAGE 0xFFC0 -#define RAWHID_USAGE 0x0C00 -#define RAWHID_TX_SIZE 64 -#define RAWHID_RX_SIZE 64 +#define RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF +#define RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF +#define RAWHID_TX_SIZE (USB_EP_SIZE-1) +#define RAWHID_RX_SIZE (USB_EP_SIZE-1) + +#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED) +// extern accessible led out report +uint8_t hid_keyboard_leds = 0; +#endif extern const u8 _hidReportDescriptor[] PROGMEM; const u8 _hidReportDescriptor[] = { - - // Mouse +#ifdef HID_MOUSE_ENABLED + // Mouse 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 0x09, 0x02, // USAGE (Mouse) 0xa1, 0x01, // COLLECTION (Application) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) - 0x85, 0x01, // REPORT_ID (1) + 0x85, HID_REPORTID_MouseReport,// REPORT_ID + // 5 buttons 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x29, 0x05, // USAGE_MAXIMUM (Button 5) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) + 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) + // reserved 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) + 0x75, 0x03, // REPORT_SIZE (3) 0x81, 0x03, // INPUT (Cnst,Var,Abs) + // x, y, wheel 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) @@ -71,58 +79,75 @@ const u8 _hidReportDescriptor[] = { 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x03, // REPORT_COUNT (3) 0x81, 0x06, // INPUT (Data,Var,Rel) + // end 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION +#endif - // Keyboard - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 +#ifdef HID_KEYBOARD_ENABLED + // Keyboard + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) - 0x85, 0x02, // REPORT_ID (2) + 0x85, HID_REPORTID_KeyboardReport, // REPORT_ID 0x05, 0x07, // USAGE_PAGE (Keyboard) - + // modifiers 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) - 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) + // reserved byte 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) - + // Key[6] Array 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) +#ifdef HID_KEYBOARD_LEDS_ENABLED + // LEDs for num lock etc + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + // Reserved 3 bits + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x03, /* REPORT_SIZE (3) */ + 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */ +#endif + // end 0xc0, // END_COLLECTION +#endif -#ifdef RAWHID_ENABLED - // RAW HID +#ifdef HID_RAWHID_ENABLED + // RAW HID 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), - 0xA1, 0x01, // Collection 0x01 - 0x85, 0x03, // REPORT_ID (3) - 0x75, 0x08, // report size = 8 bits - 0x15, 0x00, // logical minimum = 0 - 0x26, 0xFF, 0x00, // logical maximum = 255 + 0xA1, 0x01, // Collection 0x01 + 0x85, HID_REPORTID_RawKeyboardReport, // REPORT_ID + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 - 0x95, 64, // report count TX - 0x09, 0x01, // usage - 0x81, 0x02, // Input (array) + 0x95, RAWHID_TX_SIZE, // report count TX + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) - 0x95, 64, // report count RX - 0x09, 0x02, // usage - 0x91, 0x02, // Output (array) - 0xC0 // end collection + 0x95, RAWHID_RX_SIZE, // report count RX + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0, // end collection #endif }; @@ -192,6 +217,20 @@ bool WEAK HID_Setup(Setup& setup) _hid_idle = setup.wValueL; return true; } + +#if defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED) + if (HID_SET_REPORT == r) + { + //TODO check correct report ID (not needed for now, no other device has an out report) + if (setup.wLength == 2) + { + // write led out report data + uint8_t data[2]; + if (2 == USB_RecvControl(data, 2)) + hid_keyboard_leds = data[1]; + } + } +#endif } return false; } @@ -200,6 +239,8 @@ bool WEAK HID_Setup(Setup& setup) //================================================================================ // Mouse +#ifdef HID_MOUSE_ENABLED + Mouse_::Mouse_(void) : _buttons(0) { } @@ -256,10 +297,14 @@ bool Mouse_::isPressed(uint8_t b) return false; } +#endif + //================================================================================ //================================================================================ // Keyboard +#ifdef HID_KEYBOARD_ENABLED + Keyboard_::Keyboard_(void) { } @@ -520,4 +565,6 @@ size_t Keyboard_::write(uint8_t c) #endif +#endif + #endif /* if defined(USBCON) */ diff --git a/HID_Tests/HID_Tests.ino b/HID_Tests/HID_Tests.ino index cdba2e4..4dcabe2 100644 --- a/HID_Tests/HID_Tests.ino +++ b/HID_Tests/HID_Tests.ino @@ -15,6 +15,11 @@ void loop() { } delay(3000); + Keyboard.write(KEY_CAPS_LOCK); + Serial.println("Leds"); + Serial.println(Keyboard.getLEDs(), BIN); + + Serial.println("Serial"); Serial.println(Serial.dtr()); Serial.println(Serial.rts()); Serial.println(Serial.baud()); diff --git a/USBAPI.h b/USBAPI.h index 049a133..c135e52 100644 --- a/USBAPI.h +++ b/USBAPI.h @@ -34,6 +34,29 @@ typedef unsigned long u32; #if defined(USBCON) +// include needed HID devices +// the more you activate, the more flash it will take +// by default only Mouse + Keyboard (without LEDs) are activated +#define HID_MOUSE_ENABLED +#define HID_KEYBOARD_ENABLED +//#define HID_KEYBOARD_LEDS_ENABLED + +//#define HID_RAWHID_ENABLED (currently broken for USB-Core) +//#define HID_MEDIA_ENABLED +//#define HID_SYSTEM_ENABLED +//#define HID_GAMEPAD_ENABLED + +/** Enum for the HID report IDs used in the device. */ +typedef enum{ + HID_REPORTID_NotAReport = 0x00, /**< first entry is always zero for multireports */ + HID_REPORTID_MouseReport = 0x01, /**< Report ID for the Mouse report within the device. */ + HID_REPORTID_KeyboardReport = 0x02, /**< Report ID for the Keyboard report within the device. */ + HID_REPORTID_RawHidReport = 0x03, /**< Report ID for the Raw Hid report within the device. */ + HID_REPORTID_MediaReport = 0x04, /**< Report ID for the Media report within the device. */ + HID_REPORTID_SystemReport = 0x05, /**< Report ID for the Power report within the device. */ + HID_REPORTID_GamepadReport = 0x06, /**< Report ID for the Gamepad report within the device. */ +} HID_Report_IDs; + #include "USBDesc.h" #include "USBCore.h" @@ -102,10 +125,14 @@ extern Serial_ Serial; //================================================================================ // Mouse -#define MOUSE_LEFT 1 -#define MOUSE_RIGHT 2 -#define MOUSE_MIDDLE 4 -#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) +#ifdef HID_MOUSE_ENABLED + +#define MOUSE_LEFT 0x01 +#define MOUSE_RIGHT 0x02 +#define MOUSE_MIDDLE 0x04 +#define MOUSE_PREV 0x08 +#define MOUSE_NEXT 0x10 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE | MOUSE_PREV | MOUSE_NEXT) class Mouse_ { @@ -124,18 +151,29 @@ public: }; extern Mouse_ Mouse; +#endif + //================================================================================ //================================================================================ // Keyboard +#ifdef HID_KEYBOARD_ENABLED + +#define KEY_PRINT 0xCE +#define KEY_NUM_LOCK 0xDB +#define KEY_SCROLL_LOCK 0xCF +#define KEY_PAUSE 0xD0 + #define KEY_LEFT_CTRL 0x80 #define KEY_LEFT_SHIFT 0x81 #define KEY_LEFT_ALT 0x82 #define KEY_LEFT_GUI 0x83 +#define KEY_LEFT_WINDOWS KEY_LEFT_GUI #define KEY_RIGHT_CTRL 0x84 #define KEY_RIGHT_SHIFT 0x85 #define KEY_RIGHT_ALT 0x86 #define KEY_RIGHT_GUI 0x87 +#define KEY_RIGHT_WINDOWS KEY_RIGHT_GUI #define KEY_UP_ARROW 0xDA #define KEY_DOWN_ARROW 0xD9 @@ -165,6 +203,15 @@ extern Mouse_ Mouse; #define KEY_F11 0xCC #define KEY_F12 0xCD +#define LED_NUM_LOCK 0x01 +#define LED_CAPS_LOCK 0x02 +#define LED_SCROLL_LOCK 0x04 + +#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED) +// extern accessible led out report +extern uint8_t hid_keyboard_leds; +#endif + // Low level key report: up to 6 keys and shift, ctrl etc at once typedef struct { @@ -186,9 +233,15 @@ public: virtual size_t press(uint8_t k); virtual size_t release(uint8_t k); virtual void releaseAll(void); + +#if defined(HID_KEYBOARD_LEDS_ENABLED) + inline uint8_t getLEDs(void){ return hid_keyboard_leds; } +#endif }; extern Keyboard_ Keyboard; +#endif + //================================================================================ //================================================================================ // Low level API