From bb008e6daa810de63c4ff3b450f0083c3c29af52 Mon Sep 17 00:00:00 2001 From: Nico Date: Fri, 2 Jan 2015 16:23:27 +0100 Subject: [PATCH] Added Examples --- Readme.md | 3 + .../hid_descriptors/hid_descriptors.h | 33 +++- .../AdvancedGamepad/AdvancedGamepad.ino | 53 ++++++ .../AdvancedKeyboard/AdvancedKeyboard.ino | 98 ++++++++++ .../AdvancedRawHID/AdvancedRawHID.ino | 109 +++++++++++ .../HoodLoader1_API_Legacy.ino | 163 +++++++++++++++++ .../HoodLoader2_PWM_Fade.ino | 39 ++++ .../HoodLoader2_SerialKeyboard.ino | 54 ++++++ .../HoodLoader2_USB-Serial.ino | 51 ++++++ .../Gamepad_Project/Gamepad_Project.ino | 113 ++++++++++++ examples/Readme.md | 4 + examples/hidtests2/hidtests2.ino | 169 ------------------ 12 files changed, 714 insertions(+), 175 deletions(-) create mode 100644 examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino create mode 100644 examples/Advanced/AdvancedKeyboard/AdvancedKeyboard.ino create mode 100644 examples/Advanced/AdvancedRawHID/AdvancedRawHID.ino create mode 100644 examples/HoodLoader1/HoodLoader1_API_Legacy/HoodLoader1_API_Legacy.ino create mode 100644 examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino create mode 100644 examples/HoodLoader2/HoodLoader2_SerialKeyboard/HoodLoader2_SerialKeyboard.ino create mode 100644 examples/HoodLoader2/HoodLoader2_USB-Serial/HoodLoader2_USB-Serial.ino create mode 100644 examples/Projects/Gamepad_Project/Gamepad_Project.ino create mode 100644 examples/Readme.md delete mode 100644 examples/hidtests2/hidtests2.ino diff --git a/Readme.md b/Readme.md index 7dbb0cc..304c28f 100644 --- a/Readme.md +++ b/Readme.md @@ -38,6 +38,9 @@ Mouse Abs only works with system report under special circumstances. Gamepad + Mouse Abs doesnt work (fix Gamepad) Fix HID_SendReport() prototype workaround in HID-APIs Core selection in boards.txt is not working + +Do not name the Arduino Sketch 'Mouse.ino' or 'Keyboard.ino' etc. +Your Arduino IDE will output errors then if you double click the file and try to compile. ``` diff --git a/avr/variants/hid_descriptors/hid_descriptors.h b/avr/variants/hid_descriptors/hid_descriptors.h index 787b865..529adec 100644 --- a/avr/variants/hid_descriptors/hid_descriptors.h +++ b/avr/variants/hid_descriptors/hid_descriptors.h @@ -1,11 +1,28 @@ +/* +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. +*/ + // add your custom HID Report Descriptor here. // you can use the pre defined reports as well -#define EXTERN_HID_REPORT DEFAULT_HID_REPORT - -#define GAMEPAD_HID_REPORT \ -HID_REPORT_KEYBOARD_LEDS(HID_REPORTID_KEYBOARD), \ -HID_REPORT_MOUSE(HID_REPORTID_MOUSE), \ -HID_REPORT_GAMEPAD(HID_REPORTID_GAMEPAD) +//#define EXTERN_HID_REPORT DEFAULT_HID_REPORT +#define EXTERN_HID_REPORT EXTENDED_HID_REPORT +//#define EXTERN_HID_REPORT GAMEPAD_HID_REPORT #define EXTENDED_HID_REPORT \ HID_REPORT_KEYBOARD_LEDS(HID_REPORTID_KEYBOARD), \ @@ -14,6 +31,10 @@ HID_REPORT_MOUSE_ABSOLUTE(HID_REPORTID_MOUSE_ABSOLUTE), \ HID_REPORT_CONSUMERCONTROL(HID_REPORTID_CONSUMERCONTROL), \ HID_REPORT_SYSTEMCONTROL(HID_REPORTID_SYSTEMCONTROL) +#define GAMEPAD_HID_REPORT \ +HID_REPORT_KEYBOARD_LEDS(HID_REPORTID_KEYBOARD), \ +HID_REPORT_MOUSE(HID_REPORTID_MOUSE), \ +HID_REPORT_GAMEPAD(HID_REPORTID_GAMEPAD) // use this to enable the Keyboard Led functions #define HID_KEYBOARD_LEDS_ENABLED diff --git a/examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino b/examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino new file mode 100644 index 0000000..eef660d --- /dev/null +++ b/examples/Advanced/AdvancedGamepad/AdvancedGamepad.ino @@ -0,0 +1,53 @@ +/* + 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 new file mode 100644 index 0000000..e6d71cf --- /dev/null +++ b/examples/Advanced/AdvancedKeyboard/AdvancedKeyboard.ino @@ -0,0 +1,98 @@ +/* + 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 new file mode 100644 index 0000000..202e3b2 --- /dev/null +++ b/examples/Advanced/AdvancedRawHID/AdvancedRawHID.ino @@ -0,0 +1,109 @@ +/* + 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/HoodLoader1/HoodLoader1_API_Legacy/HoodLoader1_API_Legacy.ino b/examples/HoodLoader1/HoodLoader1_API_Legacy/HoodLoader1_API_Legacy.ino new file mode 100644 index 0000000..546a413 --- /dev/null +++ b/examples/HoodLoader1/HoodLoader1_API_Legacy/HoodLoader1_API_Legacy.ino @@ -0,0 +1,163 @@ +/* + Copyright (c) 2014 NicoHood + See the readme for credit to other people. + + Keyboard HoodLoader1 API Legacy example + + Legacy Example on how to access the Serial HID API of HoodLoader1. + This methode is outdated, because you can now control the whole + 16u2 with HoodLoader2. It might be still usefull if you want the 328/2560 + keep control of the USB functions. Keep in mind that there is no such thing + as flushing HID reports. If the USB Host is too slow HID reports might be missed. + + You can also adapt the sending method below to send Mouse/Keyboard/Media/System reports. + Gamepads/RawHID have a general problem with the original HoodLoader1 firmware, so please avoid this. + It might be compatible with the new HoodLoader2 port of the protocol later on. + + HID reports are converted into a special Serial Protocol with NHP. + This sketch should only be used with a 328/2560, not a 16u2. + The 16u2 has a HoodLoader1 compatible sketch/firmware loaded and will + listen to the Serial Port for these Protocol packets on baud 115200. + + The HID_SendReport function is implemented weak, so we can overwrite it + in this sketch below. A simple NHP implementation encapsulated the HID reports + into NHP packets with correct addresses and checksums. + + Press a button to write some text to your pc. + See official documentation for more infos + */ + +// Serial to write Protocol data to. Default: Serial +#define HID_SERIAL Serial +#define SERIAL_HID_BAUD 115200 + +// extra delay for raspberry. Only needed for Hoodloader and slow devices +//#define HID_EXTRADELAY 20 + +const int pinLed = 13; +const int pinButton = 8; + +void setup() { + pinMode(pinLed, OUTPUT); + pinMode(pinButton, INPUT_PULLUP); + + // Starts Serial at baud 115200 otherwise HID wont work with HoodLoader1. + // This is not needed for Leonado/(Pro)Micro/16u2(HoodLoader2) + Serial.begin(SERIAL_HID_BAUD); + + // 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! + Keyboard.begin(); +} + + +void loop() { + if (!digitalRead(pinButton)) { + digitalWrite(pinLed, HIGH); + + // Same use as the official library, pretty much self explaining + Keyboard.println("This message was sent with my Arduino."); + Serial.println("Serial port is still working and not glitching out"); + + // simple debounce + delay(300); + digitalWrite(pinLed, LOW); + } +} + +//================================================================================ +// HoodLoader1 compatible NHP sending API +//================================================================================ + +// Start Mask +#define NHP_MASK_START 0xC0 //B11|000000 the two MSB bits +#define NHP_MASK_LEAD 0xC0 //B11|000000 +#define NHP_MASK_DATA 0x00 //B0|0000000 only the first MSB is important +#define NHP_MASK_END 0x80 //B10|000000 + +// Content Mask +#define NHP_MASK_LENGTH 0x38 //B00|111|000 +#define NHP_MASK_COMMAND 0x0F //B0000|1111 +#define NHP_MASK_DATA_7BIT 0x7F //B0|1111111 +#define NHP_MASK_DATA_4BIT 0x0F //B0000|1111 +#define NHP_MASK_DATA_3BIT 0x07 //B00000|111 +#define NHP_MASK_ADDRESS 0x3F //B00|111111 + +// Reserved Addresses +#define NHP_ADDRESS_CONTROL 0x01 + +// Reserved Usages +#define NHP_USAGE_ARDUINOHID 0x01 + +// overwrites the HID_SendReport function which is empty/not used on a 328/2560 +void HID_SendReport(uint8_t id, const void* data, int len) +{ + // write the Report via Protocol and checksum. 16bit for each sending + // send control address + NHPwriteChecksum(NHP_ADDRESS_CONTROL, (NHP_USAGE_ARDUINOHID << 8) | id); + const uint8_t* report = (const uint8_t*)data; + for (int i = 0; i < len; i++) { + uint8_t data0 = report[i++]; + uint8_t data1 = 0; + if (i != len) + data1 = report[i]; + // valid HID reports start at Address 2 + NHPwriteChecksum(2 + i / 2, (data1 << 8) | data0); + } +#ifdef HID_EXTRADELAY + delay(HID_EXTRADELAY); +#endif +} + +// simple copy/modification of the NicoHoodProtocol writechecksum function +void NHPwriteChecksum(uint8_t address, uint16_t indata) { + // writes two bytes with its inverse + uint32_t temp = ~indata; + uint32_t data = (temp << 16) | indata; + + // buffer for write operation + uint8_t writebuffer[6]; + + // start with the maximum size of blocks + uint8_t blocks = 7; + + // check for the first 7 bit block that doesnt fit into the first 3 bits + while (blocks > 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_PWM_Fade/HoodLoader2_PWM_Fade.ino b/examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino new file mode 100644 index 0000000..0ba22c8 --- /dev/null +++ b/examples/HoodLoader2/HoodLoader2_PWM_Fade/HoodLoader2_PWM_Fade.ino @@ -0,0 +1,39 @@ +/* + 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 new file mode 100644 index 0000000..5aef446 --- /dev/null +++ b/examples/HoodLoader2/HoodLoader2_SerialKeyboard/HoodLoader2_SerialKeyboard.ino @@ -0,0 +1,54 @@ +/* + 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 new file mode 100644 index 0000000..1dce7ff --- /dev/null +++ b/examples/HoodLoader2/HoodLoader2_USB-Serial/HoodLoader2_USB-Serial.ino @@ -0,0 +1,51 @@ +/* + 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 new file mode 100644 index 0000000..e3418d7 --- /dev/null +++ b/examples/Projects/Gamepad_Project/Gamepad_Project.ino @@ -0,0 +1,113 @@ +/* + 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. + + Make sure the Gamepad report is set in: + sketchbook/hardware/HID/avr/variants/hid_descriptors/hid_descriptors.h +*/ + +// 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 new file mode 100644 index 0000000..30a01d3 --- /dev/null +++ b/examples/Readme.md @@ -0,0 +1,4 @@ +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/examples/hidtests2/hidtests2.ino b/examples/hidtests2/hidtests2.ino deleted file mode 100644 index 9f2af89..0000000 --- a/examples/hidtests2/hidtests2.ino +++ /dev/null @@ -1,169 +0,0 @@ -void setup() { - // put your setup code here, to run once: - pinMode(7, INPUT_PULLUP); - pinMode(8, INPUT_PULLUP); - pinMode(9, INPUT_PULLUP); - pinMode(10, INPUT_PULLUP); - pinMode(2, INPUT_PULLUP); - pinMode(3, INPUT_PULLUP); - - // 7052 279 - Keyboard.begin(); - Gamepad.begin(); - hid_keyboard_leds = 0; //test to access it from here -} - -uint32_t eventBaud = 0; - -void loop() { - - if (!digitalRead(7)) { - digitalWrite(13, 1); - Mouse.moveTo(1000, 1000); - delay(300); - digitalWrite(13, 0); - } - - if (!digitalRead(8)) { - digitalWrite(13, 1); - Mouse.move(100, 0); - delay(300); - digitalWrite(13, 0); - } - - if (!digitalRead(9)) { - digitalWrite(13, 1); - Mouse.move(-100, 0); - delay(300); - digitalWrite(13, 0); - } - - if (!digitalRead(10)) { - uint8_t k[8] = {0}; - k[1] = 1; - - k[2] = 4; - k[3] = 5; - HID_SendReport(HID_REPORTID_KEYBOARD, &k, sizeof(k)); - Keyboard.releaseAll(); - delay(300); - } - if (!digitalRead(2)) { - digitalWrite(13, 1); - System.write(SYSTEM_SLEEP); - delay(300); - digitalWrite(13, 0); - } - if (!digitalRead(3)) { - digitalWrite(13, 1); - USBDevice.wakeupHost(); - delay(300); - digitalWrite(13, 0); - } - - if (Serial.available()) { - // let the Serial receive all bytes and discard the first bytes - // this is to ensure you only input a single char and no string - char c; - delay(300); - int length = Serial.available(); - while (Serial.available()) - c = Serial.read(); - if (length > 1) { - Serial.println("Please only input a single character or deactivate linefeed!"); - return; - } - - if (c != -1) { - Serial.println(c); - switch (c) { - case 'a': - Keyboard.write('b'); - break; - - case 'p': - Consumer.write(MEDIA_PLAY_PAUSE); - break; - - case 'o': - { - // uint8_t k[8] = {0}; - // k[1] = 1 << 4; - // //k[2] = 4; - // HID_SendReport(HID_REPORTID_KEYBOARD, &k, sizeof(k)); - // Keyboard.releaseAll(); - break; - } - - case 's': - System.write(SYSTEM_SLEEP); - break; - - case 'r': - Mouse.move(100, 0); - break; - - case 'l': - Mouse.move(-100, 0); - break; - - case 't': - Mouse.moveTo(1000, 1000); - break; - - case 'c': - case 'C': - Keyboard.write(KEY_CAPS_LOCK); - Serial.println("Leds"); - Serial.println(Keyboard.getLEDs(), BIN); - break; - - case 'k': - Keyboard.print("Testing USB functions xyz"); - break; - - case '\r': - case '\n': - Serial.println("Please only input a single character!"); - break; - - case 'g': { - // 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; - } - Gamepad.write(); - } - break; - - case 'd': - Serial.println("Serial"); - Serial.println(Serial.dtr()); - Serial.println(Serial.rts()); - Serial.println(Serial.baud()); - Serial.println(Serial.stopbits()); - Serial.println(Serial.paritytype()); - Serial.println(Serial.numbits()); - break; - - default: - Serial.println("unknown"); - } - } - } - - - if (eventBaud) { - Serial.println("Event"); - Serial.println(eventBaud); - eventBaud = 0; - } -} - -void CDC_LineEncodingEvent(void) -{ - eventBaud = Serial.baud(); -}