From c4c2f47f61d76e5135127e5beac0ecc59237c337 Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 8 Dec 2014 17:02:18 +0100 Subject: [PATCH] Starting from Zero --- .gitignore | 2 - CDC.cpp | 275 ----- HID.cpp | 405 ------- Readme.md | 330 ----- USBAPI.h | 1078 ----------------- USBCore.cpp | 785 ------------ USBCore.h | 307 ----- USBDesc.h | 90 -- .../AdvancedGamepad/AdvancedGamepad.ino | 53 - .../AdvancedKeyboard/AdvancedKeyboard.ino | 98 -- .../AdvancedRawHID/AdvancedRawHID.ino | 109 -- examples/Basics/Gamepad/Gamepad.ino | 87 -- examples/Basics/Keyboard/Keyboard.ino | 84 -- examples/Basics/Media/Media.ino | 58 - examples/Basics/Mouse/Mouse.ino | 47 - examples/Basics/System/System.ino | 41 - .../HoodLoader1_API_Legacy.ino | 163 --- .../HoodLoader2_NoUSB_Blink.ino | 38 - .../HoodLoader2_PWM_Fade.ino | 39 - .../HoodLoader2_SerialKeyboard.ino | 54 - .../HoodLoader2_USB-Serial.ino | 51 - .../Gamepad_Project/Gamepad_Project.ino | 110 -- examples/Readme.md | 4 - header.jpg | Bin 150263 -> 0 bytes keywords.txt | 201 --- wiring_private.h | 73 -- 26 files changed, 4582 deletions(-) delete mode 100644 .gitignore delete mode 100644 CDC.cpp delete mode 100644 HID.cpp delete mode 100644 Readme.md delete mode 100644 USBAPI.h delete mode 100644 USBCore.cpp delete mode 100644 USBCore.h delete mode 100644 USBDesc.h delete mode 100644 examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino delete mode 100644 examples/Advanced/AdvancedKeyboard/AdvancedKeyboard.ino delete mode 100644 examples/Advanced/AdvancedRawHID/AdvancedRawHID.ino delete mode 100644 examples/Basics/Gamepad/Gamepad.ino delete mode 100644 examples/Basics/Keyboard/Keyboard.ino delete mode 100644 examples/Basics/Media/Media.ino delete mode 100644 examples/Basics/Mouse/Mouse.ino delete mode 100644 examples/Basics/System/System.ino delete mode 100644 examples/HoodLoader1/HoodLoader1_API_Legacy/HoodLoader1_API_Legacy.ino delete mode 100644 examples/HoodLoader2/HoodLoader2_NoUSB_Blink/HoodLoader2_NoUSB_Blink.ino delete mode 100644 examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino delete mode 100644 examples/HoodLoader2/HoodLoader2_SerialKeyboard/HoodLoader2_SerialKeyboard.ino delete mode 100644 examples/HoodLoader2/HoodLoader2_USB-Serial/HoodLoader2_USB-Serial.ino delete mode 100644 examples/Projects/Gamepad_Project/Gamepad_Project.ino delete mode 100644 examples/Readme.md delete mode 100644 header.jpg delete mode 100644 keywords.txt delete mode 100644 wiring_private.h diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 117ca86..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -dev/* -*.pdn \ No newline at end of file diff --git a/CDC.cpp b/CDC.cpp deleted file mode 100644 index d08ba97..0000000 --- a/CDC.cpp +++ /dev/null @@ -1,275 +0,0 @@ - - -/* Copyright (c) 2011, Peter Barrett -** -** Permission to use, copy, modify, and/or distribute this software for -** any purpose with or without fee is hereby granted, provided that the -** above copyright notice and this permission notice appear in all copies. -** -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -** SOFTWARE. -*/ - -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "USBAPI.h" -#include - -#if defined(USBCON) -#ifdef CDC_ENABLED - -typedef struct -{ - u32 dwDTERate; - u8 bCharFormat; - u8 bParityType; - u8 bDataBits; - u8 lineState; -} LineInfo; - -static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; - -#define WEAK __attribute__ ((weak)) - -extern const CDCDescriptor _cdcInterface PROGMEM; -const CDCDescriptor _cdcInterface = -{ - D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 1), - - // CDC communication interface - D_INTERFACE(CDC_ACM_INTERFACE, 1, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0), - D_CDCCS(CDC_HEADER, 0x10, 0x01), // Header (1.10 bcd) - D_CDCCS(CDC_CALL_MANAGEMENT, 1, 1), // Device handles call management (not) - D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT, 6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported - D_CDCCS(CDC_UNION, CDC_ACM_INTERFACE, CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 - D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_ACM), USB_ENDPOINT_TYPE_INTERRUPT, 0x10, 0x40), - - // CDC data interface - D_INTERFACE(CDC_DATA_INTERFACE, 2, CDC_DATA_INTERFACE_CLASS, 0, 0), - // edit by NicoHood - D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0), - D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_IN), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0) -}; - -int WEAK CDC_GetInterface(u8* interfaceNum) -{ - interfaceNum[0] += 2; // uses 2 - return USB_SendControl(TRANSFER_PGM, &_cdcInterface, sizeof(_cdcInterface)); -} -// edit by NicoHood -// ensure the address isnt used anywhere else by adding a compiler flag in the makefile lf flag -// -Wl,--section-start=.blkey=0x280 -//TODO where to put that flag? use different position: 0x100 maybe? -// someone has to add the compiler flag to fix this bug: https://github.com/arduino/Arduino/issues/2474 -//volatile uint8_t MagicBootKey __attribute__((section(".blkey"))); - -bool WEAK CDC_Setup(Setup& setup) -{ - u8 r = setup.bRequest; - u8 requestType = setup.bmRequestType; - - if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) - { - if (CDC_GET_LINE_CODING == r) - { - USB_SendControl(0, (void*)&_usbLineInfo, 7); - return true; - } - } - - if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) - { - if (CDC_SET_LINE_CODING == r) - { - USB_RecvControl((void*)&_usbLineInfo, 7); - } - - if (CDC_SET_CONTROL_LINE_STATE == r) - { - _usbLineInfo.lineState = setup.wValueL; - } - - if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r) - { - // auto-reset into the bootloader is triggered when the port, already - // open at 1200 bps, is closed. this is the signal to start the watchdog - // with a relatively long period so it can finish housekeeping tasks - // like servicing endpoints before the sketch ends - - // We check DTR state to determine if host port is open (bit 0 of lineState). - if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) - { - // edit by NicoHood - // change ram pointer to fit the 16u2's ram size and only use a 8bit value -#if defined(__AVR_ATmega32U4__) - *(uint16_t *)0x0800 = 0x7777; - wdt_enable(WDTO_120MS); -#else - // workaround for this issue: - // https://github.com/arduino/Arduino/issues/2474 - // I didnt change this for the 32u4 to simply not touch their code - cli(); - - //MagicBootKey = 0x77; - *(uint8_t *)0x0280 = 0x77; - - wdt_enable(WDTO_120MS); - - // wait for reset - for (;;); -#endif - - } - else - { - // Most OSs do some intermediate steps when configuring ports and DTR can - // twiggle more than once before stabilizing. - // To avoid spurious resets we set the watchdog to 250ms and eventually - // cancel if DTR goes back high. - - // edit by NicoHood -#if defined(__AVR_ATmega32U4__) - wdt_disable(); - wdt_reset(); - *(uint16_t *)0x0800 = 0x0; -#else - // not used because of the workaround above - //wdt_disable(); - //wdt_reset(); - //MagicBootKey = 0x0; - //*(uint8_t *)0x0280 = 0x00; -#endif - } - } - return true; - } - return false; -} - - -void Serial_::begin(unsigned long /* baud_count */) -{ - peek_buffer = -1; -} - -void Serial_::begin(unsigned long /* baud_count */, byte /* config */) -{ - peek_buffer = -1; -} - -void Serial_::end(void) -{ -} - -// edit by NicoHood -uint8_t Serial_::lineState(void) -{ - return _usbLineInfo.lineState; -} - -int Serial_::available(void) -{ - if (peek_buffer >= 0) { - return 1 + USB_Available(CDC_RX); - } - return USB_Available(CDC_RX); -} - -int Serial_::peek(void) -{ - if (peek_buffer < 0) - peek_buffer = USB_Recv(CDC_RX); - return peek_buffer; -} - -int Serial_::read(void) -{ - if (peek_buffer >= 0) { - int c = peek_buffer; - peek_buffer = -1; - return c; - } - return USB_Recv(CDC_RX); -} - -void Serial_::flush(void) -{ - USB_Flush(CDC_TX); -} - -size_t Serial_::write(uint8_t c) -{ - return write(&c, 1); -} - -size_t Serial_::write(const uint8_t *buffer, size_t size) -{ - /* only try to send bytes if the high-level CDC connection itself - is open (not just the pipe) - the OS should set lineState when the port - is opened and clear lineState when the port is closed. - bytes sent before the user opens the connection or after - the connection is closed are lost - just like with a UART. */ - - // TODO - ZE - check behavior on different OSes and test what happens if an - // open connection isn't broken cleanly (cable is yanked out, host dies - // or locks up, or host virtual serial port hangs) - if (_usbLineInfo.lineState > 0) { - int r = USB_Send(CDC_TX, buffer, size); - if (r > 0) { - return r; - } - else { - setWriteError(); - return 0; - } - } - setWriteError(); - return 0; -} - -// This operator is a convenient way for a sketch to check whether the -// port has actually been configured and opened by the host (as opposed -// to just being connected to the host). It can be used, for example, in -// setup() before printing to ensure that an application on the host is -// actually ready to receive and display the data. -// We add a short delay before returning to fix a bug observed by Federico -// where the port is configured (lineState != 0) but not quite opened. -Serial_::operator bool() { - bool result = false; - if (_usbLineInfo.lineState > 0) - result = true; - delay(10); - return result; -} - -Serial_ Serial; - -#endif -#endif /* if defined(USBCON) */ diff --git a/HID.cpp b/HID.cpp deleted file mode 100644 index 70f8d60..0000000 --- a/HID.cpp +++ /dev/null @@ -1,405 +0,0 @@ - - -/* Copyright (c) 2011, Peter Barrett -** -** Permission to use, copy, modify, and/or distribute this software for -** any purpose with or without fee is hereby granted, provided that the -** above copyright notice and this permission notice appear in all copies. -** -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -** SOFTWARE. -*/ - -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "USBAPI.h" - -#if defined(USBCON) -#ifdef HID_ENABLED - -//================================================================================ -//================================================================================ -// HID report descriptor - -#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[] = { -#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, HID_REPORTID_MouseReport,// REPORT_ID - // 5 buttons - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x05, // USAGE_MAXIMUM (Button 5) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x05, // REPORT_COUNT (5) - 0x75, 0x01, // REPORT_SIZE (1) - 0x81, 0x02, // INPUT (Data,Var,Abs) - // reserved - 0x95, 0x01, // REPORT_COUNT (1) - 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) - 0x09, 0x38, // USAGE (Wheel) - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7f, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (3) - 0x81, 0x06, // INPUT (Data,Var,Rel) - // end - 0xc0, // END_COLLECTION - 0xc0, // END_COLLECTION -#endif - -#ifdef HID_KEYBOARD_ENABLED - // Keyboard - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x06, // USAGE (Keyboard) - 0xa1, 0x01, // COLLECTION (Application) - 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 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, HID_REPORTID_RawKeyboardReport, // REPORT_ID - 0x75, 0x08, // report size = 8 bits - 0x15, 0x00, // logical minimum = 0 - 0x26, 0xFF, 0x00, // logical maximum = 255 - - 0x95, RAWHID_TX_SIZE, // report count TX - 0x09, 0x01, // usage - 0x81, 0x02, // Input (array) - - 0x95, RAWHID_RX_SIZE, // report count RX - 0x09, 0x02, // usage - 0x91, 0x02, // Output (array) - 0xC0, // end collection -#endif - -#ifdef HID_MEDIA_ENABLED - // Media - 0x05, 0x0C, // usage page (consumer device) - 0x09, 0x01, // usage -- consumer control - 0xA1, 0x01, // collection (application) - 0x85, HID_REPORTID_MediaReport, // report id - //0x05, 0x0C, // usage page (consumer) - - // 4 media Keys - 0x15, 0x00, //logical minimum - 0x26, 0xFF, 0x03, //logical maximum (3ff) - 0x19, 0x00, // usage minimum (0) - 0x2A, 0xFF, 0x03, //usage maximum (3ff) - 0x95, 0x04, //report count (4) - 0x75, 0x10, //report size (16) - - 0x81, 0x00, //input - 0xC0, //end collection -#endif - -#ifdef HID_SYSTEM_ENABLED - // System - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x80, // USAGE (System Control) - 0xa1, 0x01, // COLLECTION (Application) - 0x85, HID_REPORTID_SystemReport, // REPORT_ID - // 1 system key - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x19, 0x00, // USAGE_MINIMUM (Undefined) - 0x29, 0xff, // USAGE_MAXIMUM (System Menu Down) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x08, // REPORT_SIZE (8) - 0x81, 0x00, // INPUT (Data,Ary,Abs) - 0xc0, // END_COLLECTION -#endif - -#ifdef HID_GAMEPAD_ENABLED - // Gamepad - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x04, // USAGE (Joystick) - 0xa1, 0x01, // COLLECTION (Application) - 0x85, HID_REPORTID_GamepadReport, // 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 -}; - -extern const HIDDescriptor _hidInterface PROGMEM; -const HIDDescriptor _hidInterface = -{ - D_INTERFACE(HID_INTERFACE, 1, 3, 0, 0), - D_HIDREPORT(sizeof(_hidReportDescriptor)), - // edit by NicoHood - D_ENDPOINT(USB_ENDPOINT_IN(HID_ENDPOINT_INT), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) -}; - -//================================================================================ -//================================================================================ -// Driver - -u8 _hid_protocol = 1; -u8 _hid_idle = 1; - -#define WEAK __attribute__ ((weak)) - -int WEAK HID_GetInterface(u8* interfaceNum) -{ - interfaceNum[0] += 1; // uses 1 - return USB_SendControl(TRANSFER_PGM, &_hidInterface, sizeof(_hidInterface)); -} - -int WEAK HID_GetDescriptor(int /* i */) -{ - return USB_SendControl(TRANSFER_PGM, _hidReportDescriptor, sizeof(_hidReportDescriptor)); -} - -void WEAK HID_SendReport(u8 id, const void* data, int len) -{ - USB_Send(HID_TX, &id, 1); - USB_Send(HID_TX | TRANSFER_RELEASE, data, len); -} - -bool WEAK HID_Setup(Setup& setup) -{ - u8 r = setup.bRequest; - u8 requestType = setup.bmRequestType; - if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) - { - if (HID_GET_REPORT == r) - { - //HID_GetReport(); - return true; - } - if (HID_GET_PROTOCOL == r) - { - //Send8(_hid_protocol); // TODO - return true; - } - } - - if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) - { - if (HID_SET_PROTOCOL == r) - { - _hid_protocol = setup.wValueL; - return true; - } - - if (HID_SET_IDLE == r) - { - _hid_idle = setup.wValueL; - return true; - } - - // edit by NicoHood -#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED) - if (HID_SET_REPORT == r) - { - if (setup.wLength == 2) - { - uint8_t data[2]; - if (2 == USB_RecvControl(data, 2)) - { - // write led out report data - hid_keyboard_leds=data[1]; - } - } - } -#endif - } - return false; -} - -#endif - -#else if defined(USE_USB_API) - -// still provide the weak HID_SendReport function to be able to overwrite it externaly -void __attribute__((weak)) HID_SendReport(uint8_t id, const void* data, int len) -{ - // the user has to overwrite this if no USB Core is used -} - -#endif /* if defined(USBCON) */ - -// HID API libs are only included if the device has USB functionality or if the USE_USB_API is needed -#if defined(USBCON) || defined(USE_USB_API) - -//================================================================================ -// Mouse -//================================================================================ - -#ifdef HID_MOUSE_ENABLED - -// object instance -Mouse_ Mouse; - -#endif - -//================================================================================ -// Keyboard -//================================================================================ - -#ifdef HID_KEYBOARD_ENABLED - -// object instance -Keyboard_ Keyboard; - -#endif - - -//================================================================================ -// Media -//================================================================================ - -#ifdef HID_MEDIA_ENABLED - -// object instance -Media_ Media; - -#endif - - -//================================================================================ -// System -//================================================================================ - -#ifdef HID_SYSTEAM_ENABLED - -// object instance -System_ System; - -#endif - - -//================================================================================ -// Gamepad -//================================================================================ - -#ifdef HID_GAMEPAD_ENABLED - -// object instance -Gamepad_ Gamepad; - -#endif - -#endif // if defined(USBCON) || defined(USE_USB_API) \ No newline at end of file diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 61daaea..0000000 --- a/Readme.md +++ /dev/null @@ -1,330 +0,0 @@ -Arduino HID Project 2.0 -======================= -![Header Picture](header.jpg) - -This project went through a lot of phases and has now reached an HID library with 3 software solutions. -The idea is to enable enhanced USB functions to almost all 'standard' Arduino boards. -This is done with slightly different methods for different boards. - -**Arduino IDE 1.5.8 is required for the HID Project.** - -**Supported HID devices:** - -* Keyboard with Leds out (modifiers + 6 keys pressed at the same time) -* Mouse (5 buttons, move, wheel) -* Media Keys (4 keys for music player, webbrowser and more) -* System Key (for PC standby/shutdown) -* 1 Gamepad (32 buttons, 4 16bit axis, 2 8bit axis, 2 D-Pads) - -**Supported Arduinos:** -* Uno -* Mega -* Leonardo -* (Pro)Micro -* Any other 8u2/16u/at90usb162/32u2/32u4 compatible board - -| Leonardo/Micro | Uno/Mega HoodLoader2 | Uno/Mega HoodLoader1 | -|:---------------------------|:----------------------------|---------------------------------------| -| Extended Arduino USB-Core | Same Core as Leonardo/Micro | Coded with Lufa | -| More HID devices | Fully reprogrammable 16u2 | No reprogrammable 16u2 | -| Keyboard Led Out report | Serial0 fully usable | Main MCU sends HID reports on Serial0 | -| System Wakeup fix (soon) | | Serial Protocol filters HID reports | -| Serial Control Line access | | Built-in ISP function | - -The HID project contains HID APIs to generate HID reports and functions to send them to the USB Host. -The API (syntax/usage) of the HID Project is always the same for each solution, **you can port code from one device to another very easy**. - -* On a Leonardo this function is extended and improved to get more HID devices + some improvements. -* [HoodLoader2](https://github.com/NicoHood/HoodLoader2) is a BootLoader for the 16u2 that let's you use it as standalone MCU with the same USB-Core. -* [HoodLoader1](https://github.com/NicoHood/HoodLoader) is a 16u2 firmware that filters special HW Serial signals from the main MCU and sends HID signals to the USB Host. - - -To make things more clear the HID Software is in a separate repository than the HoodLoader (1 & 2) sources and installing instructions. -**HoodLoader 1&2 is only used for an Uno/Mega to actually enable USB functions.** The 16u2 is normally used for USB-Serial programming of the main MCU but can do way more than that. -To use HoodLoader1&2 you also need the HID Project. For more information and installation instructions see the specific repository. - -HoodLoader1 was the first solution to enable HID functions to the Uno/Mega but HoodLoader2 opens way more options because you can reprogram the whole MCU standalone. -See the repository for more infos about this great new opportunity. HoodLoader1 API is still usable in a specific example. HoodLoader1&2 are not needed/compatible with a Leonardo/Micro. - -Installation -============ - -**Please remove any older HID Project files from your sketchbook and your Arduino core to not run into any problems.** - -Download the library and [install it](http://arduino.cc/en/pmwiki.php?n=Guide/Libraries) like you are used to (access the examples, keywords.txt with IDE). -Then **move and replace** all .h and .cpp files to the path below. **I strongly recommend to install the library like this. Otherwise it wont work.** - -``` -C:\Arduino\arduino-1.5.8\hardware\arduino\avr\cores\arduino -``` -The installation path may differ to yours. **Please use Arduino IDE 1.5.8** and file an issue if a newer version isn't working. -Restart the IDE. Ensure all drivers are installed. See [this](https://learn.sparkfun.com/tutorials/disabling-driver-signature-on-windows-8/disabling-signed-driver-enforcement-on-windows-8) -on how to install the unsigned HoodLoader2 drivers. - -**If you are using an Arduino Uno/Mega follow the installation instructions of the HoodLoader1 or 2** (no extra hardware needed, just a few cables). -You can grab the latest version + installing instructions of each HoodLoader in its own repository linked above. - -Of course the new version [HoodLoader2](https://github.com/NicoHood/HoodLoader2) is recommend and HoodLoader1 API is only for compatibility reasons online. -The old, full HoodLoader1 HID (software)solution (before update 2.0) can be found here: [Outdated HID Project for 1.5.7](https://github.com/NicoHood/HID/tree/3d8a9b40752a143141b8be4b8f744e203c80b000) - - -How to use -========== - -### Micro/Leonardo + HoodLoader2 - -**Edit the USBAPI.h you installed to de/activate usb functions.** By default only Mouse and Keyboard is activated. -The more you activate the more flash is used. For the Uno/Mega you have a limited ram/flash size, so please try not to exceed this limit and only use the needed HID devices. -RawHID is currently not working properly. - -**Try the Basic examples for each HID device. They are pretty much self explaining.** - -**The HoodLoader2 examples are to show some special cases for the 16u2.** It shows how to remove the USB functions if needed, -how to optimally use ram since its limited and some ported sketches to reprogram the main MCU or for the missing ISP function. Please check them out. - - -### HoodLoader1 - -**Try the HoodLoader1 example. It provides the basic Serial protocol API to send HID reports. You have to copy this to every sketch again.** - -With HoodLoader1 you can **only use baud 115200 for HID** due to speed/programming reasons. -Use Serial.begin(115200) in every HoodLoader1 sketch. -Its not bad anyway because its the fastest baud and you want fast HID recognition. -You still can **fully use any other baud** for normal sketches but HID wont work. -If you try nevertheless it will output Serial crap to the monitor. - -Keep in mind that HoodLoader1 has **no flush function**. If the PC is reading HID too slow it can miss data, like on a Raspberry Pi. -Add a delay to the sending function or just use the newer HoodLoader2. - -Always release buttons to not cause any erros. Replug USB cable to reset the values if anything went wrong. -Keep in mind that **with HoodLoader1 the 16u2 is always on**. The 16u2 and its HID reports are not reset if the main MCU is reset. -So you need to reset the HID reports on every startup with a begin() of each used API. -On Windows every USB report will reset when you open the lock screen. -See [deactivate HID function (Hoodloader only)](https://github.com/NicoHood/Hoodloader) how to temporary disable HID again. - -For **16u2 as ISP usage** (optional, Hoodloader only, has nothing to do with HID function) -see [Hoodloader repository](https://github.com/NicoHood/Hoodloader). - -The sending API is no longer integrated directly in the HID Project since it is now more an extended USB-Core and this has nothing to do with it. -Its more a legacy version to still use HoodLoader1 or to reimplement something similar with HoodLoader2 if you still want full report access for the main MCU. - -**The older, full integrated HID Core can be found here.** Keep in mind to remove all newer stuff since it may conflict (a clean arduino core would do it). -It is not better than this solution, maybe easier to use since its just more integrated. -[Outdated HID Project for 1.5.7](https://github.com/NicoHood/HID/tree/3d8a9b40752a143141b8be4b8f744e203c80b000) - - -How it works -============ -For the Leonardo/Micro + HoodLoader2 its a modified version of the HID descriptors and USB-Core. -This changes were made to improve the functions, add more devices and add u2 series compatibility. - -HoodLoader1 only: -For the Uno/Mega you need a special Bootloader. Why? See [Hoodloader repository](https://github.com/NicoHood/Hoodloader). -To sum it up: Serial information is grabbed by the "man in the middle, 16u2" and you dont have to worry to get any wrong Serial stuff via USB. -Thatswhy you need a special baud (115200) that both sides can communicate with each other. -Every USB command is send via a special [NicoHood Protocol](https://github.com/NicoHood/NicoHoodProtocol) -that's filtered out by the 16u2. If you use Serial0 for extern devices it cannot filter the signal of course. -You can still use the NHP, just dont use the reserved Address 1. - -This project wouldnt be possible without -======================================== - -* [Lufa 140302 from Dean Camera](http://www.fourwalledcubicle.com/LUFA.php) -* [Darran's HID Projects] (https://github.com/harlequin-tech/arduino-usb) -* [Connor's Joystick for the Leonardo](http://www.imaginaryindustries.com/blog/?p=80) -* [Stefan Jones Multimedia Keys Example](http://stefanjones.ca/blog/arduino-leonardo-remote-multimedia-keys/) -* [Athanasios Douitsis Multimedia Keys Example](https://github.com/aduitsis/ardumultimedia) -* [The Original Arduino Sources](https://github.com/arduino/Arduino/tree/master/hardware/arduino/firmwares/atmegaxxu2/arduino-usbserial) -* [USBlyzer](http://www.usblyzer.com/) -* [Mattairtechs 16u2 Lufa USB Core](https://www.mattairtech.com/index.php/development-boards/mt-db-u1.html) -* [Paul Brook's Minimus 32u2 Arduino USB Core](https://github.com/pbrook/minimus-arduino) -* [Paul Stoffregen's Teensy Core](https://github.com/PaulStoffregen/cores) -* [Keyboard Led Out report by hartmut_holgraefe](http://forum.arduino.cc/index.php?topic=173583.0) -* A lot of searching through the web -* The awesome official Arduino IRC chat! -* [The NicoHood Protocol ^.^](https://github.com/NicoHood/NicoHoodProtocol) -* See HoodLoader1&2 repository for more credits/links - -**Projects can be found here:** -* [Gamecube to PC adapter](https://github.com/NicoHood/Nintendo) -* [Other projects](http://nicohood.wordpress.com/) -* For donations please contact me on my blog :) - -Ideas for the future -==================== -* Add more devices (even more?, voice device, flight control?) -* Add Midi (no more free Endpoints, possible on 32u4) -* Add HID rumble support (very hard) - -Known Bugs -========== -See [Hoodloader repository](https://github.com/NicoHood/Hoodloader) for Hoodloader related Bugs/Issues. - -System Wakeup is currently not working on all versions! Will be fixed soon! -System Shutdown is only working on Windows systems. - -RawHID is not working properly, test it at your own risk. - -Feel free to open an Issue on Github if you find a bug. Or message me via my [blog](http://nicohood.wordpress.com/)! - -Known Issues -============ - -**If You have weird Problems especially with controllers, let me know.** -Sometimes the problem is just that Windows messes up the PID so you might want to compile the hoodloader with a different PID -or reinstall the drivers. With HoodLoader1 we had a lot of problems especially with linux. - -XBMC 13.1 (a Media Center) uses Gamepad input. Its seems to not work and may cause weird errors. -Even with a standard Gamepad I have these errors. Just want to mention it here. - -The USB implementation of the Leonardo/Micro is not that good it can cause errors or disconnects with massiv Serial input. -This has nothing to do with this library! For example Adalight dosnt work well for me, -so you better use an Arduino Uno with Hoodloader1 (yes the older one!) for Mediacenter control and Ambilight. - -Do not use HID in interrupts because it uses Serial (Hoodloader1 only). Your Arduino can crash! - -HoodLoader1 only: If you get a checksum error after uploading please message me and send me the whole project. -Same if your Arduino crashes and dont want to upload sketches anymore (Replug usb fixes this). -These bugs occurred while developing the bootloader and should be fixed. Just in case it happens again I noted it here. -USB can behave weird, so please check your code for errors first. If you cannot find a mistake open a Github issue. - -Version History -=============== -``` -2.0 Release (29.11.2014) -* Added HoodLoader2 -* Separated HoodLoader1&2 more -* Added u2 series for USB-Core -* Extended USB core and fixed minor things for the u2 series -* Added Led Out report. -* Added CDC Line state -* Reworked the whole library structure again - -1.8 Beta Release (26.08.2014) -* Changes in the Hoodloader: - * **Huge improvements**, see [Hoodloader repository](https://github.com/NicoHood/Hoodloader) - * Reworked the whole library, easy installation now - * HID fixes for Media Keys/Ubuntu - * Removed Joystick, added 4 Gamepads - -1.7.3 Beta Release (10.08.2014) -* Changes in the Hoodloader: - * Fixed HID flush bug (1.6 - 1.7.2) - -1.7.2 Beta Release (10.08.2014) -* Changes in the Hoodloader: - * Added Lite version for 8u2 - * Added Versions that show up as Uno/Mega (not recommended) - * Makefile and structure changes - -1.7.1 Beta Release (10.08.2014) -* Changes in the Hoodloader: - * Fixed HID deactivation bug - -1.7 Beta Release (10.08.2014) -* Changes in the Hoodloader: - * Works as ISP now. See the [Hoodloader Repository](https://github.com/NicoHood/Hoodloader) for more information. - * Exceeded 8kb limit. For flashing a 8u2 use v1.6 please! -* Changed Readme text - -1.6 Beta Release (09.08.2014) -* Bugfixes in the Hoodloader: - * Changed HID management (not blocking that much, faster) - * added RawHID in/out (HID to Serial) -* Added RawHID Class and example - -1.5 Beta Release (21.07.2014) -* Moved Hoodloader source to a [separate Github page](https://github.com/NicoHood/Hoodloader) -* Bugfixes in the Hoodloader: - * Firmware is still available here - * Overall a lot of ram improvements, now with a big global union of ram - * Removed USBtoUSART buffer (not needed, saved 128/500 bytes) - * Removed Lite version because of better ram usage not needed - * Separated different modes better to not cause any errors in default mode - * Improved the deactivate option - * Integrated NHP directly - * Replaced LightweightRingbuffer with native Lufa Ringbuffer - * Improved writing to CDC Host - * Fixed a bug in checkNHPProtocol: & needs to be a == - * General structure changes - * Improved stability - * Fixed Arduino as ISP bug - -1.4.1 Beta Release (10.07.2014) -* #define Bugfix in USBAPI.h - -1.4 Beta Release (10.07.2014) -* Bugfixes in the Hoodloader: - * Added Lite Version with less ram usage - * Changed PIDs, edited driver file -* merged v1.0.x and v1.5.x together (both are compatible!) -* added IDE v1.5.7 support -* added Tutorials - -1.3 Beta Release (01.07.2014) -* Bugfixes in the Hoodloader: - * Improved ram usage (you can get even better but that messes up code and increases flash) -* **Important NHP fix inside the HID Class for Uno/Mega** - -1.2 Beta Release (22.06.2014) -* Added 1.0.x/1.5.x support -* Bugfixes in the Hoodloader: - * Sometimes HID Devices weren't updating when using more than 1 Device (set forcewrite to true) - * Fast updates crashed the bootloader (too much ram usage, set CDC buffer from 128b to 100b each) -* Minor file structure changes - -1.1 Beta Release (05.06.2014) -* Added Leonardo/Micro support -* Included NicoHoodProtocol -* Minor fixes - -1.0 Beta Release (03.06.2014) -``` - -Licence and Copyright -===================== -If you use this library for any cool project let me know! - -``` -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -``` - -For Developers -============== -If you deactivate some reports it can occur that windows will cause problems and recognize it as different device. -While developing I had that much trouble that I had to change the PID. No way to repair the broken windows driver settings. -So be careful if you change the source on your own with important PIDs. (Therefore I made a 2nd Lite Version with a different PID and more ram) -Therefore reinstall the divers for any device or just dont touch the HID reports in the Bootloader. -The Leonardo/Micro version worked fine till now. - -See this how to uninstall the drivers: -https://support.microsoft.com/kb/315539 - -The Hootloader was coded with Windows7 and Visual Studio and compiled with a Raspberry Pi. -Lufa version 140302 is included! -**To recompile see instructions in [Hoodloader Repository](https://github.com/NicoHood/Hoodloader).** - -The difference between the Leonardo/Micro and Uno/Mega is that the HID Class is different. All other classes are the same. -The Leonardo/Micro Version uses USBAPI.h and no Serial while the Uno/Mega Version uses Serial. -You can also modify the library to send HID reports to other devices/other serials. -Just modify the HID Class (#define HID_SERIAL Serial). - diff --git a/USBAPI.h b/USBAPI.h deleted file mode 100644 index 9cae349..0000000 --- a/USBAPI.h +++ /dev/null @@ -1,1078 +0,0 @@ -/* - USBAPI.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 - */ - -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef __USBAPI__ -#define __USBAPI__ - -#include -#include -#include -#include -#include - -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned long u32; - -#include "Arduino.h" - -#ifdef USBCON -// include needed HID devices -// the more you activate, the more flash it will take -// by default only Mouse + Keyboard are activated -#define HID_MOUSE_ENABLED -#define HID_KEYBOARD_ENABLED -//#define HID_KEYBOARD_LEDS_ENABLED - -//#define HID_RAWHID_ENABLED -//#define HID_MEDIA_ENABLED -//#define HID_SYSTEM_ENABLED -//#define HID_GAMEPAD_ENABLED - -// calculate HID report size for each device - -#ifdef HID_MOUSE_ENABLED -#define HID_MOUSE_SIZE 54 -#else -#define HID_MOUSE_SIZE 0 -#endif - -#ifdef HID_KEYBOARD_ENABLED -#define HID_KEYBOARD_SIZE (65-18) //18 for missing led out report = 47 - -#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED) -// extern accessible led out report -extern uint8_t hid_keyboard_leds; - -#define LED_NUM_LOCK 0x01 -#define LED_CAPS_LOCK 0x02 -#define LED_SCROLL_LOCK 0x04 -#endif -#else -#define HID_KEYBOARD_SIZE 0 -#endif - -#ifdef HID_RAWHID_ENABLED -#define HID_RAWHID_SIZE 30 -#else -#define HID_RAWHID_SIZE 0 -#endif - -#ifdef HID_MEDIA_ENABLED -#define HID_MEDIA_SIZE 25 -#else -#define HID_MEDIA_SIZE 0 -#endif - -#ifdef HID_SYSTEM_ENABLED -#define HID_SYSTEM_SIZE 24 -#else -#define HID_SYSTEM_SIZE 0 -#endif - -#ifdef HID_GAMEPAD_ENABLED -#define HID_GAMEPAD_SIZE 80 -#else -#define HID_GAMEPAD_SIZE 0 -#endif - -// check if usb descriptor isn't too big for USBCore (seems to not work properly then) -#define HID_DESCRIPTOR_SIZE (HID_MOUSE_SIZE + HID_KEYBOARD_SIZE + HID_RAWHID_SIZE + \ -HID_MEDIA_SIZE + HID_SYSTEM_SIZE + HID_GAMEPAD_SIZE + 0) -#if (HID_DESCRIPTOR_SIZE >= 256) -#error Please do not use HID reports >= 256 bytes. Edit USBAPI.h and remove some devices, please. -#endif - -#else // ifdef USBCON - -// still use USE_USB_API sending API to be able to overwrite the HID_SendReport function -#define USE_USB_API - -// activate all API's -// ignore this, this is not the setting for the USB core, its only used for non usb boards to use the APIs -#define HID_MOUSE_ENABLED -#define HID_KEYBOARD_ENABLED -#define HID_RAWHID_ENABLED -#define HID_MEDIA_ENABLED -#define HID_SYSTEM_ENABLED -#define HID_GAMEPAD_ENABLED - -#endif - -/** 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_RawKeyboardReport = 0x03, /**< Report ID for the Raw Keyboard 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; - -// usb core functions -#if defined(USBCON) - -#include "USBDesc.h" -#include "USBCore.h" - -//================================================================================ -//================================================================================ -// USB - -class USBDevice_ -{ -public: - USBDevice_(); - bool configured(); - - void attach(); - void detach(); // Serial port goes down too... - void poll(); -}; -extern USBDevice_ USBDevice; - -//================================================================================ -//================================================================================ -// Serial over CDC (Serial1 is the physical port) - -struct ring_buffer; - -#if (RAMEND < 1000) -#define SERIAL_BUFFER_SIZE 16 -#else -#define SERIAL_BUFFER_SIZE 64 -#endif - -class Serial_ : public Stream -{ -private: - int peek_buffer; -public: - Serial_() { peek_buffer = -1; }; - void begin(unsigned long); - void begin(unsigned long, uint8_t); - void end(void); - - // edit by NicoHood - uint8_t lineState(void); - - virtual int available(void); - virtual int peek(void); - virtual int read(void); - virtual void flush(void); - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t*, size_t); - using Print::write; // pull in write(str) and write(buf, size) from Print - operator bool(); - - volatile uint8_t _rx_buffer_head; - volatile uint8_t _rx_buffer_tail; - unsigned char _rx_buffer[SERIAL_BUFFER_SIZE]; -}; -extern Serial_ Serial; - -#define HAVE_CDCSERIAL - -//================================================================================ -//================================================================================ -// Low level API - -typedef struct -{ - uint8_t bmRequestType; - uint8_t bRequest; - uint8_t wValueL; - uint8_t wValueH; - uint16_t wIndex; - uint16_t wLength; -} Setup; - -//================================================================================ -//================================================================================ -// HID 'Driver' - -int HID_GetInterface(uint8_t* interfaceNum); -int HID_GetDescriptor(int i); -bool HID_Setup(Setup& setup); -void HID_SendReport(uint8_t id, const void* data, int len); - -//================================================================================ -//================================================================================ -// MSC 'Driver' - -int MSC_GetInterface(uint8_t* interfaceNum); -int MSC_GetDescriptor(int i); -bool MSC_Setup(Setup& setup); -bool MSC_Data(uint8_t rx, uint8_t tx); - -//================================================================================ -//================================================================================ -// CSC 'Driver' - -int CDC_GetInterface(uint8_t* interfaceNum); -int CDC_GetDescriptor(int i); -bool CDC_Setup(Setup& setup); - -//================================================================================ -//================================================================================ - -#define TRANSFER_PGM 0x80 -#define TRANSFER_RELEASE 0x40 -#define TRANSFER_ZERO 0x20 - -int USB_SendControl(uint8_t flags, const void* d, int len); -int USB_RecvControl(void* d, int len); - -uint8_t USB_Available(uint8_t ep); -int USB_Send(uint8_t ep, const void* data, int len); // blocking -int USB_Recv(uint8_t ep, void* data, int len); // non-blocking -int USB_Recv(uint8_t ep); // non-blocking -void USB_Flush(uint8_t ep); - - -#else if defined(USE_USB_API) - -// still provide the weak HID_SendReport function to be able to overwrite it externaly -void HID_SendReport(uint8_t id, const void* data, int len); - -#endif /* if defined(USBCON) */ - -// HID API libs are only included if the device has USB functionality or if the USE_USB_API is needed -#if defined(USBCON) || defined(USE_USB_API) - -//================================================================================ -// Mouse -//================================================================================ - -#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) - -typedef union{ - // mouse report: 5 buttons, position, wheel - uint8_t whole8[4]; - uint16_t whole16[4 / 2]; - uint32_t whole32[4 / 4]; - - struct{ - uint8_t buttons : 5; - uint8_t reserved : 3; - int8_t xAxis; - int8_t yAxis; - int8_t wheel; - }; -} HID_MouseReport_Data_t; - -class Mouse_ -{ -public: - inline Mouse_(void) { - // removed this to avoid creating an instance of Mouse if not needed - // the user should call begin first. - //: _buttons(0){ - // empty - } - - inline void begin(void){ - // release all buttons - end(); - } - - inline void end(void){ - _buttons = 0; - move(0, 0, 0); - } - - inline void click(uint8_t b = MOUSE_LEFT){ - _buttons = b; - move(0, 0, 0); - _buttons = 0; - move(0, 0, 0); - } - - inline void move(signed char x, signed char y, signed char wheel = 0){ - u8 m[4]; - m[0] = _buttons; - m[1] = x; - m[2] = y; - m[3] = wheel; - HID_SendReport(1, m, 4); - } - - inline void press(uint8_t b = MOUSE_LEFT){ - // press LEFT by default - buttons(_buttons | b); - } - - inline void release(uint8_t b = MOUSE_LEFT){ - // release LEFT by default - buttons(_buttons & ~b); - } - - inline bool isPressed(uint8_t b = MOUSE_LEFT){ - // check LEFT by default - if ((b & _buttons) > 0) - return true; - return false; - } - -private: - uint8_t _buttons; - inline void buttons(uint8_t b){ - if (b != _buttons) - { - _buttons = b; - move(0, 0, 0); - } - } -}; -extern Mouse_ Mouse; - -#endif - - -//================================================================================ -// Keyboard -//================================================================================ - -#ifdef HID_KEYBOARD_ENABLED - -//Keyboard fixed/added missing Keys -#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 -#define KEY_LEFT_ARROW 0xD8 -#define KEY_RIGHT_ARROW 0xD7 -#define KEY_BACKSPACE 0xB2 -#define KEY_TAB 0xB3 -#define KEY_RETURN 0xB0 -#define KEY_ENTER KEY_RETURN -#define KEY_ESC 0xB1 -#define KEY_INSERT 0xD1 -#define KEY_DELETE 0xD4 -#define KEY_PAGE_UP 0xD3 -#define KEY_PAGE_DOWN 0xD6 -#define KEY_HOME 0xD2 -#define KEY_END 0xD5 -#define KEY_CAPS_LOCK 0xC1 -#define KEY_F1 0xC2 -#define KEY_F2 0xC3 -#define KEY_F3 0xC4 -#define KEY_F4 0xC5 -#define KEY_F5 0xC6 -#define KEY_F6 0xC7 -#define KEY_F7 0xC8 -#define KEY_F8 0xC9 -#define KEY_F9 0xCA -#define KEY_F10 0xCB -#define KEY_F11 0xCC -#define KEY_F12 0xCD - -//Raw Keyboard definitions -#define RAW_KEYBOARD_LEFT_CTRL B00000001 -#define RAW_KEYBOARD_LEFT_SHIFT B00000010 -#define RAW_KEYBOARD_LEFT_ALT B00000100 -#define RAW_KEYBOARD_LEFT_GUI B00001000 -#define RAW_KEYBOARD_RIGHT_CTRL B00010000 -#define RAW_KEYBOARD_RIGHT_SHIFT B00100000 -#define RAW_KEYBOARD_RIGHT_ALT B01000000 -#define RAW_KEYBOARD_RIGHT_GUI B10000000 - -#define RAW_KEYBOARD_KEY(key) ((key>='a' && key<='z') ? (0x04 + key-'a') :\ -(key>='A' && key<='Z') ? (0x04 + key-'A') : (key>='1' && key<='9') ? (0x1E + key-'1') : 0x27) - -#define RAW_KEYBOARD_UP_ARROW 0x52 -#define RAW_KEYBOARD_DOWN_ARROW 0x51 -#define RAW_KEYBOARD_LEFT_ARROW 0x50 -#define RAW_KEYBOARD_RIGHT_ARROW 0x4F -#define RAW_KEYBOARD_SPACEBAR 0x2C -#define RAW_KEYBOARD_BACKSPACE 0x2A -#define RAW_KEYBOARD_TAB 0x2B -#define RAW_KEYBOARD_RETURN 0x28 -#define RAW_KEYBOARD_ESC 0x29 -#define RAW_KEYBOARD_INSERT 0x49 -#define RAW_KEYBOARD_DELETE 0x4C -#define RAW_KEYBOARD_PAGE_UP 0x4B -#define RAW_KEYBOARD_PAGE_DOWN 0x4E -#define RAW_KEYBOARD_HOME 0x4A -#define RAW_KEYBOARD_END 0x4D -#define RAW_KEYBOARD_CAPS_LOCK 0x39 -#define RAW_KEYBOARD_F1 0x3A -#define RAW_KEYBOARD_F2 0x3B -#define RAW_KEYBOARD_F3 0x3C -#define RAW_KEYBOARD_F4 0x3D -#define RAW_KEYBOARD_F5 0x3E -#define RAW_KEYBOARD_F6 0x3F -#define RAW_KEYBOARD_F7 0x40 -#define RAW_KEYBOARD_F8 0x41 -#define RAW_KEYBOARD_F9 0x42 -#define RAW_KEYBOARD_F10 0x43 -#define RAW_KEYBOARD_F11 0x44 -#define RAW_KEYBOARD_F12 0x45 -#define RAW_KEYBOARD_PRINT 0x46 -#define RAW_KEYBOARD_SCROLL_LOCK 0x47 -#define RAW_KEYBOARD_PAUSE 0x48 - -#define SHIFT 0x80 -static const uint8_t _asciimap[128] PROGMEM = -{ - 0x00, // NUL - 0x00, // SOH - 0x00, // STX - 0x00, // ETX - 0x00, // EOT - 0x00, // ENQ - 0x00, // ACK - 0x00, // BEL - 0x2a, // BS Backspace - 0x2b, // TAB Tab - 0x28, // LF Enter - 0x00, // VT - 0x00, // FF - 0x00, // CR - 0x00, // SO - 0x00, // SI - 0x00, // DEL - 0x00, // DC1 - 0x00, // DC2 - 0x00, // DC3 - 0x00, // DC4 - 0x00, // NAK - 0x00, // SYN - 0x00, // ETB - 0x00, // CAN - 0x00, // EM - 0x00, // SUB - 0x00, // ESC - 0x00, // FS - 0x00, // GS - 0x00, // RS - 0x00, // US - - 0x2c, // ' ' - 0x1e | SHIFT, // ! - 0x34 | SHIFT, // " - 0x20 | SHIFT, // # - 0x21 | SHIFT, // $ - 0x22 | SHIFT, // % - 0x24 | SHIFT, // & - 0x34, // ' - 0x26 | SHIFT, // ( - 0x27 | SHIFT, // ) - 0x25 | SHIFT, // * - 0x2e | SHIFT, // + - 0x36, // , - 0x2d, // - - 0x37, // . - 0x38, // / - 0x27, // 0 - 0x1e, // 1 - 0x1f, // 2 - 0x20, // 3 - 0x21, // 4 - 0x22, // 5 - 0x23, // 6 - 0x24, // 7 - 0x25, // 8 - 0x26, // 9 - 0x33 | SHIFT, // : - 0x33, // ; - 0x36 | SHIFT, // < - 0x2e, // = - 0x37 | SHIFT, // > - 0x38 | SHIFT, // ? - 0x1f | SHIFT, // @ - 0x04 | SHIFT, // A - 0x05 | SHIFT, // B - 0x06 | SHIFT, // C - 0x07 | SHIFT, // D - 0x08 | SHIFT, // E - 0x09 | SHIFT, // F - 0x0a | SHIFT, // G - 0x0b | SHIFT, // H - 0x0c | SHIFT, // I - 0x0d | SHIFT, // J - 0x0e | SHIFT, // K - 0x0f | SHIFT, // L - 0x10 | SHIFT, // M - 0x11 | SHIFT, // N - 0x12 | SHIFT, // O - 0x13 | SHIFT, // P - 0x14 | SHIFT, // Q - 0x15 | SHIFT, // R - 0x16 | SHIFT, // S - 0x17 | SHIFT, // T - 0x18 | SHIFT, // U - 0x19 | SHIFT, // V - 0x1a | SHIFT, // W - 0x1b | SHIFT, // X - 0x1c | SHIFT, // Y - 0x1d | SHIFT, // Z - 0x2f, // [ - 0x31, // bslash - 0x30, // ] - 0x23 | SHIFT, // ^ - 0x2d | SHIFT, // _ - 0x35, // ` - 0x04, // a - 0x05, // b - 0x06, // c - 0x07, // d - 0x08, // e - 0x09, // f - 0x0a, // g - 0x0b, // h - 0x0c, // i - 0x0d, // j - 0x0e, // k - 0x0f, // l - 0x10, // m - 0x11, // n - 0x12, // o - 0x13, // p - 0x14, // q - 0x15, // r - 0x16, // s - 0x17, // t - 0x18, // u - 0x19, // v - 0x1a, // w - 0x1b, // x - 0x1c, // y - 0x1d, // z - 0x2f | SHIFT, // - 0x31 | SHIFT, // | - 0x30 | SHIFT, // } - 0x35 | SHIFT, // ~ - 0 // DEL -}; - -typedef union{ - // Low level key report: up to 6 keys and shift, ctrl etc at once - uint8_t whole8[8]; - uint16_t whole16[8 / 2]; - uint32_t whole32[8 / 4]; - - struct{ - uint8_t modifiers; - uint8_t reserved; - uint8_t keys[6]; - }; -} HID_KeyboardReport_Data_t; - -class Keyboard_ : public Print{ -public: - inline Keyboard_(void){ - // empty - } - - inline void begin(void){ - end(); - } - - inline void end(void){ - // edit by NicoHood - releaseAll(); - } - -#if defined(HID_KEYBOARD_LEDS_ENABLED) - inline uint8_t getLEDs(void){ - return hid_keyboard_leds; - } -#endif - - inline size_t write(uint8_t c){ - uint8_t p = press(c); // Keydown - release(c); // Keyup - return (p); // just return the result of press() since release() almost always returns 1 - } - - // press() adds the specified key (printing, non-printing, or modifier) - // to the persistent key report and sends the report. Because of the way - // USB HID works, the host acts like the key remains pressed until we - // call release(), releaseAll(), or otherwise clear the report and resend. - inline size_t press(uint8_t k) - { - uint8_t i; - if (k >= 136) { // it's a non-printing key (not a modifier) - k = k - 136; - } - else if (k >= 128) { // it's a modifier key - _keyReport.modifiers |= (1 << (k - 128)); - k = 0; - } - else { // it's a printing key - k = pgm_read_byte(_asciimap + k); - if (!k) { - setWriteError(); - return 0; - } - if (k & 0x80) { // it's a capital letter or other character reached with shift - _keyReport.modifiers |= 0x02; // the left shift modifier - k &= 0x7F; - } - } - - // Add k to the key report only if it's not already present - // and if there is an empty slot. - if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && - _keyReport.keys[2] != k && _keyReport.keys[3] != k && - _keyReport.keys[4] != k && _keyReport.keys[5] != k) { - - for (i = 0; i < 6; i++) { - if (_keyReport.keys[i] == 0x00) { - _keyReport.keys[i] = k; - break; - } - } - if (i == 6) { - setWriteError(); - return 0; - } - } - sendReport(&_keyReport); - return 1; - } - - // release() takes the specified key out of the persistent key report and - // sends the report. This tells the OS the key is no longer pressed and that - // it shouldn't be repeated any more. - inline size_t release(uint8_t k) - { - uint8_t i; - if (k >= 136) { // it's a non-printing key (not a modifier) - k = k - 136; - } - else if (k >= 128) { // it's a modifier key - _keyReport.modifiers &= ~(1 << (k - 128)); - k = 0; - } - else { // it's a printing key - k = pgm_read_byte(_asciimap + k); - if (!k) { - return 0; - } - if (k & 0x80) { // it's a capital letter or other character reached with shift - _keyReport.modifiers &= ~(0x02); // the left shift modifier - k &= 0x7F; - } - } - - // Test the key report to see if k is present. Clear it if it exists. - // Check all positions in case the key is present more than once (which it shouldn't be) - for (i = 0; i < 6; i++) { - if (0 != k && _keyReport.keys[i] == k) { - _keyReport.keys[i] = 0x00; - } - } - - sendReport(&_keyReport); - return 1; - } - - inline void releaseAll(void){ - // release all keys - memset(&_keyReport, 0x00, sizeof(_keyReport)); - sendReport(&_keyReport); - } - -private: - HID_KeyboardReport_Data_t _keyReport; - inline void sendReport(HID_KeyboardReport_Data_t* keys){ - HID_SendReport(HID_REPORTID_KeyboardReport, &_keyReport, sizeof(_keyReport)); - } -}; -extern Keyboard_ Keyboard; - -#endif - - -//================================================================================ -// RawHID -//================================================================================ - -#ifdef HID_RAWHID_ENABLED - -#define LSB(_x) ((_x) & 0xFF) -#define MSB(_x) ((_x) >> 8) - -//TODO -#define RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF -#define RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF -#define RAWHID_TX_SIZE 64 //TODO 16? -#define RAWHID_RX_SIZE 64 -//#define RAWHID_TX_SIZE 15 // 1 byte for report ID -//#define RAWHID_RX_SIZE 15 // 1 byte for report ID - -typedef union{ - // a RAWHID_TX_SIZE byte buffer for rx or tx - uint8_t whole8[RAWHID_TX_SIZE]; - uint16_t whole16[RAWHID_TX_SIZE / 2]; - uint32_t whole32[RAWHID_TX_SIZE / 4]; - uint8_t buff[RAWHID_TX_SIZE]; -} HID_RawKeyboardReport_Data_t; - -class RawHID_ : public Print{ -public: - inline RawHID_(void){ - // empty - } - - inline void begin(void){ - // empty - } - - inline void end(void){ - // empty - } - - using Print::write; // to get the String version of write - inline size_t write(uint8_t b){ - write(&b, 1); - } - - inline size_t write(const uint8_t *buffer, size_t size){ - size_t bytesleft = size; - // first work through the buffer thats already there - while (bytesleft >= RAWHID_RX_SIZE){ - HID_SendReport(HID_REPORTID_RawKeyboardReport, &buffer[size - bytesleft], RAWHID_RX_SIZE); - bytesleft -= RAWHID_RX_SIZE; - } - // write down the other bytes and fill with zeros - if (bytesleft){ - uint8_t rest[RAWHID_RX_SIZE]; - memcpy(rest, &buffer[size - bytesleft], bytesleft); - memset(&rest[bytesleft], 0, RAWHID_RX_SIZE - bytesleft); - HID_SendReport(HID_REPORTID_RawKeyboardReport, &rest, RAWHID_RX_SIZE); - } - } -}; -extern RawHID_ RawHID; - -#endif - - -//================================================================================ -// Media -//================================================================================ - -#ifdef HID_MEDIA_ENABLED - -// Media key definitions, see official USB docs for more -#define MEDIA_FAST_FORWARD 0xB3 -#define MEDIA_REWIND 0xB4 -#define MEDIA_NEXT 0xB5 -#define MEDIA_PREVIOUS 0xB6 -#define MEDIA_STOP 0xB7 -#define MEDIA_PLAY_PAUSE 0xCD - -#define MEDIA_VOLUME_MUTE 0xE2 -#define MEDIA_VOLUME_UP 0xE9 -#define MEDIA_VOLUME_DOWN 0xEA - -#define MEDIA_EMAIL_READER 0x18A -#define MEDIA_CALCULATOR 0x192 -#define MEDIA_EXPLORER 0x194 - -#define MEDIA_BROWSER_HOME 0x223 -#define MEDIA_BROWSER_BACK 0x224 -#define MEDIA_BROWSER_FORWARD 0x225 -#define MEDIA_BROWSER_REFRESH 0x227 -#define MEDIA_BROWSER_BOOKMARKS 0x22A - -typedef union{ - // every usable media key possible, up to 4 keys presses possible - uint8_t whole8[8]; - uint16_t whole16[8 / 2]; - uint32_t whole32[8 / 4]; - - struct{ - uint16_t key1; - uint16_t key2; - uint16_t key3; - uint16_t key4; - }; -} HID_MediaReport_Data_t; - -class Media_{ -public: - inline Media_(void){ - // empty - } - - inline void begin(void){ - // release all buttons - end(); - } - - inline void end(void){ - memset(&_report, 0, sizeof(_report)); - HID_SendReport(HID_REPORTID_MediaReport, &_report, sizeof(_report)); - } - - inline void write(uint16_t m){ - press(m); - release(m); - } - - inline void press(uint16_t m){ - // search for a free spot - for (int i = 0; i < sizeof(HID_MediaReport_Data_t) / 2; i++) { - if (_report.whole16[i] == 0x00) { - _report.whole16[i] = m; - break; - } - } - HID_SendReport(HID_REPORTID_MediaReport, &_report, sizeof(_report)); - } - - inline void release(uint16_t m){ - // search and release the keypress - for (int i = 0; i < sizeof(HID_MediaReport_Data_t) / 2; i++) { - if (_report.whole16[i] == m) { - _report.whole16[i] = 0x00; - // no break to delete multiple keys - } - } - HID_SendReport(HID_REPORTID_MediaReport, &_report, sizeof(_report)); - } - - inline void releaseAll(void){ - begin(); - } -private: - HID_MediaReport_Data_t _report; -}; -extern Media_ Media; - -#endif - - -//================================================================================ -// System -//================================================================================ - -#ifdef HID_SYSTEM_ENABLED - -#define SYSTEM_POWER_DOWN 0x81 -#define SYSTEM_SLEEP 0x82 -#define SYSTEM_WAKE_UP 0x83 - -typedef union{ - // every usable system control key possible - uint8_t whole8[1]; - uint8_t key; -} HID_SystemReport_Data_t; - -class System_{ -public: - inline System_(void){ - // empty - } - - inline void begin(void){ - // release all buttons - end(); - } - - inline void end(void){ - uint8_t _report = 0; - HID_SendReport(HID_REPORTID_SystemReport, &_report, sizeof(_report)); - } - - inline void write(uint8_t s){ - press(s); - release(); - } - - inline void press(uint8_t s){ - HID_SendReport(HID_REPORTID_SystemReport, &s, sizeof(s)); - } - - inline void release(void){ - begin(); - } - - inline void releaseAll(void){ - begin(); - } -}; -extern System_ System; - -#endif - -//================================================================================ -// Gamepad -//================================================================================ - -#ifdef HID_GAMEPAD_ENABLED - -// 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_GamepadReport, &_report, sizeof(_report)); - } - - inline void write(void){ HID_SendReport(HID_REPORTID_GamepadReport, &_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 - -#endif // if defined(USBCON) || defined(USE_USB_API) - -#endif /* if defined(__USBAPI__) */ diff --git a/USBCore.cpp b/USBCore.cpp deleted file mode 100644 index 7373819..0000000 --- a/USBCore.cpp +++ /dev/null @@ -1,785 +0,0 @@ - - -/* Copyright (c) 2010, Peter Barrett -** -** Permission to use, copy, modify, and/or distribute this software for -** any purpose with or without fee is hereby granted, provided that the -** above copyright notice and this permission notice appear in all copies. -** -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -** SOFTWARE. -*/ - -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "USBAPI.h" - -#if defined(USBCON) - -#define EP_TYPE_CONTROL 0x00 -#define EP_TYPE_BULK_IN 0x81 -#define EP_TYPE_BULK_OUT 0x80 -#define EP_TYPE_INTERRUPT_IN 0xC1 -#define EP_TYPE_INTERRUPT_OUT 0xC0 -#define EP_TYPE_ISOCHRONOUS_IN 0x41 -#define EP_TYPE_ISOCHRONOUS_OUT 0x40 - -/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ -#define TX_RX_LED_PULSE_MS 100 -volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ -volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ - -//================================================================== -//================================================================== - -extern const u16 STRING_LANGUAGE[] PROGMEM; -extern const u8 STRING_PRODUCT[] PROGMEM; -extern const u8 STRING_MANUFACTURER[] PROGMEM; -extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM; -extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM; - -const u16 STRING_LANGUAGE[2] = { - (3 << 8) | (2 + 2), - 0x0409 // English -}; - -#ifndef USB_PRODUCT -// If no product is provided, use USB IO Board -#define USB_PRODUCT "USB IO Board" -#endif - -const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT; - -#if USB_VID == 0x2341 -# if defined(USB_MANUFACTURER) -# undef USB_MANUFACTURER -# endif -# define USB_MANUFACTURER "Arduino LLC" -#elif USB_VID == 0x1b4f -# if defined(USB_MANUFACTURER) -# undef USB_MANUFACTURER -# endif -# define USB_MANUFACTURER "SparkFun" -#elif !defined(USB_MANUFACTURER) -// Fall through to unknown if no manufacturer name was provided in a macro -# define USB_MANUFACTURER "Unknown" -#endif - -const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER; - - -#ifdef CDC_ENABLED -#define DEVICE_CLASS 0x02 -#else -#define DEVICE_CLASS 0x00 -#endif - -// edit by NicoHood -// warning from USBlyzer: IAD is used. Should be EFh (Miscellaneous Device Class). -// Lufa also use these values, so i will use them at least for the u2 boards. Someone should fix this for the u4 series if needed. -// You have to use this descriptor if you have CDC AND HID at the same time. Otherwise they are quite different. -#if defined(HID_ENABLED) && (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)) - -// DEVICE DESCRIPTOR -const DeviceDescriptor USB_DeviceDescriptor = -D_DEVICE(0xEF, 0x02, 0x01, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1); - -#else - -// DEVICE DESCRIPTOR -const DeviceDescriptor USB_DeviceDescriptor = -D_DEVICE(0x00, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1); - -#endif - -const DeviceDescriptor USB_DeviceDescriptorA = -D_DEVICE(DEVICE_CLASS, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1); - -//================================================================== -//================================================================== - -volatile u8 _usbConfiguration = 0; - -static inline void WaitIN(void) -{ - while (!(UEINTX & (1 << TXINI))) - ; -} - -static inline void ClearIN(void) -{ - UEINTX = ~(1 << TXINI); -} - -static inline void WaitOUT(void) -{ - while (!(UEINTX & (1 << RXOUTI))) - ; -} - -static inline u8 WaitForINOrOUT() -{ - while (!(UEINTX & ((1 << TXINI) | (1 << RXOUTI)))) - ; - return (UEINTX & (1 << RXOUTI)) == 0; -} - -static inline void ClearOUT(void) -{ - UEINTX = ~(1 << RXOUTI); -} - -void Recv(volatile u8* data, u8 count) -{ - while (count--) - *data++ = UEDATX; - - RXLED1; // light the RX LED - RxLEDPulse = TX_RX_LED_PULSE_MS; -} - -static inline u8 Recv8() -{ - RXLED1; // light the RX LED - RxLEDPulse = TX_RX_LED_PULSE_MS; - - return UEDATX; -} - -static inline void Send8(u8 d) -{ - UEDATX = d; -} - -static inline void SetEP(u8 ep) -{ - UENUM = ep; -} - -static inline u8 FifoByteCount() -{ - return UEBCLX; -} - -static inline u8 ReceivedSetupInt() -{ - return UEINTX & (1 << RXSTPI); -} - -static inline void ClearSetupInt() -{ - UEINTX = ~((1 << RXSTPI) | (1 << RXOUTI) | (1 << TXINI)); -} - -static inline void Stall() -{ - UECONX = (1 << STALLRQ) | (1 << EPEN); -} - -static inline u8 ReadWriteAllowed() -{ - return UEINTX & (1 << RWAL); -} - -static inline u8 Stalled() -{ - return UEINTX & (1 << STALLEDI); -} - -static inline u8 FifoFree() -{ - return UEINTX & (1 << FIFOCON); -} - -static inline void ReleaseRX() -{ - UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 -} - -static inline void ReleaseTX() -{ - UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 -} - -static inline u8 FrameNumber() -{ - return UDFNUML; -} - -//================================================================== -//================================================================== - -u8 USBGetConfiguration(void) -{ - return _usbConfiguration; -} - -#define USB_RECV_TIMEOUT -class LockEP -{ - u8 _sreg; -public: - LockEP(u8 ep) : _sreg(SREG) - { - cli(); - SetEP(ep & 7); - } - ~LockEP() - { - SREG = _sreg; - } -}; - -// Number of bytes, assumes a rx endpoint -u8 USB_Available(u8 ep) -{ - LockEP lock(ep); - return FifoByteCount(); -} - -// Non Blocking receive -// Return number of bytes read -int USB_Recv(u8 ep, void* d, int len) -{ - if (!_usbConfiguration || len < 0) - return -1; - - LockEP lock(ep); - u8 n = FifoByteCount(); - len = min(n, len); - n = len; - u8* dst = (u8*)d; - while (n--) - *dst++ = Recv8(); - if (len && !FifoByteCount()) // release empty buffer - ReleaseRX(); - - return len; -} - -// Recv 1 byte if ready -int USB_Recv(u8 ep) -{ - u8 c; - if (USB_Recv(ep, &c, 1) != 1) - return -1; - return c; -} - -// Space in send EP -u8 USB_SendSpace(u8 ep) -{ - LockEP lock(ep); - if (!ReadWriteAllowed()) - return 0; - // edit by NicoHood - return USB_EP_SIZE - FifoByteCount(); -} - -// Blocking Send of data to an endpoint -int USB_Send(u8 ep, const void* d, int len) -{ - if (!_usbConfiguration) - return -1; - - int r = len; - const u8* data = (const u8*)d; - u8 timeout = 250; // 250ms timeout on send? TODO - while (len) - { - u8 n = USB_SendSpace(ep); - if (n == 0) - { - if (!(--timeout)) - return -1; - delay(1); - continue; - } - - if (n > len) - n = len; - { - LockEP lock(ep); - // Frame may have been released by the SOF interrupt handler - if (!ReadWriteAllowed()) - continue; - len -= n; - if (ep & TRANSFER_ZERO) - { - while (n--) - Send8(0); - } - else if (ep & TRANSFER_PGM) - { - while (n--) - Send8(pgm_read_byte(data++)); - } - else - { - while (n--) - Send8(*data++); - } - if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer - ReleaseTX(); - } - } - TXLED1; // light the TX LED - TxLEDPulse = TX_RX_LED_PULSE_MS; - return r; -} - -extern const u8 _initEndpoints[] PROGMEM; -const u8 _initEndpoints[] = -{ - 0, - -#ifdef CDC_ENABLED - EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM - EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT - EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN -#endif - -#ifdef HID_ENABLED - EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT -#endif -}; - -#define EP_SINGLE_64 0x32 // EP0 -#define EP_DOUBLE_64 0x36 // Other endpoints -// edit by NicoHood -#define EP_SINGLE_16 0x12 - -static -void InitEP(u8 index, u8 type, u8 size) -{ - UENUM = index; - UECONX = 1; - UECFG0X = type; - UECFG1X = size; -} - -static -void InitEndpoints() -{ - for (u8 i = 1; i < sizeof(_initEndpoints); i++) - { - UENUM = i; - UECONX = 1; - UECFG0X = pgm_read_byte(_initEndpoints + i); - // edit by NicoHood -#if USB_EP_SIZE == 16 - UECFG1X = EP_SINGLE_16; -#elif USB_EP_SIZE == 64 - UECFG1X = EP_DOUBLE_64; -#else -#error Unsupported value for USB_EP_SIZE -#endif - } - UERST = 0x7E; // And reset them - UERST = 0; -} - -// Handle CLASS_INTERFACE requests -static -bool ClassInterfaceRequest(Setup& setup) -{ - u8 i = setup.wIndex; - -#ifdef CDC_ENABLED - if (CDC_ACM_INTERFACE == i) - return CDC_Setup(setup); -#endif - -#ifdef HID_ENABLED - if (HID_INTERFACE == i) - return HID_Setup(setup); -#endif - return false; -} - -int _cmark; -int _cend; -void InitControl(int end) -{ - SetEP(0); - _cmark = 0; - _cend = end; -} - -static -bool SendControl(u8 d) -{ - if (_cmark < _cend) - { - if (!WaitForINOrOUT()) - return false; - Send8(d); - if (!((_cmark + 1) & 0x3F)) - ClearIN(); // Fifo is full, release this packet - } - _cmark++; - return true; -}; - -// Clipped by _cmark/_cend -int USB_SendControl(u8 flags, const void* d, int len) -{ - int sent = len; - const u8* data = (const u8*)d; - bool pgm = flags & TRANSFER_PGM; - while (len--) - { - u8 c = pgm ? pgm_read_byte(data++) : *data++; - if (!SendControl(c)) - return -1; - } - return sent; -} - -// Send a USB descriptor string. The string is stored in PROGMEM as a -// plain ASCII string but is sent out as UTF-16 with the correct 2-byte -// prefix -static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) { - SendControl(2 + string_len * 2); - SendControl(3); - for (u8 i = 0; i < string_len; i++) { - bool r = SendControl(pgm_read_byte(&string_P[i])); - r &= SendControl(0); // high byte - if (!r) { - return false; - } - } - return true; -} - -// Does not timeout or cross fifo boundaries -// Will only work for transfers <= 64 bytes -// TODO -int USB_RecvControl(void* d, int len) -{ - WaitOUT(); - Recv((u8*)d, len); - ClearOUT(); - return len; -} - -int SendInterfaces() -{ - int total = 0; - u8 interfaces = 0; - -#ifdef CDC_ENABLED - total = CDC_GetInterface(&interfaces); -#endif - -#ifdef HID_ENABLED - total += HID_GetInterface(&interfaces); -#endif - - return interfaces; -} - -// Construct a dynamic configuration descriptor -// This really needs dynamic endpoint allocation etc -// TODO -static -bool SendConfiguration(int maxlen) -{ - // Count and measure interfaces - InitControl(0); - int interfaces = SendInterfaces(); - ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor), interfaces); - - // Now send them - InitControl(maxlen); - USB_SendControl(0, &config, sizeof(ConfigDescriptor)); - SendInterfaces(); - return true; -} - -u8 _cdcComposite = 0; - -static -bool SendDescriptor(Setup& setup) -{ - u8 t = setup.wValueH; - if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) - return SendConfiguration(setup.wLength); - - InitControl(setup.wLength); -#ifdef HID_ENABLED - if (HID_REPORT_DESCRIPTOR_TYPE == t) - return HID_GetDescriptor(t); -#endif - - const u8* desc_addr = 0; - if (USB_DEVICE_DESCRIPTOR_TYPE == t) - { - if (setup.wLength == 8) - _cdcComposite = 1; - desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; - } - else if (USB_STRING_DESCRIPTOR_TYPE == t) - { - if (setup.wValueL == 0) { - desc_addr = (const u8*)&STRING_LANGUAGE; - } - else if (setup.wValueL == IPRODUCT) { - return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT)); - } - else if (setup.wValueL == IMANUFACTURER) { - return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER)); - } - else - return false; - } - - if (desc_addr == 0) - return false; - u8 desc_length = pgm_read_byte(desc_addr); - - USB_SendControl(TRANSFER_PGM, desc_addr, desc_length); - return true; -} - -// Endpoint 0 interrupt -ISR(USB_COM_vect) -{ - SetEP(0); - if (!ReceivedSetupInt()) - return; - - Setup setup; - Recv((u8*)&setup, 8); - ClearSetupInt(); - - u8 requestType = setup.bmRequestType; - if (requestType & REQUEST_DEVICETOHOST) - WaitIN(); - else - ClearIN(); - - bool ok = true; - if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) - { - // Standard Requests - u8 r = setup.bRequest; - if (GET_STATUS == r) - { - Send8(0); // TODO - Send8(0); - } - else if (CLEAR_FEATURE == r) - { - } - else if (SET_FEATURE == r) - { - } - else if (SET_ADDRESS == r) - { - WaitIN(); - UDADDR = setup.wValueL | (1 << ADDEN); - } - else if (GET_DESCRIPTOR == r) - { - ok = SendDescriptor(setup); - } - else if (SET_DESCRIPTOR == r) - { - ok = false; - } - else if (GET_CONFIGURATION == r) - { - Send8(1); - } - else if (SET_CONFIGURATION == r) - { - if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT)) - { - InitEndpoints(); - _usbConfiguration = setup.wValueL; - } - else - ok = false; - } - else if (GET_INTERFACE == r) - { - } - else if (SET_INTERFACE == r) - { - } - } - else - { - InitControl(setup.wLength); // Max length of transfer - ok = ClassInterfaceRequest(setup); - } - - if (ok) - ClearIN(); - else - { - Stall(); - } -} - -void USB_Flush(u8 ep) -{ - SetEP(ep); - if (FifoByteCount()) - ReleaseTX(); -} - -// General interrupt -ISR(USB_GEN_vect) -{ - u8 udint = UDINT; - UDINT = 0; - - // End of Reset - if (udint & (1 << EORSTI)) - { - InitEP(0, EP_TYPE_CONTROL, EP_SINGLE_64); // init ep0 - _usbConfiguration = 0; // not configured yet - UEIENX = 1 << RXSTPE; // Enable interrupts for ep0 - } - - // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too - if (udint & (1 << SOFI)) - { -#ifdef CDC_ENABLED - USB_Flush(CDC_TX); // Send a tx frame if found -#endif - - // check whether the one-shot period has elapsed. if so, turn off the LED - if (TxLEDPulse && !(--TxLEDPulse)) - TXLED0; - if (RxLEDPulse && !(--RxLEDPulse)) - RXLED0; - } -} - -// VBUS or counting frames -// Any frame counting? -u8 USBConnected() -{ - u8 f = UDFNUML; - delay(3); - return f != UDFNUML; -} - -//======================================================================= -//======================================================================= - -USBDevice_ USBDevice; - -USBDevice_::USBDevice_() -{ -} - -// edit by NicoHood -// added from teensy definition by paul stoffregen -#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) -#define HW_CONFIG() -#define PLL_CONFIG() (PLLCSR = ((1<> 8) & 0xFF) - -#define CDC_V1_10 0x0110 -#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 - -#define CDC_CALL_MANAGEMENT 0x01 -#define CDC_ABSTRACT_CONTROL_MODEL 0x02 -#define CDC_HEADER 0x00 -#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 -#define CDC_UNION 0x06 -#define CDC_CS_INTERFACE 0x24 -#define CDC_CS_ENDPOINT 0x25 -#define CDC_DATA_INTERFACE_CLASS 0x0A - -#define MSC_SUBCLASS_SCSI 0x06 -#define MSC_PROTOCOL_BULK_ONLY 0x50 - -#define HID_HID_DESCRIPTOR_TYPE 0x21 -#define HID_REPORT_DESCRIPTOR_TYPE 0x22 -#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 - - -// Device -typedef struct { - u8 len; // 18 - u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE - u16 usbVersion; // 0x200 - u8 deviceClass; - u8 deviceSubClass; - u8 deviceProtocol; - u8 packetSize0; // Packet 0 - u16 idVendor; - u16 idProduct; - u16 deviceVersion; // 0x100 - u8 iManufacturer; - u8 iProduct; - u8 iSerialNumber; - u8 bNumConfigurations; -} DeviceDescriptor; - -// Config -typedef struct { - u8 len; // 9 - u8 dtype; // 2 - u16 clen; // total length - u8 numInterfaces; - u8 config; - u8 iconfig; - u8 attributes; - u8 maxPower; -} ConfigDescriptor; - -// String - -// Interface -typedef struct -{ - u8 len; // 9 - u8 dtype; // 4 - u8 number; - u8 alternate; - u8 numEndpoints; - u8 interfaceClass; - u8 interfaceSubClass; - u8 protocol; - u8 iInterface; -} InterfaceDescriptor; - -// Endpoint -typedef struct -{ - u8 len; // 7 - u8 dtype; // 5 - u8 addr; - u8 attr; - u16 packetSize; - u8 interval; -} EndpointDescriptor; - -// Interface Association Descriptor -// Used to bind 2 interfaces together in CDC compostite device -typedef struct -{ - u8 len; // 8 - u8 dtype; // 11 - u8 firstInterface; - u8 interfaceCount; - u8 functionClass; - u8 funtionSubClass; - u8 functionProtocol; - u8 iInterface; -} IADDescriptor; - -// CDC CS interface descriptor -typedef struct -{ - u8 len; // 5 - u8 dtype; // 0x24 - u8 subtype; - u8 d0; - u8 d1; -} CDCCSInterfaceDescriptor; - -typedef struct -{ - u8 len; // 4 - u8 dtype; // 0x24 - u8 subtype; - u8 d0; -} CDCCSInterfaceDescriptor4; - -typedef struct -{ - u8 len; - u8 dtype; // 0x24 - u8 subtype; // 1 - u8 bmCapabilities; - u8 bDataInterface; -} CMFunctionalDescriptor; - -typedef struct -{ - u8 len; - u8 dtype; // 0x24 - u8 subtype; // 1 - u8 bmCapabilities; -} ACMFunctionalDescriptor; - -typedef struct -{ - // IAD - IADDescriptor iad; // Only needed on compound device - - // Control - InterfaceDescriptor cif; // - CDCCSInterfaceDescriptor header; - CMFunctionalDescriptor callManagement; // Call Management - ACMFunctionalDescriptor controlManagement; // ACM - CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION - EndpointDescriptor cifin; - - // Data - InterfaceDescriptor dif; - EndpointDescriptor in; - EndpointDescriptor out; -} CDCDescriptor; - -typedef struct -{ - InterfaceDescriptor msc; - EndpointDescriptor in; - EndpointDescriptor out; -} MSCDescriptor; - -typedef struct -{ - u8 len; // 9 - u8 dtype; // 0x21 - u8 addr; - u8 versionL; // 0x101 - u8 versionH; // 0x101 - u8 country; - u8 desctype; // 0x22 report - u8 descLenL; - u8 descLenH; -} HIDDescDescriptor; - -typedef struct -{ - InterfaceDescriptor hid; - HIDDescDescriptor desc; - EndpointDescriptor in; -} HIDDescriptor; - - -#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ - { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } - -#define D_CONFIG(_totalLength,_interfaces) \ - { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } - -#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ - { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } - -#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ - { 7, 5, _addr,_attr,_packetSize, _interval } - -#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ - { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } - -#define D_HIDREPORT(_descriptorLength) \ - { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } - -#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } -#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } - - -#endif \ No newline at end of file diff --git a/USBDesc.h b/USBDesc.h deleted file mode 100644 index 75f4558..0000000 --- a/USBDesc.h +++ /dev/null @@ -1,90 +0,0 @@ - - -/* Copyright (c) 2011, Peter Barrett -** -** Permission to use, copy, modify, and/or distribute this software for -** any purpose with or without fee is hereby granted, provided that the -** above copyright notice and this permission notice appear in all copies. -** -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -** SOFTWARE. -*/ - -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#define CDC_ENABLED -#define HID_ENABLED - - -#ifdef CDC_ENABLED -#define CDC_INTERFACE_COUNT 2 -#define CDC_ENPOINT_COUNT 3 -#else -#define CDC_INTERFACE_COUNT 0 -#define CDC_ENPOINT_COUNT 0 -#endif - -#ifdef HID_ENABLED -#define HID_INTERFACE_COUNT 1 -#define HID_ENPOINT_COUNT 1 -#else -#define HID_INTERFACE_COUNT 0 -#define HID_ENPOINT_COUNT 0 -#endif - -#define CDC_ACM_INTERFACE 0 // CDC ACM -#define CDC_DATA_INTERFACE 1 // CDC Data -#define CDC_FIRST_ENDPOINT 1 -#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First -#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1) -#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2) - -#define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface -#define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT) -#define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT) - -#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT) - -#ifdef CDC_ENABLED -#define CDC_RX CDC_ENDPOINT_OUT -#define CDC_TX CDC_ENDPOINT_IN -#endif - -#ifdef HID_ENABLED -#define HID_TX HID_ENDPOINT_INT -#endif - -// edit by NicoHood -#ifndef USB_EP_SIZE -#define USB_EP_SIZE 64 -#endif -#define IMANUFACTURER 1 -#define IPRODUCT 2 - diff --git a/examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino b/examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino deleted file mode 100644 index eef660d..0000000 --- a/examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - Advanced Gamepad example - */ - -// include HID library -#include - -// see HID_Reports.h for all data structures -HID_GamepadReport_Data_t Gamepadreport; - -const int pinLed = LED_BUILTIN; -const int pinButton = 2; - -// see HID_Reports.h for all data structures -HID_GamepadReport_Data_t Gamepadreport; - -void setup() { - pinMode(pinLed, OUTPUT); - pinMode(pinButton, INPUT_PULLUP); - - // Sends a clean report to the host. This is important on any Arduino type. - // Make sure all desired USB functions are activated in USBAPI.h! - memset(&Gamepadreport, 0, sizeof(Gamepadreport)); - HID_SendReport(HID_REPORTID_Gamepad1Report, &Gamepadreport, sizeof(Gamepadreport)); -} - -void loop() { - if (!digitalRead(pinButton)) { - digitalWrite(pinLed, HIGH); - - // This demo is actually made for advanced users to show them how they can write an own report. - // This might be useful for a Gamepad if you want to edit the values direct on your own. - - // count with buttons binary - static uint32_t count = 0; - Gamepadreport.whole32[0] = count++; - - // move x/y Axis to a new position (16bit) - Gamepadreport.whole16[2] = (random(0xFFFF)); - - // functions before only set the values - // this writes the report to the host - HID_SendReport(HID_REPORTID_Gamepad1Report, &Gamepadreport, sizeof(Gamepadreport)); - - // simple debounce - delay(300); - digitalWrite(pinLed, LOW); - } -} - diff --git a/examples/Advanced/AdvancedKeyboard/AdvancedKeyboard.ino b/examples/Advanced/AdvancedKeyboard/AdvancedKeyboard.ino deleted file mode 100644 index e6d71cf..0000000 --- a/examples/Advanced/AdvancedKeyboard/AdvancedKeyboard.ino +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - Advanced Keyboard example - - This demo is actually made for advanced users to show them how they can write an own report. - This might be useful for a Keyboard if you only use one key, - because the library has a lot of code for simple use - */ - -const int pinLed = LED_BUILTIN; -const int pinButton = 2; - -void setup() { - pinMode(pinLed, OUTPUT); - pinMode(pinButton, INPUT_PULLUP); - - // Sends a clean report to the host. This is important on any Arduino type. - // Make sure all desired USB functions are activated in USBAPI.h! - pressRawKeyboard(0, 0); -} - -void loop() { - if (!digitalRead(pinButton)) { - digitalWrite(pinLed, HIGH); - - // press normal keys (a-z, A-Z, 0-9) - pressRawKeyboard(0, RAW_KEYBOARD_KEY('a')); //modifiers + a - pressRawKeyboard(0, RAW_KEYBOARD_KEY('Z')); //modifiers + Z - - // press STRG + ALT + DEL on keyboard (see usb documentation for more) - //pressRawKeyboard(RAW_KEYBOARD_LEFT_CTRL | RAW_KEYBOARD_LEFT_ALT , RAW_KEYBOARD_DELETE); //modifiers + key - - // release! Important - pressRawKeyboard(0, 0); - - // simple debounce - delay(300); - digitalWrite(pinLed, LOW); - } -} - -void pressRawKeyboard(uint8_t modifiers, uint8_t key) { - uint8_t keys[8] = { - modifiers, 0, key, 0, 0, 0, 0, 0 - }; //modifiers, reserved, key[0] - HID_SendReport(HID_REPORTID_KeyboardReport, keys, sizeof(keys)); -} - -/* -See Hut1_12v2.pdf Chapter 10 (Page 53) for more Keys - (especially a-z, a=0x04 z=29) - Definitions: - - RAW_KEYBOARD_LEFT_CTRL - RAW_KEYBOARD_LEFT_SHIFT - RAW_KEYBOARD_LEFT_ALT - RAW_KEYBOARD_LEFT_GUI - RAW_KEYBOARD_RIGHT_CTRL - RAW_KEYBOARD_RIGHT_SHIFT - RAW_KEYBOARD_RIGHT_ALT - RAW_KEYBOARD_RIGHT_GUI - - RAW_KEYBOARD_KEY(key) - - RAW_KEYBOARD_UP_ARROW - RAW_KEYBOARD_DOWN_ARROW - RAW_KEYBOARD_LEFT_ARROW - RAW_KEYBOARD_RIGHT_ARROW - RAW_KEYBOARD_SPACEBAR - RAW_KEYBOARD_BACKSPACE - RAW_KEYBOARD_TAB - RAW_KEYBOARD_RETURN - RAW_KEYBOARD_ESC - RAW_KEYBOARD_INSERT - RAW_KEYBOARD_DELETE - RAW_KEYBOARD_PAGE_UP - RAW_KEYBOARD_PAGE_DOWN - RAW_KEYBOARD_HOME - RAW_KEYBOARD_END - RAW_KEYBOARD_CAPS_LOCK - RAW_KEYBOARD_F1 - RAW_KEYBOARD_F2 - RAW_KEYBOARD_F3 - RAW_KEYBOARD_F4 - RAW_KEYBOARD_F5 - RAW_KEYBOARD_F6 - RAW_KEYBOARD_F7 - RAW_KEYBOARD_F8 - RAW_KEYBOARD_F9 - RAW_KEYBOARD_F10 - RAW_KEYBOARD_F11 - RAW_KEYBOARD_F12 - RAW_KEYBOARD_PRINT - RAW_KEYBOARD_SCROLL_LOCK - RAW_KEYBOARD_PAUSE - */ \ No newline at end of file diff --git a/examples/Advanced/AdvancedRawHID/AdvancedRawHID.ino b/examples/Advanced/AdvancedRawHID/AdvancedRawHID.ino deleted file mode 100644 index 202e3b2..0000000 --- a/examples/Advanced/AdvancedRawHID/AdvancedRawHID.ino +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - Advanced RawHID example - - Shows how to send bytes via raw HID - Press a button to send some example values. - Keep in mind that you can only send full data packets, the rest is filled with zero! - - Definitions from HID_Reports.h: - RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF - RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF - RAWHID_TX_SIZE 15 // 1 byte for report ID - RAWHID_RX_SIZE 15 // 1 byte for report ID - */ - -const int pinLed = LED_BUILTIN; -const int pinButton = 2; - -void setup() { - pinMode(pinLed, OUTPUT); - pinMode(pinButton, INPUT_PULLUP); - - // no begin function needed for RawHID - // Make sure all desired USB functions are activated in USBAPI.h! -} - -void loop() { - if (!digitalRead(pinButton)) { - digitalWrite(pinLed, HIGH); - - // direct without library. Always send RAWHID_RX_SIZE bytes! - uint8_t buff[RAWHID_RX_SIZE]; // unitialized, has random values - HID_SendReport(HID_REPORTID_RawKeyboardReport, buff, sizeof(buff)); - - // with library - memset(&buff, 42, sizeof(buff)); - RawHID.write(buff, sizeof(buff)); - - // write a single byte, will fill the rest with zeros - RawHID.write(0xCD); - - // huge buffer with library, will fill the rest with zeros - uint8_t megabuff[64]; - for (int i = 0; i < sizeof(megabuff); i++) - megabuff[i] = i; - RawHID.write(megabuff, sizeof(megabuff)); - - // You can use print too, but better dont use a linefeed - RawHID.println("Hello World"); - - // And compare it to write: - RawHID.write("Hello World\r\n"); - - // simple debounce - delay(300); - digitalWrite(pinLed, LOW); - } -} - -/* -Expected output: - -// manual with unintialized buff -recv 15 bytes: -01 55 C1 FF 01 01 01 00 00 01 00 00 01 00 20 - -// filled buff -recv 15 bytes: -2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A - -// single byte filled with zero -recv 15 bytes: -CD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -// huge buffer filled with zero at the end -recv 15 bytes: -00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E - -recv 15 bytes: -0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D - -recv 15 bytes: -1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C - -recv 15 bytes: -2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B - -recv 15 bytes: -3C 3D 3E 3F 00 00 00 00 00 00 00 00 00 00 00 - -// print -recv 15 bytes: -48 65 6C 6C 6F 20 57 6F 72 6C 64 00 00 00 00 - -//\r -recv 15 bytes: -0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -//\n -recv 15 bytes: -0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -//write -recv 15 bytes: -48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A 00 00 - -*/ \ No newline at end of file diff --git a/examples/Basics/Gamepad/Gamepad.ino b/examples/Basics/Gamepad/Gamepad.ino deleted file mode 100644 index 9014e36..0000000 --- a/examples/Basics/Gamepad/Gamepad.ino +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Gamepad example - -Press a button and demonstrate Gamepad actions -*/ - -const int pinLed = LED_BUILTIN; -const int pinButton = 2; - -void setup() { - pinMode(pinLed, OUTPUT); - pinMode(pinButton, INPUT_PULLUP); - - // Sends a clean report to the host. This is important on any Arduino type. - // Make sure all desired USB functions are activated in USBAPI.h! - Gamepad.begin(); -} - -void loop() { - if (!digitalRead(pinButton)) { - digitalWrite(pinLed, HIGH); - - // press button 1-32 and reset (34 becaue its written later) - static uint8_t count = 1; - Gamepad.press(count++); - if (count == 34) { - Gamepad.releaseAll(); - count = 1; - } - - // move x/y Axis to a new position (16bit) - Gamepad.xAxis(random(0xFFFF)); - Gamepad.yAxis(random(0xFFFF)); - - // go through all dPad positions - // values: 0-8 (0==centred) - static uint8_t dpad1 = GAMEPAD_DPAD_CENTERED; - Gamepad.dPad1(dpad1++); - if(dpad1>GAMEPAD_DPAD_UP_LEFT) dpad1 = GAMEPAD_DPAD_CENTERED; - static int8_t dpad2 = GAMEPAD_DPAD_CENTERED; - Gamepad.dPad2(dpad2--); - if(dpad2 2) { - uint8_t nextvalue = (data >> (7 * (blocks - 3))); - - if (nextvalue > NHP_MASK_DATA_3BIT) { - // special case for the MSB - if (blocks == 7) { - writebuffer[0] = nextvalue; - blocks--; - } - // this block is too big, write this into the next data block - break; - } - else { - // write the possible first 3 bits and check again after if zero - writebuffer[0] = nextvalue; - blocks--; - // we have our first bits, stop (nonzero) - if (nextvalue) - break; - } - } - - // write the rest of the data bits - uint8_t datablocks = blocks - 2; - while (datablocks > 0) { - writebuffer[datablocks] = data & NHP_MASK_DATA_7BIT; - data >>= 7; - datablocks--; - } - - // write lead + length mask - writebuffer[0] |= NHP_MASK_LEAD | (blocks << 3); - - // write end mask - writebuffer[blocks - 1] = NHP_MASK_END | ((address - 1) & NHP_MASK_ADDRESS); - - // write the buffer - HID_SERIAL.write(writebuffer, blocks); -} diff --git a/examples/HoodLoader2/HoodLoader2_NoUSB_Blink/HoodLoader2_NoUSB_Blink.ino b/examples/HoodLoader2/HoodLoader2_NoUSB_Blink/HoodLoader2_NoUSB_Blink.ino deleted file mode 100644 index 4f5fb1a..0000000 --- a/examples/HoodLoader2/HoodLoader2_NoUSB_Blink/HoodLoader2_NoUSB_Blink.ino +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - HoodLoader2 NoUSB Blink example - - This sketch demonstrates how to use HoodLoader2 without USB Core. - This might be useful to keep ram/flash usage at a very low level. - Select Tools->USB Core->No USB functions to get rid of the USB Core. - - Blinks Leds and shows what workaround is needed to get the timing correct. - You can still use the normal digitalWrite(LED_BUILTIN_TX, LOW); for updating Leds. - Keep in mind that the logic is inverted then! LOW=HIGH and vice versa. - */ - -#ifndef USBCON -// workaround for undefined USBCON has to be placed in every sketch -// otherwise the timings wont work correctly -ISR(USB_GEN_vect) -{ - UDINT = 0; -} -#endif - -void setup() { - TX_RX_LED_INIT; -} - -void loop() { - TXLED0; - delay(100); - TXLED1; - delay(100); - RXLED0; - delay(100); - RXLED1; - delay(100); -} diff --git a/examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino b/examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino deleted file mode 100644 index 0ba22c8..0000000 --- a/examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - PWM Fade - - This example shows how to fade an LED on pin 7 - using the analogWrite() function. - - Basically it is a demonstartion that PWM on pin 7 works fine. - You can also deactivate the USB Core for this example, but then you'd - need the workaround. See the other example for this. -*/ - -int led = 7; // the pin that the LED is attached to -int brightness = 0; // how bright the LED is -int fadeAmount = 5; // how many points to fade the LED by - -// the setup routine runs once when you press reset: -void setup() { - // declare pin 9 to be an output: - pinMode(led, OUTPUT); -} - -// the loop routine runs over and over again forever: -void loop() { - // set the brightness of pin 9: - analogWrite(led, brightness); - - // change the brightness for next time through the loop: - brightness = brightness + fadeAmount; - - // reverse the direction of the fading at the ends of the fade: - if (brightness == 0 || brightness == 255) { - fadeAmount = -fadeAmount ; - } - // wait for 30 milliseconds to see the dimming effect - delay(30); -} diff --git a/examples/HoodLoader2/HoodLoader2_SerialKeyboard/HoodLoader2_SerialKeyboard.ino b/examples/HoodLoader2/HoodLoader2_SerialKeyboard/HoodLoader2_SerialKeyboard.ino deleted file mode 100644 index 5aef446..0000000 --- a/examples/HoodLoader2/HoodLoader2_SerialKeyboard/HoodLoader2_SerialKeyboard.ino +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - HoodLoader2 SerialKeyboard example - - This sketch should demonstrate how to program a basic sketch with HoodLoader2. - It was used to demonstrate that Serial and HID is working properly. - The the other examples on how to use the other APIs, it works the same. - - Use the F() macro to save strings in PROGMEM to keep ram usage low. - The 16u2 has very low RAM, so don't try to use that much ram. - - Open the Serial port, type in anything and see that Serial and Keyboard is working. - See official documentation for more infos. - */ - -void setup() { - // start + wait for serial debug in/output - while (!Serial); - Serial.begin(115200); - Serial.println(F("Startup")); - - // Sends a clean report to the host. This is important because - // the 16u2 of the Uno/Mega is not turned off while programming - // so you want to start with a clean report to avoid strange bugs after reset. - Keyboard.begin(); -} - - -void loop() { - if (Serial.available()) { - // discard all Serial bytes to avoid multiple sendings - unsigned long currentMillis = millis(); - while (millis() - currentMillis < 100) { - if (Serial.available()) - Serial.write(Serial.read()); - } - - // print an information back to the serial port - Serial.println(); - Serial.println(F("Serial port working. Printing Text in 3 seconds.")); - - // wait 3 seconds and discard all new in bytes to not crash the Arduino - currentMillis = millis(); - while (millis() - currentMillis < 3000) { - if (Serial.available()) - Serial.write(Serial.read()); - } - - // same use as the official library, pretty much self explaining - Keyboard.print(F("This message was sent with my Arduino.")); - } -} \ No newline at end of file diff --git a/examples/HoodLoader2/HoodLoader2_USB-Serial/HoodLoader2_USB-Serial.ino b/examples/HoodLoader2/HoodLoader2_USB-Serial/HoodLoader2_USB-Serial.ino deleted file mode 100644 index 1dce7ff..0000000 --- a/examples/HoodLoader2/HoodLoader2_USB-Serial/HoodLoader2_USB-Serial.ino +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - HoodLoader2 USB-Serial - - Transferes from USB to HW Serial and vice versa. - It also resets the main MCU on a DTR rise. - */ - -void setup() { - // set main MCU by default active - pinMode(MAIN_MCU_RESET_PIN, OUTPUT); - digitalWrite(MAIN_MCU_RESET_PIN, HIGH); - - // Start USB and HW Serial - Serial.begin(115200); - Serial1.begin(115200); -} - -void loop() { - // USB -> Serial - for (int i = 0; i < USB_EP_SIZE; i++) { - // read maximum one EP_SIZE to not block - if (Serial.available()) - Serial1.write(Serial.read()); - else break; - } - - // Serial -> USB - if (Serial1.available()) { - Serial.flush(); - // send maximum one EP_SIZE to give the usb some time to flush the buffer - uint8_t buff[USB_EP_SIZE-1]; - int i = 0; - for (i = 0; i < USB_EP_SIZE-1; i++) { - if (Serial1.available()) - buff[i] = Serial1.read(); - else break; - } - Serial.write(buff, i); - } - - // reset the main mcu if DTR goes HIGH - static bool lastDTR = 0; - bool newDTR = (Serial.lineState()&CDC_CONTROL_LINE_OUT_DTR) ? 1 : 0; - if (lastDTR ^ newDTR) - digitalWrite(MAIN_MCU_RESET_PIN, lastDTR); - lastDTR = newDTR; -} - diff --git a/examples/Projects/Gamepad_Project/Gamepad_Project.ino b/examples/Projects/Gamepad_Project/Gamepad_Project.ino deleted file mode 100644 index f4d17a0..0000000 --- a/examples/Projects/Gamepad_Project/Gamepad_Project.ino +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -Gamepad example project - -Press physical buttons to press USB Gamepad buttons. -This can be used for a simple SNES Controller. -*/ - -// pin mappings -const int pinButton1 = 2; -const int pinButton2 = 3; -const int pinButton3 = 4; -const int pinButton4 = 5; -const int pinButton5 = 6; -const int pinButton6 = 7; -const int pinButton7 = 8; -const int pinButton8 = 9; -const int pinButton9 = 10; -const int pinButton10 = 18; -const int pinButton11 = 19; -const int pinButton12 = 20; - -void setup() { - // pinsetup - pinMode(pinButton1, INPUT_PULLUP); - pinMode(pinButton2, INPUT_PULLUP); - pinMode(pinButton3, INPUT_PULLUP); - pinMode(pinButton4, INPUT_PULLUP); - pinMode(pinButton5, INPUT_PULLUP); - pinMode(pinButton6, INPUT_PULLUP); - pinMode(pinButton7, INPUT_PULLUP); - pinMode(pinButton8, INPUT_PULLUP); - pinMode(pinButton9, INPUT_PULLUP); - pinMode(pinButton10, INPUT_PULLUP); - pinMode(pinButton11, INPUT_PULLUP); - pinMode(pinButton12, INPUT_PULLUP); - - // Sends a clean report to the host. This is important on any Arduino type. - // Make sure all desired USB functions are activated in USBAPI.h! - Gamepad.begin(); -} - -void loop() { - // check each button and press Gamepad if needed - if (!digitalRead(pinButton1)) - Gamepad.press(1); - else - Gamepad.release(1); - - if (!digitalRead(pinButton2)) - Gamepad.press(2); - else - Gamepad.release(2); - - if (!digitalRead(pinButton3)) - Gamepad.press(3); - else - Gamepad.release(3); - - if (!digitalRead(pinButton4)) - Gamepad.press(4); - else - Gamepad.release(4); - - if (!digitalRead(pinButton5)) - Gamepad.press(5); - else - Gamepad.release(5); - - if (!digitalRead(pinButton6)) - Gamepad.press(6); - else - Gamepad.release(6); - - if (!digitalRead(pinButton7)) - Gamepad.press(7); - else - Gamepad.release(7); - - if (!digitalRead(pinButton8)) - Gamepad.press(8); - else - Gamepad.release(8); - - if (!digitalRead(pinButton9)) - Gamepad.press(9); - else - Gamepad.release(9); - - if (!digitalRead(pinButton10)) - Gamepad.press(10); - else - Gamepad.release(10); - - if (!digitalRead(pinButton11)) - Gamepad.press(11); - else - Gamepad.release(11); - - if (!digitalRead(pinButton12)) - Gamepad.press(12); - else - Gamepad.release(12); - - // write the information to the host now! - Gamepad.write(); -} - diff --git a/examples/Readme.md b/examples/Readme.md deleted file mode 100644 index 30a01d3..0000000 --- a/examples/Readme.md +++ /dev/null @@ -1,4 +0,0 @@ -Examples -======== - -Just try these examples once the HID Source is installed. Its pretty much self explaining. \ No newline at end of file diff --git a/header.jpg b/header.jpg deleted file mode 100644 index d87032a640a9052d4cd80c2b450a8dc27659d8a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150263 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 JJ%|06_&>z+PgDQ^ diff --git a/keywords.txt b/keywords.txt deleted file mode 100644 index ddefd30..0000000 --- a/keywords.txt +++ /dev/null @@ -1,201 +0,0 @@ -####################################### -# Syntax Coloring Map For HID -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -begin KEYWORD2 -end KEYWORD2 -click KEYWORD2 -move KEYWORD2 -write KEYWORD2 -press KEYWORD2 -isPressed KEYWORD2 -releaseAll KEYWORD2 -buttons KEYWORD2 -xAxis KEYWORD2 -yAxis KEYWORD2 -zAxis KEYWORD2 -rxAxis KEYWORD2 -ryAxis KEYWORD2 -rzAxis KEYWORD2 -dPad1 KEYWORD2 -dPad2 KEYWORD2 -HID_SendReport KEYWORD2 - -####################################### -# Classes (KEYWORD3) -####################################### - -Mouse KEYWORD3 -Keyboard KEYWORD3 -RawHID KEYWORD3 -Media KEYWORD3 -System KEYWORD3 -Gamepad KEYWORD3 - -####################################### -# Instances (KEYWORD2) -####################################### - -####################################### -# Constants (LITERAL1) -####################################### - -#CDC -CDC_CONTROL_LINE_OUT_DTR LITERAL1 -CDC_CONTROL_LINE_OUT_TRS LITERAL1 - -#Mouse - -MOUSE_LEFT LITERAL1 -MOUSE_RIGHT LITERAL1 -MOUSE_MIDDLE LITERAL1 -MOUSE_PREV LITERAL1 -MOUSE_NEXT LITERAL1 - -#Keyboard - -LED_NUM_LOCK LITERAL1 -LED_CAPS_LOCK LITERAL1 -LED_SCROLL_LOCK LITERAL1 - -KEY_LEFT_CTRL LITERAL1 -KEY_LEFT_SHIFT LITERAL1 -KEY_LEFT_ALT LITERAL1 -KEY_LEFT_GUI LITERAL1 -KEY_LEFT_WINDOWS LITERAL1 -KEY_RIGHT_CTRL LITERAL1 -KEY_RIGHT_SHIFT LITERAL1 -KEY_RIGHT_ALT LITERAL1 -KEY_RIGHT_GUI LITERAL1 -KEY_RIGHT_WINDOWS LITERAL1 - -KEY_UP_ARROW LITERAL1 -KEY_DOWN_ARROW LITERAL1 -KEY_LEFT_ARROW LITERAL1 -KEY_RIGHT_ARROW LITERAL1 -KEY_BACKSPACE LITERAL1 -KEY_TAB LITERAL1 -KEY_RETURN LITERAL1 -KEY_ENTER LITERAL1 -KEY_ESC LITERAL1 -KEY_INSERT LITERAL1 -KEY_DELETE LITERAL1 -KEY_PAGE_UP LITERAL1 -KEY_PAGE_DOWN LITERAL1 -KEY_HOME LITERAL1 -KEY_END LITERAL1 -KEY_CAPS_LOCK LITERAL1 -KEY_F1 LITERAL1 -KEY_F2 LITERAL1 -KEY_F3 LITERAL1 -KEY_F4 LITERAL1 -KEY_F5 LITERAL1 -KEY_F6 LITERAL1 -KEY_F7 LITERAL1 -KEY_F8 LITERAL1 -KEY_F9 LITERAL1 -KEY_F10 LITERAL1 -KEY_F11 LITERAL1 -KEY_F12 LITERAL1 - -KEY_PRINT LITERAL1 -KEY_NUM_LOCK LITERAL1 -KEY_SCROLL_LOCK LITERAL1 -KEY_PAUSE LITERAL1 - -#Raw Keyboard definitions - -RAW_KEYBOARD_LEFT_CTRL LITERAL1 -RAW_KEYBOARD_LEFT_SHIFT LITERAL1 -RAW_KEYBOARD_LEFT_ALT LITERAL1 -RAW_KEYBOARD_LEFT_GUI LITERAL1 -RAW_KEYBOARD_RIGHT_CTRL LITERAL1 -RAW_KEYBOARD_RIGHT_SHIFT LITERAL1 -RAW_KEYBOARD_RIGHT_ALT LITERAL1 -RAW_KEYBOARD_RIGHT_GUI LITERAL1 - -RAW_KEYBOARD_KEY LITERAL1 - -RAW_KEYBOARD_UP_ARROW LITERAL1 -RAW_KEYBOARD_DOWN_ARROW LITERAL1 -RAW_KEYBOARD_LEFT_ARROW LITERAL1 -RAW_KEYBOARD_RIGHT_ARROW LITERAL1 -RAW_KEYBOARD_SPACEBAR LITERAL1 -RAW_KEYBOARD_BACKSPACE LITERAL1 -RAW_KEYBOARD_TAB LITERAL1 -RAW_KEYBOARD_RETURN LITERAL1 -RAW_KEYBOARD_ESC LITERAL1 -RAW_KEYBOARD_INSERT LITERAL1 -RAW_KEYBOARD_DELETE LITERAL1 -RAW_KEYBOARD_PAGE_UP LITERAL1 -RAW_KEYBOARD_PAGE_DOWN LITERAL1 -RAW_KEYBOARD_HOME LITERAL1 -RAW_KEYBOARD_END LITERAL1 -RAW_KEYBOARD_CAPS_LOCK LITERAL1 -RAW_KEYBOARD_F1 LITERAL1 -RAW_KEYBOARD_F2 LITERAL1 -RAW_KEYBOARD_F3 LITERAL1 -RAW_KEYBOARD_F4 LITERAL1 -RAW_KEYBOARD_F5 LITERAL1 -RAW_KEYBOARD_F6 LITERAL1 -RAW_KEYBOARD_F7 LITERAL1 -RAW_KEYBOARD_F8 LITERAL1 -RAW_KEYBOARD_F9 LITERAL1 -RAW_KEYBOARD_F10 LITERAL1 -RAW_KEYBOARD_F11 LITERAL1 -RAW_KEYBOARD_F12 LITERAL1 -RAW_KEYBOARD_PRINT LITERAL1 -RAW_KEYBOARD_SCROLL_LOCK LITERAL1 -RAW_KEYBOARD_PAUSE LITERAL1 - -#RawHID -RAWHID_RX_SIZE LITERAL1 -RAWHID_TX_SIZE LITERAL1 - -#Media - -MEDIA_FAST_FORWARD LITERAL1 -MEDIA_REWIND LITERAL1 -MEDIA_NEXT LITERAL1 -MEDIA_PREVIOUS LITERAL1 -MEDIA_STOP LITERAL1 -MEDIA_PLAY_PAUSE LITERAL1 - -MEDIA_VOLUME_MUTE LITERAL1 -MEDIA_VOLUME_UP LITERAL1 -MEDIA_VOLUME_DOWN LITERAL1 - -MEDIA_EMAIL_READER LITERAL1 -MEDIA_CALCULATOR LITERAL1 -MEDIA_EXPLORER LITERAL1 - -MEDIA_BROWSER_HOME LITERAL1 -MEDIA_BROWSER_BACK LITERAL1 -MEDIA_BROWSER_FORWARD LITERAL1 -MEDIA_BROWSER_REFRESH LITERAL1 -MEDIA_BROWSER_BOOKMARKS LITERAL1 - -#System - -SYSTEM_POWER_DOWN LITERAL1 -SYSTEM_SLEEP LITERAL1 -SYSTEM_WAKE_UP LITERAL1 - -#Gamepad -GAMEPAD_DPAD_CENTERED LITERAL1 -GAMEPAD_DPAD_UP LITERAL1 -GAMEPAD_DPAD_UP_RIGHT LITERAL1 -GAMEPAD_DPAD_RIGHT LITERAL1 -GAMEPAD_DPAD_DOWN_RIGHT LITERAL1 -GAMEPAD_DPAD_DOWN LITERAL1 -GAMEPAD_DPAD_DOWN_LEFT LITERAL1 -GAMEPAD_DPAD_LEFT LITERAL1 -GAMEPAD_DPAD_UP_LEFT LITERAL1 diff --git a/wiring_private.h b/wiring_private.h deleted file mode 100644 index 4f06421..0000000 --- a/wiring_private.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - wiring_private.h - Internal header file. - Part of Arduino - http://www.arduino.cc/ - - Copyright (c) 2005-2006 David A. Mellis - - 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., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ -*/ - -#ifndef WiringPrivate_h -#define WiringPrivate_h - -#include -#include -#include -#include - -#include "Arduino.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -#ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif -#ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif - -#define EXTERNAL_INT_0 0 -#define EXTERNAL_INT_1 1 -#define EXTERNAL_INT_2 2 -#define EXTERNAL_INT_3 3 -#define EXTERNAL_INT_4 4 -#define EXTERNAL_INT_5 5 -#define EXTERNAL_INT_6 6 -#define EXTERNAL_INT_7 7 - -// edit by NicoHood -#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) \ -|| defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) -#define EXTERNAL_NUM_INTERRUPTS 8 -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) -#define EXTERNAL_NUM_INTERRUPTS 3 -#elif defined(__AVR_ATmega32U4__) -#define EXTERNAL_NUM_INTERRUPTS 5 -#else -#define EXTERNAL_NUM_INTERRUPTS 2 -#endif - -typedef void (*voidFuncPtr)(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif