Compare commits
53 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3fcbe5ccda | |||
| 6e4ed069be | |||
| aab401084b | |||
| 54d29302ae | |||
|
|
d4938ddcff | ||
|
|
4249490ab3 | ||
|
|
3c5000c4b6 | ||
|
|
ee0bbd9657 | ||
|
|
8cdc8cca26 | ||
|
|
813eb71440 | ||
|
|
2169d34f2c | ||
|
|
af9fff10e9 | ||
|
|
ede4a3e9cf | ||
|
|
a5e20e94d2 | ||
|
|
51611e6548 | ||
|
|
583718f453 | ||
|
|
12557b5489 | ||
|
|
7c269d9749 | ||
|
|
b33ff31253 | ||
|
|
d3147adbfd | ||
|
|
3a71aaeb72 | ||
|
|
f50383922e | ||
|
|
44fbac4089 | ||
|
|
516c6f3efd | ||
|
|
93a27986f8 | ||
|
|
dced097808 | ||
|
|
f96e09c75b | ||
|
|
8e5d8571e2 | ||
|
|
14f52f1879 | ||
|
|
bb0960c9f3 | ||
|
|
8bb3b2339f | ||
|
|
df98686d03 | ||
|
|
9a113eb8d2 | ||
|
|
4423cf6a47 | ||
|
|
7754123b6e | ||
|
|
5c245d7a8b | ||
|
|
e8f3178509 | ||
|
|
e632912905 | ||
|
|
a95361043b | ||
|
|
214802a3b6 | ||
|
|
86ed8a146b | ||
|
|
4c90e0b90d | ||
|
|
fcb32a5cf0 | ||
|
|
c197491272 | ||
|
|
626be84137 | ||
|
|
eed1098a21 | ||
|
|
0487754e10 | ||
|
|
6a93f83c46 | ||
|
|
a8c292a7bd | ||
|
|
febc714df5 | ||
|
|
ef6e8e52a7 | ||
|
|
186c2c432c | ||
|
|
b8bdc23208 |
47 changed files with 926 additions and 529 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "HID.wiki"]
|
||||||
|
path = HID.wiki
|
||||||
|
url = https://github.com/NicoHood/HID.wiki.git
|
||||||
1
HID.wiki
Submodule
1
HID.wiki
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit a1a0b086985dec037d7e7d86c6b2d5816207f202
|
||||||
222
Readme.md
222
Readme.md
|
|
@ -1,223 +1,29 @@
|
||||||
Arduino HID Project 2.4
|
**Arduino Silly Keyboard** forked from Arduino HID Project 2.4.4
|
||||||
=======================
|
=========================
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
This project went through a lot of phases and has now reached a new Arduino ~~USB-Core~~ Library
|
This is targetted at the Leonardo or compatible boards (32U4) and will be built around one of these:
|
||||||
with a lot of new functions like extended HID. It also supports HoodLoader1+2.
|
https://www.aliexpress.com/item/Beetle-Virtual-Keyboard-BadUSB-Pro-Micro-ATMEGA32U4-Module-Mini-Development-Expansion-Board-For-Arduino-Leonardo-R3/32847715254.html?spm=2114.search0104.3.1.7d542341ScymPz&ws_ab_test=searchweb0_0,searchweb201602_1_10152_10151_10065_10344_10068_10342_10343_10340_5722611_10341_10696_5722911_5722811_10084_5722711_10083_10618_10307_10134_5711211_10059_308_100031_10103_10624_10623_10622_10621_10620_5711311_5722511_10814_10815,searchweb201603_25,ppcSwitch_5&algo_expid=c50f562a-35a5-4cbe-9391-2b1586b8823e-0&algo_pvid=c50f562a-35a5-4cbe-9391-2b1586b8823e&priceBeautifyAB=0
|
||||||
The idea is to enable enhanced USB functions to almost all 'standard' Arduino boards.
|
|
||||||
|
|
||||||
**Supported Arduinos (IDE 1.6.6 or higher!):**
|
It's going to act like a keyboard (HID) and will write random words at random times with the purpose of being an entertaining toy for the office to play (innocent) jokes on colleagues.
|
||||||
* Uno (with [HoodLoader2](https://github.com/NicoHood/HoodLoader2))
|
|
||||||
* Mega (with [HoodLoader2](https://github.com/NicoHood/HoodLoader2))
|
|
||||||
* Leonardo
|
|
||||||
* (Pro)Micro
|
|
||||||
* Any other 8u2/16u2/at90usb8/162/32u2/32u4 compatible board
|
|
||||||
* No SAM/ARM support (Due, Zero etc)
|
|
||||||
|
|
||||||
**Supported HID devices:**
|
If I get clever, then it will insert words at just the right time when someone is typing - for example when the space bar is pressed and it's the perfect perfect time to insert a new new word word. Replay replay retyping things that were already typed would also be great. But I have some learning to do first!
|
||||||
* Keyboard with Leds out (8 modifiers + 6 keys pressed at the same time, + 1 limited linux consumer key)
|
|
||||||
* ~~Teensy Keyboard with different keyboard layouts (german, french and many more)~~ soon
|
|
||||||
* NKRO Keyboard with Leds out (press up to 113 keys at the same time)
|
|
||||||
* Mouse (5 buttons, move, wheel)
|
|
||||||
* BootKeyboard/BootMouse BIOS protocol support
|
|
||||||
* Absolute Mouse
|
|
||||||
* Consumer/Media Keys (4 keys for music player, web browser and more)
|
|
||||||
* System Key (for PC standby/shutdown)
|
|
||||||
* Gamepad (32 buttons, 4 16bit axis, 2 8bit axis, 2 D-Pads)
|
|
||||||
* RawHID
|
|
||||||
* Each device is available as single or multi report device (except RawHID)
|
|
||||||
|
|
||||||
See the [wiki](https://github.com/NicoHood/HID/wiki/Features) for more information about features etc.
|
The project will advance more when the hardware arrives (sometime in the next 5-6 weeks).
|
||||||
|
|
||||||
Wiki
|
|
||||||
====
|
|
||||||
|
|
||||||
All documentation moved to the [wiki page](https://github.com/NicoHood/HID/wiki).
|
|
||||||
|
|
||||||
An offline snapshot is available in [releases](https://github.com/NicoHood/HID/releases).
|
|
||||||
|
|
||||||
|
|
||||||
Contact
|
Forked at
|
||||||
=======
|
2.4.4 Release (27.01.2017)
|
||||||
|
* Added releaseAll() to Mouse API
|
||||||
You can contact me on my wordpress blog in the contact section.
|
* Fix flexible array errors
|
||||||
|
|
||||||
www.nicohood.de
|
|
||||||
|
|
||||||
|
|
||||||
Version History
|
|
||||||
===============
|
|
||||||
```
|
|
||||||
2.4 Release (06.11.2015)
|
|
||||||
* Added Arduino IDE 1.6.6 compatibility with Pluggable HID
|
|
||||||
* Improved Pluggable HID (see Arduyuino changelog for my improvements)
|
|
||||||
* Changed USB-Core into a simple library, only made possible with Pluggable HID
|
|
||||||
* Removed HID presets in boards menu (like mouse + keyboard + consumer + system)
|
|
||||||
* Added NKRO Keyboard
|
|
||||||
* Added Led report for Keyboard
|
|
||||||
* Added 1 Linux consumer key for keyboard
|
|
||||||
* Added BootKeyboard/Mouse support (BIOS compatibility)
|
|
||||||
* Added RawHID
|
|
||||||
* Added a few key definitions
|
|
||||||
* Renew whole Keyboard API and its definitions via enum
|
|
||||||
* Uses .alinkage custom IDE option
|
|
||||||
* Improved and updated examples
|
|
||||||
* A lot of other minor and major fixes I missed to mention.
|
|
||||||
|
|
||||||
2.3 Release (never released)
|
|
||||||
* Updated Libraries
|
|
||||||
* Updated Arduino Core
|
|
||||||
* Added Minor Consumer definitions
|
|
||||||
* Fixed platforms.txt
|
|
||||||
* SERIAL_RX_BUFFER_SIZE reverted to 16 (TODO add -D to build option)
|
|
||||||
|
|
||||||
2.2 Release (12.04.2015)
|
|
||||||
* added experimental, not finished nor documented HID-Bridge between 16u2 and 328/2560
|
|
||||||
* increased HW Serial1 RX buffer size from 16 to 32 (TX still 16)
|
|
||||||
* added colour highlighting (through HID-Bridge library)
|
|
||||||
* removed fixed size in report buffers
|
|
||||||
* used HID_KeyboardReport_Data_t now in Keyboard API
|
|
||||||
* Arduino as ISP fix for 328
|
|
||||||
* Upload verification on USB hubs fix for HL2.0.4
|
|
||||||
* No USB workaround for Leonardo integrated into variants
|
|
||||||
* Changed USB Wakeup in System API
|
|
||||||
* Consumer Key fix (issue #3)
|
|
||||||
* Gamepad fix (issue #14)
|
|
||||||
* Added Keycode example
|
|
||||||
* Mouse press + release fix
|
|
||||||
|
|
||||||
2.1 Release (28.01.2015)
|
|
||||||
* Reworked the whole USB-Core from scratch
|
|
||||||
* Uses less flash if HID or Serial is not used
|
|
||||||
* Extended and compacter(flash) HID Report Descriptors
|
|
||||||
* Fixed USB Device Descriptor
|
|
||||||
* Added u2 compatibility with smaller USB_EP_SIZE (16u2 etc)
|
|
||||||
* Added Serial Event for LineEncoding and LineState
|
|
||||||
* Added Serial Function to get dtr state, line encoding etc
|
|
||||||
* Added Keyboard Led Out report to get Led states (for numlock etc)
|
|
||||||
* Made CDC-Core independent from USB-Core
|
|
||||||
* Made HID-Core independent from USB-Core
|
|
||||||
* Made HID-API independent from HID-Core
|
|
||||||
* Removed not needed virtual functions in Keyboard
|
|
||||||
* Made HID Reports and its IDs replaceable via pins_Arduino.h
|
|
||||||
* Added Absolute Mouse
|
|
||||||
* Removed uint8_t USBPutChar(uint8_t c); in HID.cpp
|
|
||||||
* Made void Recv(volatile u8* data, u8 count) in USBCore.cpp static inline
|
|
||||||
* HID-APIs sends a clean report on begin() and end() now.
|
|
||||||
* Removed virtual functions in Keyboard API
|
|
||||||
* Added Keycode functions in Keyboard API
|
|
||||||
* Inlined a lot of the HID API functions to save flash
|
|
||||||
* Added Gamepad
|
|
||||||
* Added RawHID API (but RawHID itself isnt working still)
|
|
||||||
* Added USB Wakeup support
|
|
||||||
* Separated USB-Core in its own folder
|
|
||||||
* Added HID Tables
|
|
||||||
* USB-Serial now fully reprogrammable
|
|
||||||
* Easy USB-Core selection via Tools->USB-Core
|
|
||||||
* Added Arduino as ISP fix for 32u4 and 16u2
|
|
||||||
* Moved documentation to the wiki
|
|
||||||
* Added AVR libraries to the core with the better SoftSerial
|
|
||||||
|
|
||||||
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 Hoodloader1:
|
|
||||||
* **Huge improvements**, see Hoodloader1 repository
|
|
||||||
* 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 Hoodloader1:
|
|
||||||
* Fixed HID flush bug (1.6 - 1.7.2)
|
|
||||||
|
|
||||||
1.7.2 Beta Release (10.08.2014)
|
|
||||||
* Changes in the Hoodloader1:
|
|
||||||
* 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 Hoodloader1:
|
|
||||||
* Fixed HID deactivation bug
|
|
||||||
|
|
||||||
1.7 Beta Release (10.08.2014)
|
|
||||||
* Changes in the Hoodloader1:
|
|
||||||
* Works as ISP now. See Hoodloader1 Repository 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 Hoodloader1:
|
|
||||||
* 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 Hoodloader1 source to a separate Github page
|
|
||||||
* 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 Hoodloader1:
|
|
||||||
* 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 Hoodloader1:
|
|
||||||
* Improved ram usage
|
|
||||||
* **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 Hoodloader1:
|
|
||||||
* 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
|
Licence and Copyright
|
||||||
=====================
|
=====================
|
||||||
If you use this library for any cool project let me know!
|
Here's the original License conditions from NicoHood (AWESOME WORK!).
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2014-2015 NicoHood
|
Copyright (c) 2014-2016 NicoHood
|
||||||
See the readme for credit to other people.
|
See the readme for credit to other people.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|
|
||||||
|
|
@ -35,17 +35,17 @@ void loop() {
|
||||||
// Do not press to many at once or some OS will have problems.
|
// Do not press to many at once or some OS will have problems.
|
||||||
// Note that the resulting pressed order might differ,
|
// Note that the resulting pressed order might differ,
|
||||||
// because all keys are pressed at the same time.
|
// because all keys are pressed at the same time.
|
||||||
NKROKeyboard.addKeyToReport('0');
|
NKROKeyboard.add('0');
|
||||||
NKROKeyboard.addKeyToReport('1');
|
NKROKeyboard.add('1');
|
||||||
NKROKeyboard.addKeyToReport('2');
|
NKROKeyboard.add('2');
|
||||||
NKROKeyboard.addKeyToReport('3');
|
NKROKeyboard.add('3');
|
||||||
NKROKeyboard.addKeyToReport('4');
|
NKROKeyboard.add('4');
|
||||||
NKROKeyboard.addKeyToReport('5');
|
NKROKeyboard.add('5');
|
||||||
NKROKeyboard.addKeyToReport('6');
|
NKROKeyboard.add('6');
|
||||||
NKROKeyboard.addKeyToReport('7');
|
NKROKeyboard.add('7');
|
||||||
NKROKeyboard.addKeyToReport('8');
|
NKROKeyboard.add('8');
|
||||||
NKROKeyboard.addKeyToReport('9');
|
NKROKeyboard.add('9');
|
||||||
NKROKeyboard.send_now();
|
NKROKeyboard.send();
|
||||||
|
|
||||||
// Release all keys and hit enter
|
// Release all keys and hit enter
|
||||||
NKROKeyboard.releaseAll();
|
NKROKeyboard.releaseAll();
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
KeyboardFeatureReport example
|
||||||
|
|
||||||
|
Shows how to use BootKeyboard with a modified Hyperion Lightpack device.
|
||||||
|
This example also works with RawHID.
|
||||||
|
Might only work under linux.
|
||||||
|
https://github.com/tvdzwan/hyperion/pull/407
|
||||||
|
https://github.com/tvdzwan/hyperion/wiki
|
||||||
|
https://github.com/FastLED/FastLED
|
||||||
|
|
||||||
|
See HID Project documentation for more information.
|
||||||
|
https://github.com/NicoHood/HID/wiki/RawHID-API
|
||||||
|
https://github.com/NicoHood/HID/wiki/Keyboard-API#boot-keyboard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HID-Project.h"
|
||||||
|
|
||||||
|
const int pinLed = LED_BUILTIN;
|
||||||
|
|
||||||
|
|
||||||
|
// FastLED
|
||||||
|
#include "FastLED.h"
|
||||||
|
|
||||||
|
#define LED_PINS MOSI, SCK // DATA_PIN, or DATA_PIN, CLOCK_PIN
|
||||||
|
#define COLOR_ORDER RGB
|
||||||
|
#define CHIPSET WS2801 // WS2811, LPD8806, etc
|
||||||
|
#define NUM_LEDS 25
|
||||||
|
|
||||||
|
#define BRIGHTNESS 255 // Reduce power consumption
|
||||||
|
#define LED_DITHER 255 // Try 0 to disable flickering
|
||||||
|
#define CORRECTION TypicalLEDStrip
|
||||||
|
|
||||||
|
CRGB leds[NUM_LEDS]; // Define the array of leds
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// FastLED setup
|
||||||
|
FastLED.addLeds<CHIPSET, LED_PINS, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(CORRECTION);
|
||||||
|
FastLED.setBrightness(BRIGHTNESS);
|
||||||
|
FastLED.setDither(LED_DITHER);
|
||||||
|
|
||||||
|
// Startup animation
|
||||||
|
fill_solid(leds, NUM_LEDS, CRGB::Red);
|
||||||
|
FastLED.show();
|
||||||
|
delay(500);
|
||||||
|
fill_solid(leds, NUM_LEDS, CRGB::Green);
|
||||||
|
FastLED.show();
|
||||||
|
delay(500);
|
||||||
|
fill_solid(leds, NUM_LEDS, CRGB::Blue);
|
||||||
|
FastLED.show();
|
||||||
|
delay(500);
|
||||||
|
FastLED.clear();
|
||||||
|
FastLED.show();
|
||||||
|
|
||||||
|
pinMode(pinLed, OUTPUT);
|
||||||
|
|
||||||
|
// Sends a clean report to the host. This is important on any Arduino type.
|
||||||
|
BootKeyboard.begin();
|
||||||
|
|
||||||
|
// Let the feature report data directly point at the led array
|
||||||
|
BootKeyboard.setFeatureReport(leds, sizeof(leds));
|
||||||
|
BootKeyboard.enableFeatureReport();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Check if there is new feature request data from the keyboard
|
||||||
|
if (BootKeyboard.availableFeatureReport())
|
||||||
|
{
|
||||||
|
digitalWrite(pinLed, HIGH);
|
||||||
|
|
||||||
|
// Update leds, do not update in the loop, to avoid corrupted data.
|
||||||
|
// For example if you write (0, 0, 0) and the interrupt
|
||||||
|
// changes the data to (255, 255, 255) you might get (0, 255, 255).
|
||||||
|
// Using a duplicated led array in cli() context would also work.
|
||||||
|
FastLED.show();
|
||||||
|
|
||||||
|
// Release data to let the USB interrupt overwrite it again
|
||||||
|
BootKeyboard.enableFeatureReport();
|
||||||
|
|
||||||
|
digitalWrite(pinLed, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2014-2015 NicoHood
|
|
||||||
See the readme for credit to other people.
|
|
||||||
|
|
||||||
Advanced RawHID example
|
|
||||||
|
|
||||||
Shows how to send bytes via RawHID.
|
|
||||||
Press a button to send some example values.
|
|
||||||
|
|
||||||
Every received data is mirrored to the host.
|
|
||||||
The use of the RawHIDEvent() function is shown too.
|
|
||||||
|
|
||||||
This sketch only tries to show the possiblities
|
|
||||||
and is not perfect.You might want to use RawHID differently.
|
|
||||||
|
|
||||||
See HID Project documentation for more information.
|
|
||||||
https://github.com/NicoHood/HID/wiki/RawHID-API
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "HID-Project.h"
|
|
||||||
|
|
||||||
const int pinLed = LED_BUILTIN;
|
|
||||||
const int pinButton = 2;
|
|
||||||
|
|
||||||
uint8_t data[255];
|
|
||||||
volatile size_t len = 0;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
pinMode(pinLed, OUTPUT);
|
|
||||||
pinMode(pinButton, INPUT_PULLUP);
|
|
||||||
|
|
||||||
// No begin/end function required for RawHID
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
// Send data to the host
|
|
||||||
if (!digitalRead(pinButton)) {
|
|
||||||
digitalWrite(pinLed, HIGH);
|
|
||||||
|
|
||||||
// Create buffer with numbers and send it
|
|
||||||
uint8_t megabuff[100];
|
|
||||||
for (uint8_t i = 0; i < sizeof(megabuff); i++) {
|
|
||||||
megabuff[i] = i;
|
|
||||||
}
|
|
||||||
RawHID.write(megabuff, sizeof(megabuff));
|
|
||||||
|
|
||||||
// Simple debounce
|
|
||||||
delay(300);
|
|
||||||
digitalWrite(pinLed, LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This will miss longer RawHID data transmissions
|
|
||||||
// and return an error to the host if data was missed.
|
|
||||||
// Only use this for non changing/less important data.
|
|
||||||
// Or you can use this if the event aborted on a full buffer.
|
|
||||||
// Please note, that all data after this full buffer is missed anyways.
|
|
||||||
auto bytesAvailable = RawHID.available();
|
|
||||||
while (bytesAvailable--) {
|
|
||||||
if (len < sizeof(data)) {
|
|
||||||
data[len++] = RawHID.read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process data from the host
|
|
||||||
if (len) {
|
|
||||||
digitalWrite(pinLed, HIGH);
|
|
||||||
|
|
||||||
// Disable interrupts while processing the data
|
|
||||||
uint8_t oldSREG = SREG;
|
|
||||||
cli();
|
|
||||||
|
|
||||||
// Mirror the incoming data from the host back
|
|
||||||
RawHID.write(data, len);
|
|
||||||
len = 0;
|
|
||||||
|
|
||||||
SREG = oldSREG;
|
|
||||||
|
|
||||||
// Simple debounce for led
|
|
||||||
delay(300);
|
|
||||||
digitalWrite(pinLed, LOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RawHIDEvent(void) {
|
|
||||||
// This event is called via interrupt.
|
|
||||||
// Do not use print inside, or other long function calls!
|
|
||||||
// If you not use this event function,
|
|
||||||
// you might miss some data in the loop,
|
|
||||||
// if the host sends too fast or too much data at once.
|
|
||||||
|
|
||||||
auto bytesAvailable = RawHID.available();
|
|
||||||
while (bytesAvailable--) {
|
|
||||||
// Only add data to the buffer if its not full.
|
|
||||||
// If it is, no more event will occur
|
|
||||||
// and the data should be discarded
|
|
||||||
// or read (as shown) in the loop above.
|
|
||||||
if (len < sizeof(data)) {
|
|
||||||
data[len++] = RawHID.read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
71
examples/RawHID/RawHID/RawHID.ino
Normal file
71
examples/RawHID/RawHID/RawHID.ino
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Advanced RawHID example
|
||||||
|
|
||||||
|
Shows how to send bytes via RawHID.
|
||||||
|
Press a button to send some example values.
|
||||||
|
|
||||||
|
Every received data is mirrored to the host via Serial.
|
||||||
|
|
||||||
|
See HID Project documentation for more information.
|
||||||
|
https://github.com/NicoHood/HID/wiki/RawHID-API
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HID-Project.h"
|
||||||
|
|
||||||
|
const int pinLed = LED_BUILTIN;
|
||||||
|
const int pinButton = 2;
|
||||||
|
|
||||||
|
// Buffer to hold RawHID data.
|
||||||
|
// If host tries to send more data than this,
|
||||||
|
// it will respond with an error.
|
||||||
|
// If the data is not read until the host sends the next data
|
||||||
|
// it will also respond with an error and the data will be lost.
|
||||||
|
uint8_t rawhidData[255];
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(pinLed, OUTPUT);
|
||||||
|
pinMode(pinButton, INPUT_PULLUP);
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
// Set the RawHID OUT report array.
|
||||||
|
// Feature reports are also (parallel) possible, see the other example for this.
|
||||||
|
RawHID.begin(rawhidData, sizeof(rawhidData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Send data to the host
|
||||||
|
if (!digitalRead(pinButton)) {
|
||||||
|
digitalWrite(pinLed, HIGH);
|
||||||
|
|
||||||
|
// Create buffer with numbers and send it
|
||||||
|
uint8_t megabuff[100];
|
||||||
|
for (uint8_t i = 0; i < sizeof(megabuff); i++) {
|
||||||
|
megabuff[i] = i;
|
||||||
|
}
|
||||||
|
RawHID.write(megabuff, sizeof(megabuff));
|
||||||
|
|
||||||
|
// Simple debounce
|
||||||
|
delay(300);
|
||||||
|
digitalWrite(pinLed, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if there is new data from the RawHID device
|
||||||
|
auto bytesAvailable = RawHID.available();
|
||||||
|
if (bytesAvailable)
|
||||||
|
{
|
||||||
|
digitalWrite(pinLed, HIGH);
|
||||||
|
|
||||||
|
// Mirror data via Serial
|
||||||
|
while (bytesAvailable--) {
|
||||||
|
Serial.println(RawHID.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(pinLed, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
92
examples/RawHID/RawHIDPaintpack/RawHIDPaintpack.ino
Normal file
92
examples/RawHID/RawHIDPaintpack/RawHIDPaintpack.ino
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
RawHIDPaintpack example
|
||||||
|
|
||||||
|
Shows how to use RawHID with the Hyperion Lightpack device.
|
||||||
|
https://github.com/tvdzwan/hyperion/wiki
|
||||||
|
https://github.com/FastLED/FastLED
|
||||||
|
|
||||||
|
See HID Project documentation for more information.
|
||||||
|
https://github.com/NicoHood/HID/wiki/RawHID-API
|
||||||
|
https://github.com/NicoHood/HID/wiki/Keyboard-API#boot-keyboard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HID-Project.h"
|
||||||
|
|
||||||
|
const int pinLed = LED_BUILTIN;
|
||||||
|
|
||||||
|
|
||||||
|
// FastLED
|
||||||
|
#include "FastLED.h"
|
||||||
|
|
||||||
|
#define LED_PINS MOSI, SCK // DATA_PIN, or DATA_PIN, CLOCK_PIN
|
||||||
|
#define COLOR_ORDER RGB
|
||||||
|
#define CHIPSET WS2801 // WS2811, LPD8806, etc
|
||||||
|
#define NUM_LEDS 25
|
||||||
|
|
||||||
|
#define BRIGHTNESS 255 // Reduce power consumption
|
||||||
|
#define LED_DITHER 255 // Try 0 to disable flickering
|
||||||
|
#define CORRECTION TypicalLEDStrip
|
||||||
|
|
||||||
|
CRGB leds[NUM_LEDS]; // Define the array of leds
|
||||||
|
uint8_t rawhidData[sizeof(leds) + 2];
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// FastLED setup
|
||||||
|
FastLED.addLeds<CHIPSET, LED_PINS, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(CORRECTION);
|
||||||
|
FastLED.setBrightness(BRIGHTNESS);
|
||||||
|
FastLED.setDither(LED_DITHER);
|
||||||
|
|
||||||
|
// Startup animation
|
||||||
|
fill_solid(leds, NUM_LEDS, CRGB::Red);
|
||||||
|
FastLED.show();
|
||||||
|
delay(500);
|
||||||
|
fill_solid(leds, NUM_LEDS, CRGB::Green);
|
||||||
|
FastLED.show();
|
||||||
|
delay(500);
|
||||||
|
fill_solid(leds, NUM_LEDS, CRGB::Blue);
|
||||||
|
FastLED.show();
|
||||||
|
delay(500);
|
||||||
|
FastLED.clear();
|
||||||
|
FastLED.show();
|
||||||
|
|
||||||
|
pinMode(pinLed, OUTPUT);
|
||||||
|
|
||||||
|
// Set the RawHID OUT report array.
|
||||||
|
// Feature reports are also (parallel) possible, see the other example for this.
|
||||||
|
RawHID.begin(rawhidData, sizeof(rawhidData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Check if there is new data from the RawHID device
|
||||||
|
auto bytesAvailable = RawHID.available();
|
||||||
|
if (bytesAvailable == sizeof(rawhidData))
|
||||||
|
{
|
||||||
|
digitalWrite(pinLed, HIGH);
|
||||||
|
|
||||||
|
// Check header for errors
|
||||||
|
if (RawHID.read() != 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (RawHID.read() != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write data to led array
|
||||||
|
uint8_t* ptr = (uint8_t*)leds;
|
||||||
|
for (int i = 0; i < sizeof(leds); i++) {
|
||||||
|
*ptr = RawHID.read();
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update leds, do not update in the loop, to avoid corrupted data.
|
||||||
|
// For example if you write (0, 0, 0) and the interrupt
|
||||||
|
// changes the data to (255, 255, 255) you might get (0, 255, 255).
|
||||||
|
// Using a duplicated led array in cli() context would also work.
|
||||||
|
FastLED.show();
|
||||||
|
|
||||||
|
digitalWrite(pinLed, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
examples/SurfaceDial/connection_diagram.png
Normal file
BIN
examples/SurfaceDial/connection_diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 231 KiB |
85
examples/SurfaceDial/surface_dial.ino
Normal file
85
examples/SurfaceDial/surface_dial.ino
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2017 wind-rider
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Surface dial example
|
||||||
|
|
||||||
|
Use an encoder and a button to create a Surface Dial-compatible device.
|
||||||
|
See the connection diagram how to wire it up.
|
||||||
|
|
||||||
|
Please note that:
|
||||||
|
- I tested it using an Arduino Pro Micro; TinkerCad didn't have that in its component library
|
||||||
|
- you obviously don't need a motor, but TinkerCad didn't have a separate encoder
|
||||||
|
|
||||||
|
The encoder processing code is coming from https://www.allwinedesigns.com/blog/pocketnc-jog-wheel
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HID-Project.h"
|
||||||
|
|
||||||
|
// input pins for encoder channel A and channel B
|
||||||
|
int pinA = 2;
|
||||||
|
int pinB = 3;
|
||||||
|
|
||||||
|
// input pin for pushbutton
|
||||||
|
int pinButton = 4;
|
||||||
|
|
||||||
|
volatile bool previousButtonValue = false;
|
||||||
|
|
||||||
|
volatile int previous = 0;
|
||||||
|
volatile int counter = 0;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(pinA, INPUT_PULLUP);
|
||||||
|
pinMode(pinB, INPUT_PULLUP);
|
||||||
|
|
||||||
|
pinMode(pinButton, INPUT_PULLUP);
|
||||||
|
|
||||||
|
attachInterrupt(digitalPinToInterrupt(pinA), changed, CHANGE);
|
||||||
|
attachInterrupt(digitalPinToInterrupt(pinB), changed, CHANGE);
|
||||||
|
|
||||||
|
SurfaceDial.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void changed() {
|
||||||
|
int A = digitalRead(pinA);
|
||||||
|
int B = digitalRead(pinB);
|
||||||
|
|
||||||
|
int current = (A << 1) | B;
|
||||||
|
int combined = (previous << 2) | current;
|
||||||
|
|
||||||
|
if(combined == 0b0010 ||
|
||||||
|
combined == 0b1011 ||
|
||||||
|
combined == 0b1101 ||
|
||||||
|
combined == 0b0100) {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(combined == 0b0001 ||
|
||||||
|
combined == 0b0111 ||
|
||||||
|
combined == 0b1110 ||
|
||||||
|
combined == 0b1000) {
|
||||||
|
counter--;
|
||||||
|
}
|
||||||
|
|
||||||
|
previous = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
bool buttonValue = digitalRead(pinButton);
|
||||||
|
if(buttonValue != previousButtonValue){
|
||||||
|
if(buttonValue) {
|
||||||
|
SurfaceDial.press();
|
||||||
|
} else {
|
||||||
|
SurfaceDial.release();
|
||||||
|
}
|
||||||
|
previousButtonValue = buttonValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(counter >= 4) {
|
||||||
|
SurfaceDial.rotate(10);
|
||||||
|
counter -= 4;
|
||||||
|
} else if(counter <= -4) {
|
||||||
|
SurfaceDial.rotate(-10);
|
||||||
|
counter += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
extras/ArduinoRawHID.rules
Normal file
44
extras/ArduinoRawHID.rules
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Original taken and modified from:
|
||||||
|
# https://github.com/ihowson/Teensy-Raw-HID-in-Python/blob/master/teensy_loader_cli/49-teensy.rules
|
||||||
|
#
|
||||||
|
# This file must be placed at:
|
||||||
|
#
|
||||||
|
# /etc/udev/rules.d/ArduinoRawHID.rules (preferred location)
|
||||||
|
# or
|
||||||
|
# /lib/udev/rules.d/ArduinoRawHID.rules (req'd on some broken systems)
|
||||||
|
#
|
||||||
|
# SUBSYSTEMS=="usb", ATTRS{idVendor}=="0x2341", ATTRS{idProduct}=="0x8036", MODE:="0666"
|
||||||
|
#
|
||||||
|
# Reload udev rules:
|
||||||
|
# udevadm control --reload && udevadm trigger
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Arduino devices (leonardo only, or all Arduino devices):
|
||||||
|
#SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", MODE:="0666"
|
||||||
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", MODE:="0666"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666"
|
||||||
|
#SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="8000", MODE:="0666"
|
||||||
|
#KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="ttyUSB00%n", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||||
|
#
|
||||||
|
# If you share your linux system with other users, or just don't like the
|
||||||
|
# idea of write permission for everybody, you can replace MODE:="0666" with
|
||||||
|
# OWNER:="yourusername" to create the device owned by you, or with
|
||||||
|
# GROUP:="somegroupname" and mange access using standard unix groups.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# If using USB Serial you get a new device each time (Ubuntu 9.10)
|
||||||
|
# eg: /dev/ttyACM0, ttyACM1, ttyACM2, ttyACM3, ttyACM4, etc
|
||||||
|
# apt-get remove --purge modemmanager (reboot may be necessary)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Older modem proding (eg, Ubuntu 9.04) caused very slow serial device detection.
|
||||||
|
# To fix, add this near top of /lib/udev/rules.d/77-nm-probe-modem-capabilities.rules
|
||||||
|
# SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", GOTO="nm_modem_probe_end"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# (old udev rules)
|
||||||
|
#SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="047[78]", MODE:="0666"
|
||||||
|
#SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="048[02]", MODE:="0666"
|
||||||
|
#KERNEL=="ttyACM*", SYMLINK+="ttyUSB00%n", MODE:="0666"
|
||||||
|
|
@ -144,7 +144,7 @@ int rawhid_send(int num, void *buf, int len, int timeout)
|
||||||
if (hid->ep_out) {
|
if (hid->ep_out) {
|
||||||
return usb_interrupt_write(hid->usb, hid->ep_out, buf, len, timeout);
|
return usb_interrupt_write(hid->usb, hid->ep_out, buf, len, timeout);
|
||||||
} else {
|
} else {
|
||||||
return usb_control_msg(hid->usb, 0x21, 9, 0, hid->iface, buf, len, timeout);
|
return usb_control_msg(hid->usb, 0x21, 9, 0x0200, hid->iface, buf, len, timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
15
keywords.txt
15
keywords.txt
|
|
@ -13,6 +13,8 @@
|
||||||
begin KEYWORD2
|
begin KEYWORD2
|
||||||
end KEYWORD2
|
end KEYWORD2
|
||||||
press KEYWORD2
|
press KEYWORD2
|
||||||
|
add KEYWORD2
|
||||||
|
remove KEYWORD2
|
||||||
release KEYWORD2
|
release KEYWORD2
|
||||||
releaseAll KEYWORD2
|
releaseAll KEYWORD2
|
||||||
|
|
||||||
|
|
@ -22,13 +24,10 @@ moveTo KEYWORD2
|
||||||
isPressed KEYWORD2
|
isPressed KEYWORD2
|
||||||
|
|
||||||
getLeds KEYWORD2
|
getLeds KEYWORD2
|
||||||
pressKeycode KEYWORD2
|
setFeatureReport KEYWORD2
|
||||||
releaseKeycode KEYWORD2
|
availableFeatureReport KEYWORD2
|
||||||
writeKeycode KEYWORD2
|
enableFeatureReport KEYWORD2
|
||||||
addKeyToReport KEYWORD2
|
disableFeatureReport KEYWORD2
|
||||||
addKeycodeToReport KEYWORD2
|
|
||||||
removeKeyFromReport KEYWORD2
|
|
||||||
removeKeycodeFromReport KEYWORD2
|
|
||||||
|
|
||||||
write_unicode KEYWORD2
|
write_unicode KEYWORD2
|
||||||
set_modifier KEYWORD2
|
set_modifier KEYWORD2
|
||||||
|
|
@ -39,7 +38,7 @@ set_key4 KEYWORD2
|
||||||
set_key5 KEYWORD2
|
set_key5 KEYWORD2
|
||||||
set_key6 KEYWORD2
|
set_key6 KEYWORD2
|
||||||
set_media KEYWORD2
|
set_media KEYWORD2
|
||||||
send_now KEYWORD2
|
send KEYWORD2
|
||||||
|
|
||||||
buttons KEYWORD2
|
buttons KEYWORD2
|
||||||
xAxis KEYWORD2
|
xAxis KEYWORD2
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
name=HID-Project
|
name=HID-Project
|
||||||
version=2.4
|
version=2.4.4
|
||||||
author=NicoHood
|
author=NicoHood
|
||||||
maintainer=NicoHood <blog@NicoHood.de>
|
maintainer=NicoHood <blog@NicoHood.de>
|
||||||
sentence=Extended HID Functions for Arduino
|
sentence=Extended HID Functions for Arduino
|
||||||
paragraph=Includes Consumer, System and Gamepad. Also compatible with Arduino Uno/Mega via HoodLoader2.
|
paragraph=Includes BootKeyboard/Mouse, Consumer, System, Gamepad, RawHID and more features. Also compatible with Arduino Uno/Mega via HoodLoader2.
|
||||||
category=Device Control
|
category=Communication
|
||||||
url=https://github.com/NicoHood/HID
|
url=https://github.com/NicoHood/HID
|
||||||
architectures=*
|
architectures=avr
|
||||||
dot_a_linkage=true
|
dot_a_linkage=true
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
{
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "HID",
|
|
||||||
"maintainer": "NicoHood",
|
|
||||||
"websiteURL": "https://github.com/NicoHood/HID",
|
|
||||||
"email": "",
|
|
||||||
"help": {
|
|
||||||
"online": ""
|
|
||||||
},
|
|
||||||
"platforms": [
|
|
||||||
{
|
|
||||||
"name": "HID Project",
|
|
||||||
"architecture": "avr",
|
|
||||||
"version": "2.2",
|
|
||||||
"category": "HID",
|
|
||||||
"help": {
|
|
||||||
"online": ""
|
|
||||||
},
|
|
||||||
"url": "https://github.com/NicoHood/HID/releases/download/2.2/2.2-boards_manager.zip",
|
|
||||||
"archiveFileName": "2.2-boards_manager.zip",
|
|
||||||
"checksum": "SHA-256:9c86ee28a7ce9fe33e8b07ec643316131e0031b0d22e63bb398902a5fdadbca9",
|
|
||||||
"size": "351303",
|
|
||||||
"boards": [
|
|
||||||
{"name": "Arduino Leonardo"},
|
|
||||||
{"name": "Arduino Micro"}
|
|
||||||
],
|
|
||||||
"toolsDependencies": [
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avr-gcc",
|
|
||||||
"version": "4.8.1-arduino5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avrdude",
|
|
||||||
"version": "6.0.1-arduino5"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tools": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -39,9 +39,9 @@ THE SOFTWARE.
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// Absolute mouse report: 8 buttons, 2 absolute axis, wheel
|
// Absolute mouse report: 8 buttons, 2 absolute axis, wheel
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
struct{
|
struct{
|
||||||
uint8_t buttons;
|
uint8_t buttons;
|
||||||
int16_t xAxis;
|
int16_t xAxis;
|
||||||
|
|
@ -71,12 +71,12 @@ public:
|
||||||
inline void move(int x, int y, signed char wheel = 0);
|
inline void move(int x, int y, signed char wheel = 0);
|
||||||
inline void press(uint8_t b = MOUSE_LEFT);
|
inline void press(uint8_t b = MOUSE_LEFT);
|
||||||
inline void release(uint8_t b = MOUSE_LEFT);
|
inline void release(uint8_t b = MOUSE_LEFT);
|
||||||
|
inline void releaseAll(void);
|
||||||
inline bool isPressed(uint8_t b = MOUSE_LEFT);
|
inline bool isPressed(uint8_t b = MOUSE_LEFT);
|
||||||
|
|
||||||
// Sending is public in the base class for advanced users.
|
// Sending is public in the base class for advanced users.
|
||||||
virtual void SendReport(void* data, int length) = 0;
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementation is inline
|
// Implementation is inline
|
||||||
#include "AbsoluteMouseAPI.hpp"
|
#include "AbsoluteMouseAPI.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ void AbsoluteMouseAPI::buttons(uint8_t b){
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t AbsoluteMouseAPI::qadd16(int16_t base, int16_t increment) {
|
int16_t AbsoluteMouseAPI::qadd16(int16_t base, int16_t increment) {
|
||||||
// Separate between subtracting and adding
|
// Separate between subtracting and adding
|
||||||
if (increment < 0) {
|
if (increment < 0) {
|
||||||
// Subtracting more would cause an undefined overflow
|
// Subtracting more would cause an undefined overflow
|
||||||
if ((int16_t)0x8000 - increment > base)
|
if ((int16_t)0x8000 - increment > base)
|
||||||
|
|
@ -50,7 +50,7 @@ int16_t AbsoluteMouseAPI::qadd16(int16_t base, int16_t increment) {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbsoluteMouseAPI::AbsoluteMouseAPI(void):
|
AbsoluteMouseAPI::AbsoluteMouseAPI(void):
|
||||||
xAxis(0), yAxis(0), _buttons(0)
|
xAxis(0), yAxis(0), _buttons(0)
|
||||||
{
|
{
|
||||||
// Empty
|
// Empty
|
||||||
|
|
@ -98,6 +98,11 @@ void AbsoluteMouseAPI::release(uint8_t b){
|
||||||
buttons(_buttons & ~b);
|
buttons(_buttons & ~b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbsoluteMouseAPI::releaseAll(void){
|
||||||
|
_buttons = 0;
|
||||||
|
moveTo(xAxis, yAxis, 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool AbsoluteMouseAPI::isPressed(uint8_t b){
|
bool AbsoluteMouseAPI::isPressed(uint8_t b){
|
||||||
// check LEFT by default
|
// check LEFT by default
|
||||||
if ((b & _buttons) > 0)
|
if ((b & _buttons) > 0)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ enum ConsumerKeycode : uint16_t {
|
||||||
MEDIA_VOLUME_DOWN = 0xEA,
|
MEDIA_VOLUME_DOWN = 0xEA,
|
||||||
MEDIA_VOL_DOWN = 0xEA, // Alias
|
MEDIA_VOL_DOWN = 0xEA, // Alias
|
||||||
|
|
||||||
|
CONSUMER_BRIGHTNESS_UP = 0x006F,
|
||||||
|
CONSUMER_BRIGHTNESS_DOWN = 0x0070,
|
||||||
|
|
||||||
CONSUMER_SCREENSAVER = 0x19e,
|
CONSUMER_SCREENSAVER = 0x19e,
|
||||||
|
|
||||||
CONSUMER_PROGRAMMABLE_BUTTON_CONFIGURATION = 0x182,
|
CONSUMER_PROGRAMMABLE_BUTTON_CONFIGURATION = 0x182,
|
||||||
|
|
@ -450,9 +453,9 @@ enum ConsumerKeycode : uint16_t {
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
// Every usable Consumer key possible, up to 4 keys presses possible
|
// Every usable Consumer key possible, up to 4 keys presses possible
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
ConsumerKeycode keys[4];
|
ConsumerKeycode keys[4];
|
||||||
struct {
|
struct {
|
||||||
ConsumerKeycode key1;
|
ConsumerKeycode key1;
|
||||||
|
|
@ -472,7 +475,7 @@ public:
|
||||||
inline void press(ConsumerKeycode m);
|
inline void press(ConsumerKeycode m);
|
||||||
inline void release(ConsumerKeycode m);
|
inline void release(ConsumerKeycode m);
|
||||||
inline void releaseAll(void);
|
inline void releaseAll(void);
|
||||||
|
|
||||||
// Sending is public in the base class for advanced users.
|
// Sending is public in the base class for advanced users.
|
||||||
virtual void SendReport(void* data, int length) = 0;
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
|
|
||||||
|
|
@ -482,4 +485,3 @@ protected:
|
||||||
|
|
||||||
// Implementation is inline
|
// Implementation is inline
|
||||||
#include "ConsumerAPI.hpp"
|
#include "ConsumerAPI.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ THE SOFTWARE.
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
struct{
|
struct{
|
||||||
uint8_t modifiers;
|
uint8_t modifiers;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
|
|
@ -74,4 +74,3 @@ private:
|
||||||
|
|
||||||
// Implementation is inline
|
// Implementation is inline
|
||||||
#include "DefaultKeyboardAPI.hpp"
|
#include "DefaultKeyboardAPI.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ size_t DefaultKeyboardAPI::set(KeyboardKeycode k, bool s)
|
||||||
// Convert key into bitfield (0 - 7)
|
// Convert key into bitfield (0 - 7)
|
||||||
k = KeyboardKeycode(uint8_t(k) - uint8_t(KEY_LEFT_CTRL));
|
k = KeyboardKeycode(uint8_t(k) - uint8_t(KEY_LEFT_CTRL));
|
||||||
if(s){
|
if(s){
|
||||||
_keyReport.modifiers = (1 << k);
|
_keyReport.modifiers |= (1 << k);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
_keyReport.modifiers &= ~(1 << k);
|
_keyReport.modifiers &= ~(1 << k);
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@ THE SOFTWARE.
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
// 32 Buttons, 6 Axis, 2 D-Pads
|
// 32 Buttons, 6 Axis, 2 D-Pads
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
uint32_t buttons;
|
uint32_t buttons;
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
|
|
@ -117,7 +117,7 @@ public:
|
||||||
inline void rzAxis(int8_t a);
|
inline void rzAxis(int8_t a);
|
||||||
inline void dPad1(int8_t d);
|
inline void dPad1(int8_t d);
|
||||||
inline void dPad2(int8_t d);
|
inline void dPad2(int8_t d);
|
||||||
|
|
||||||
// Sending is public in the base class for advanced users.
|
// Sending is public in the base class for advanced users.
|
||||||
virtual void SendReport(void* data, int length) = 0;
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
|
|
||||||
|
|
@ -127,4 +127,3 @@ protected:
|
||||||
|
|
||||||
// Implementation is inline
|
// Implementation is inline
|
||||||
#include "GamepadAPI.hpp"
|
#include "GamepadAPI.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,9 @@ THE SOFTWARE.
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// Mouse report: 8 buttons, position, wheel
|
// Mouse report: 8 buttons, position, wheel
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
struct{
|
struct{
|
||||||
uint8_t buttons;
|
uint8_t buttons;
|
||||||
int8_t xAxis;
|
int8_t xAxis;
|
||||||
|
|
@ -53,9 +53,9 @@ typedef union{
|
||||||
typedef union{
|
typedef union{
|
||||||
// BootMouse report: 3 buttons, position
|
// BootMouse report: 3 buttons, position
|
||||||
// Wheel is not supported by boot protocol
|
// Wheel is not supported by boot protocol
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
struct{
|
struct{
|
||||||
uint8_t buttons;
|
uint8_t buttons;
|
||||||
int8_t xAxis;
|
int8_t xAxis;
|
||||||
|
|
@ -70,14 +70,15 @@ public:
|
||||||
inline void begin(void);
|
inline void begin(void);
|
||||||
inline void end(void);
|
inline void end(void);
|
||||||
inline void click(uint8_t b = MOUSE_LEFT);
|
inline void click(uint8_t b = MOUSE_LEFT);
|
||||||
inline void move(signed char x, signed char y, signed char wheel = 0);
|
inline void move(signed char x, signed char y, signed char wheel = 0);
|
||||||
inline void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
inline void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
||||||
inline void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
inline void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
||||||
|
inline void releaseAll(void);
|
||||||
inline bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
inline bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
||||||
|
|
||||||
// Sending is public in the base class for advanced users.
|
// Sending is public in the base class for advanced users.
|
||||||
virtual void SendReport(void* data, int length) = 0;
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t _buttons;
|
uint8_t _buttons;
|
||||||
inline void buttons(uint8_t b);
|
inline void buttons(uint8_t b);
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,12 @@ MouseAPI::MouseAPI(void) : _buttons(0)
|
||||||
// Empty
|
// Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseAPI::begin(void)
|
void MouseAPI::begin(void)
|
||||||
{
|
{
|
||||||
end();
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseAPI::end(void)
|
void MouseAPI::end(void)
|
||||||
{
|
{
|
||||||
_buttons = 0;
|
_buttons = 0;
|
||||||
move(0, 0, 0);
|
move(0, 0, 0);
|
||||||
|
|
@ -67,7 +67,7 @@ void MouseAPI::buttons(uint8_t b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseAPI::press(uint8_t b)
|
void MouseAPI::press(uint8_t b)
|
||||||
{
|
{
|
||||||
buttons(_buttons | b);
|
buttons(_buttons | b);
|
||||||
}
|
}
|
||||||
|
|
@ -77,10 +77,15 @@ void MouseAPI::release(uint8_t b)
|
||||||
buttons(_buttons & ~b);
|
buttons(_buttons & ~b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MouseAPI::releaseAll(void)
|
||||||
|
{
|
||||||
|
_buttons = 0;
|
||||||
|
move(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
bool MouseAPI::isPressed(uint8_t b)
|
bool MouseAPI::isPressed(uint8_t b)
|
||||||
{
|
{
|
||||||
if ((b & _buttons) > 0)
|
if ((b & _buttons) > 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,9 @@ THE SOFTWARE.
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// Modifier + keymap + 1 custom key
|
// Modifier + keymap + 1 custom key
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
struct{
|
struct{
|
||||||
uint8_t modifiers;
|
uint8_t modifiers;
|
||||||
uint8_t keys[NKRO_KEY_COUNT / 8];
|
uint8_t keys[NKRO_KEY_COUNT / 8];
|
||||||
|
|
@ -43,7 +43,7 @@ typedef union{
|
||||||
uint8_t allkeys[2 + NKRO_KEY_COUNT / 8];
|
uint8_t allkeys[2 + NKRO_KEY_COUNT / 8];
|
||||||
} HID_NKROKeyboardReport_Data_t;
|
} HID_NKROKeyboardReport_Data_t;
|
||||||
|
|
||||||
|
|
||||||
class NKROKeyboardAPI : public KeyboardAPI
|
class NKROKeyboardAPI : public KeyboardAPI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -62,4 +62,3 @@ private:
|
||||||
|
|
||||||
// Implementation is inline
|
// Implementation is inline
|
||||||
#include "NKROKeyboardAPI.hpp"
|
#include "NKROKeyboardAPI.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ size_t NKROKeyboardAPI::set(KeyboardKeycode k, bool s)
|
||||||
// Convert key into bitfield (0 - 7)
|
// Convert key into bitfield (0 - 7)
|
||||||
k = KeyboardKeycode(uint8_t(k) - uint8_t(KEY_LEFT_CTRL));
|
k = KeyboardKeycode(uint8_t(k) - uint8_t(KEY_LEFT_CTRL));
|
||||||
if(s){
|
if(s){
|
||||||
_keyReport.modifiers = (1 << k);
|
_keyReport.modifiers |= (1 << k);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
_keyReport.modifiers &= ~(1 << k);
|
_keyReport.modifiers &= ~(1 << k);
|
||||||
|
|
|
||||||
66
src/HID-APIs/SurfaceDialAPI.h
Normal file
66
src/HID-APIs/SurfaceDialAPI.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 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 guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "HID-Settings.h"
|
||||||
|
|
||||||
|
typedef union{
|
||||||
|
// SurfaceDial report: 1 button, 15-bit rotation, position
|
||||||
|
uint8_t whole8[0];
|
||||||
|
uint16_t whole16[0];
|
||||||
|
uint32_t whole32[0];
|
||||||
|
struct{
|
||||||
|
uint16_t button: 1;
|
||||||
|
uint16_t rotation: 15;
|
||||||
|
//int8_t xAxis;
|
||||||
|
//int8_t yAxis;
|
||||||
|
|
||||||
|
};
|
||||||
|
} HID_SurfaceDialReport_Data_t;
|
||||||
|
|
||||||
|
class SurfaceDialAPI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline SurfaceDialAPI(void);
|
||||||
|
inline void begin(void);
|
||||||
|
inline void end(void);
|
||||||
|
inline void click(void);
|
||||||
|
inline void rotate(int16_t rotation);
|
||||||
|
inline void press(void);
|
||||||
|
inline void release(void);
|
||||||
|
inline void releaseAll(void);
|
||||||
|
inline bool isPressed();
|
||||||
|
|
||||||
|
// Sending is public in the base class for advanced users.
|
||||||
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _button;
|
||||||
|
inline void button(bool b);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation is inline
|
||||||
|
#include "SurfaceDialAPI.hpp"
|
||||||
90
src/HID-APIs/SurfaceDialAPI.hpp
Normal file
90
src/HID-APIs/SurfaceDialAPI.hpp
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 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 guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
SurfaceDialAPI::SurfaceDialAPI(void) : _button(false)
|
||||||
|
{
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::begin(void)
|
||||||
|
{
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::end(void)
|
||||||
|
{
|
||||||
|
_button = false;
|
||||||
|
rotate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::click(void)
|
||||||
|
{
|
||||||
|
_button = true;
|
||||||
|
rotate(0);
|
||||||
|
_button = false;
|
||||||
|
rotate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::rotate(int16_t rotation)
|
||||||
|
{
|
||||||
|
HID_SurfaceDialReport_Data_t report;
|
||||||
|
report.button = _button;
|
||||||
|
report.rotation = rotation;
|
||||||
|
//report.xAxis = x;
|
||||||
|
//report.yAxis = y;
|
||||||
|
|
||||||
|
SendReport(&report, sizeof(report));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::button(bool b)
|
||||||
|
{
|
||||||
|
if (b != _button)
|
||||||
|
{
|
||||||
|
_button = b;
|
||||||
|
rotate(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::press(void)
|
||||||
|
{
|
||||||
|
button(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::release(void)
|
||||||
|
{
|
||||||
|
button(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDialAPI::releaseAll(void)
|
||||||
|
{
|
||||||
|
_button = false;
|
||||||
|
rotate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SurfaceDialAPI::isPressed()
|
||||||
|
{
|
||||||
|
return _button;
|
||||||
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ enum SystemKeycode : uint8_t {
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// Every usable system control key possible
|
// Every usable system control key possible
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint8_t key;
|
uint8_t key;
|
||||||
} HID_SystemControlReport_Data_t;
|
} HID_SystemControlReport_Data_t;
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ public:
|
||||||
inline void press(SystemKeycode s);
|
inline void press(SystemKeycode s);
|
||||||
inline void release(void);
|
inline void release(void);
|
||||||
inline void releaseAll(void);
|
inline void releaseAll(void);
|
||||||
|
|
||||||
// Sending is public in the base class for advanced users.
|
// Sending is public in the base class for advanced users.
|
||||||
virtual void SendReport(void* data, int length) = 0;
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,10 @@ THE SOFTWARE.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Software version
|
// Software version
|
||||||
#define HID_PROJECT_VERSION 240
|
#define HID_PROJECT_VERSION 244
|
||||||
|
|
||||||
// TODO remove https://github.com/arduino/arduino-builder/issues/33
|
#if ARDUINO < 10607
|
||||||
#include <Arduino.h>
|
#error HID Project requires Arduino IDE 1.6.7 or greater. Please update your IDE.
|
||||||
|
|
||||||
#if ARDUINO < 10606
|
|
||||||
#error HID Project requires Arduino IDE 1.6.6 or greater. Please update your IDE.
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USBCON)
|
#if !defined(USBCON)
|
||||||
|
|
@ -54,7 +51,7 @@ THE SOFTWARE.
|
||||||
#include "MultiReport/ImprovedKeyboard.h"
|
#include "MultiReport/ImprovedKeyboard.h"
|
||||||
#include "SingleReport/SingleNKROKeyboard.h"
|
#include "SingleReport/SingleNKROKeyboard.h"
|
||||||
#include "MultiReport/NKROKeyboard.h"
|
#include "MultiReport/NKROKeyboard.h"
|
||||||
|
#include "MultiReport/SurfaceDial.h"
|
||||||
|
|
||||||
// Include Teensy HID afterwards to overwrite key definitions if used
|
// Include Teensy HID afterwards to overwrite key definitions if used
|
||||||
// TODO include Teensy API if non english keyboard layout was used
|
// TODO include Teensy API if non english keyboard layout was used
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,3 +108,7 @@ THE SOFTWARE.
|
||||||
#ifndef HID_REPORTID_TEENSY_KEYBOARD
|
#ifndef HID_REPORTID_TEENSY_KEYBOARD
|
||||||
#define HID_REPORTID_TEENSY_KEYBOARD 9
|
#define HID_REPORTID_TEENSY_KEYBOARD 9
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HID_REPORTID_SURFACEDIAL
|
||||||
|
#define HID_REPORTID_SURFACEDIAL 10
|
||||||
|
#endif
|
||||||
|
|
@ -37,8 +37,7 @@ public:
|
||||||
Keyboard_(void);
|
Keyboard_(void);
|
||||||
void wakeupHost(void);
|
void wakeupHost(void);
|
||||||
|
|
||||||
protected:
|
virtual inline int send(void) final;
|
||||||
virtual inline int send(void) override;
|
|
||||||
};
|
};
|
||||||
extern Keyboard_ Keyboard;
|
extern Keyboard_ Keyboard;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,7 @@ class NKROKeyboard_ : public NKROKeyboardAPI
|
||||||
public:
|
public:
|
||||||
NKROKeyboard_(void);
|
NKROKeyboard_(void);
|
||||||
|
|
||||||
protected:
|
virtual int send(void) final;
|
||||||
virtual inline int send(void) override;
|
|
||||||
};
|
};
|
||||||
extern NKROKeyboard_ NKROKeyboard;
|
extern NKROKeyboard_ NKROKeyboard;
|
||||||
|
|
||||||
|
|
|
||||||
87
src/MultiReport/SurfaceDial.cpp
Normal file
87
src/MultiReport/SurfaceDial.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 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 "SurfaceDial.h"
|
||||||
|
|
||||||
|
static const uint8_t _hidMultiReportDescriptorSurfaceDial[] PROGMEM = {
|
||||||
|
// Integrated Radial Controller TLC
|
||||||
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||||
|
0x09, 0x0e, // USAGE (System Multi-Axis Controller)
|
||||||
|
0xa1, 0x01, // COLLECTION (Application)
|
||||||
|
0x85, HID_REPORTID_SURFACEDIAL, // REPORT_ID (Radial Controller)
|
||||||
|
0x05, 0x0d, // USAGE_PAGE (Digitizers)
|
||||||
|
0x09, 0x21, // USAGE (Puck)
|
||||||
|
0xa1, 0x00, // COLLECTION (Physical)
|
||||||
|
0x05, 0x09, // USAGE_PAGE (Buttons)
|
||||||
|
0x09, 0x01, // USAGE (Button 1)
|
||||||
|
0x95, 0x01, // REPORT_COUNT (1)
|
||||||
|
0x75, 0x01, // REPORT_SIZE (1)
|
||||||
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||||
|
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||||
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||||
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||||
|
0x09, 0x37, // USAGE (Dial)
|
||||||
|
0x95, 0x01, // REPORT_COUNT (1)
|
||||||
|
0x75, 0x0f, // REPORT_SIZE (15)
|
||||||
|
0x55, 0x0f, // UNIT_EXPONENT (-1)
|
||||||
|
0x65, 0x14, // UNIT (Degrees, English Rotation)
|
||||||
|
0x36, 0xf0, 0xf1, // PHYSICAL_MINIMUM (-3600)
|
||||||
|
0x46, 0x10, 0x0e, // PHYSICAL_MAXIMUM (3600)
|
||||||
|
0x16, 0xf0, 0xf1, // LOGICAL_MINIMUM (-3600)
|
||||||
|
0x26, 0x10, 0x0e, // LOGICAL_MAXIMUM (3600)
|
||||||
|
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||||
|
// 0x09, 0x30, // USAGE (X)
|
||||||
|
// 0x75, 0x10, // REPORT_SIZE (16)
|
||||||
|
// 0x55, 0x0d, // UNIT_EXPONENT (-3)
|
||||||
|
// 0x65, 0x13, // UNIT (Inch,EngLinear)
|
||||||
|
// 0x35, 0x00, // PHYSICAL_MINIMUM (0)
|
||||||
|
// 0x46, 0xc0, 0x5d, // PHYSICAL_MAXIMUM (24000)
|
||||||
|
// 0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||||
|
// 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
|
||||||
|
// 0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||||
|
// 0x09, 0x31, // USAGE (Y)
|
||||||
|
// 0x46, 0xb0, 0x36, // PHYSICAL_MAXIMUM (14000)
|
||||||
|
// 0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||||
|
// 0x05, 0x0d, // USAGE_PAGE (Digitizers)
|
||||||
|
// 0x09, 0x48, // USAGE (Width)
|
||||||
|
// 0x36, 0xb8, 0x0b, // PHYSICAL_MINIMUM (3000)
|
||||||
|
// 0x46, 0xb8, 0x0b, // PHYSICAL_MAXIMUM (3000)
|
||||||
|
// 0x16, 0xb8, 0x0b, // LOGICAL_MINIMUM (3000)
|
||||||
|
// 0x26, 0xb8, 0x0b, // LOGICAL_MAXIMUM (3000)
|
||||||
|
// 0x81, 0x03 // INPUT (Cnst,Var,Abs)
|
||||||
|
0xc0, // END_COLLECTION
|
||||||
|
0xc0 // END_COLLECTION
|
||||||
|
};
|
||||||
|
|
||||||
|
SurfaceDial_::SurfaceDial_(void)
|
||||||
|
{
|
||||||
|
static HIDSubDescriptor node(_hidMultiReportDescriptorSurfaceDial, sizeof(_hidMultiReportDescriptorSurfaceDial));
|
||||||
|
HID().AppendDescriptor(&node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceDial_::SendReport(void *data, int length)
|
||||||
|
{
|
||||||
|
HID().SendReport(HID_REPORTID_SURFACEDIAL, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceDial_ SurfaceDial;
|
||||||
43
src/MultiReport/SurfaceDial.h
Normal file
43
src/MultiReport/SurfaceDial.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 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 guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "PluggableUSB.h"
|
||||||
|
#include "HID.h"
|
||||||
|
#include "HID-Settings.h"
|
||||||
|
#include "../HID-APIs/SurfaceDialAPI.h"
|
||||||
|
|
||||||
|
|
||||||
|
class SurfaceDial_ : public SurfaceDialAPI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SurfaceDial_(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual inline void SendReport(void* data, int length) override;
|
||||||
|
};
|
||||||
|
extern SurfaceDial_ SurfaceDial;
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ static const uint8_t _hidReportDescriptorKeyboard[] PROGMEM = {
|
||||||
0xc0 /* END_COLLECTION */
|
0xc0 /* END_COLLECTION */
|
||||||
};
|
};
|
||||||
|
|
||||||
BootKeyboard_::BootKeyboard_(void) : PluggableUSBModule(1, 1, epType), protocol(HID_REPORT_PROTOCOL), idle(1), leds(0)
|
BootKeyboard_::BootKeyboard_(void) : PluggableUSBModule(1, 1, epType), protocol(HID_REPORT_PROTOCOL), idle(1), leds(0), featureReport(NULL), featureLength(0)
|
||||||
{
|
{
|
||||||
epType[0] = EP_TYPE_INTERRUPT_IN;
|
epType[0] = EP_TYPE_INTERRUPT_IN;
|
||||||
PluggableUSB().plug(this);
|
PluggableUSB().plug(this);
|
||||||
|
|
@ -120,10 +120,12 @@ bool BootKeyboard_::setup(USBSetup& setup)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (request == HID_GET_PROTOCOL) {
|
if (request == HID_GET_PROTOCOL) {
|
||||||
|
// TODO improve
|
||||||
UEDATX = protocol;
|
UEDATX = protocol;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (request == HID_GET_IDLE) {
|
if (request == HID_GET_IDLE) {
|
||||||
|
// TODO improve
|
||||||
UEDATX = idle;
|
UEDATX = idle;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -141,10 +143,39 @@ bool BootKeyboard_::setup(USBSetup& setup)
|
||||||
}
|
}
|
||||||
if (request == HID_SET_REPORT)
|
if (request == HID_SET_REPORT)
|
||||||
{
|
{
|
||||||
// Check if data has the correct length
|
// Check if data has the correct length afterwards
|
||||||
auto length = setup.wLength;
|
int length = setup.wLength;
|
||||||
if(length == sizeof(leds)){
|
|
||||||
USB_RecvControl(&leds, length);
|
// Feature (set feature report)
|
||||||
|
if(setup.wValueH == HID_REPORT_TYPE_FEATURE){
|
||||||
|
// No need to check for negative featureLength values,
|
||||||
|
// except the host tries to send more then 32k bytes.
|
||||||
|
// We dont have that much ram anyways.
|
||||||
|
if (length == featureLength) {
|
||||||
|
USB_RecvControl(featureReport, featureLength);
|
||||||
|
|
||||||
|
// Block until data is read (make length negative)
|
||||||
|
disableFeatureReport();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// TODO fake clear data?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output (set led states)
|
||||||
|
else if(setup.wValueH == HID_REPORT_TYPE_OUTPUT){
|
||||||
|
if(length == sizeof(leds)){
|
||||||
|
USB_RecvControl(&leds, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input (set HID report)
|
||||||
|
else if(setup.wValueH == HID_REPORT_TYPE_INPUT)
|
||||||
|
{
|
||||||
|
if(length == sizeof(_keyReport)){
|
||||||
|
USB_RecvControl(&_keyReport, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,33 @@ public:
|
||||||
uint8_t getLeds(void);
|
uint8_t getLeds(void);
|
||||||
uint8_t getProtocol(void);
|
uint8_t getProtocol(void);
|
||||||
void wakeupHost(void);
|
void wakeupHost(void);
|
||||||
|
|
||||||
|
void setFeatureReport(void* report, int length){
|
||||||
|
if(length > 0){
|
||||||
|
featureReport = (uint8_t*)report;
|
||||||
|
featureLength = length;
|
||||||
|
|
||||||
|
// Disable feature report by default
|
||||||
|
disableFeatureReport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int availableFeatureReport(void){
|
||||||
|
if(featureLength < 0){
|
||||||
|
return featureLength & ~0x8000;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableFeatureReport(void){
|
||||||
|
featureLength &= ~0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableFeatureReport(void){
|
||||||
|
featureLength |= 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int send(void) final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implementation of the PUSBListNode
|
// Implementation of the PUSBListNode
|
||||||
|
|
@ -51,7 +78,8 @@ protected:
|
||||||
|
|
||||||
uint8_t leds;
|
uint8_t leds;
|
||||||
|
|
||||||
virtual int send(void) override;
|
uint8_t* featureReport;
|
||||||
|
int featureLength;
|
||||||
};
|
};
|
||||||
extern BootKeyboard_ BootKeyboard;
|
extern BootKeyboard_ BootKeyboard;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,7 @@ static const uint8_t _hidReportDescriptorRawHID[] PROGMEM = {
|
||||||
0xC0 /* end collection */
|
0xC0 /* end collection */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Weak implementation of the Event function
|
RawHID_::RawHID_(void) : PluggableUSBModule(1, 1, epType), protocol(HID_REPORT_PROTOCOL), idle(1), dataLength(0), dataAvailable(0), featureReport(NULL), featureLength(0)
|
||||||
void RawHIDEvent(void) __attribute__ ((weak));
|
|
||||||
void RawHIDEvent(void){
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
RawHID_::RawHID_(void) : PluggableUSBModule(1, 1, epType), protocol(HID_REPORT_PROTOCOL), idle(1), dataLength(0)
|
|
||||||
{
|
{
|
||||||
epType[0] = EP_TYPE_INTERRUPT_IN;
|
epType[0] = EP_TYPE_INTERRUPT_IN;
|
||||||
PluggableUSB().plug(this);
|
PluggableUSB().plug(this);
|
||||||
|
|
@ -120,50 +114,36 @@ bool RawHID_::setup(USBSetup& setup)
|
||||||
}
|
}
|
||||||
if (request == HID_SET_REPORT)
|
if (request == HID_SET_REPORT)
|
||||||
{
|
{
|
||||||
// Get the data length information and the corresponding bytes
|
// Check if data has the correct length afterwards
|
||||||
int length = setup.wLength;
|
int length = setup.wLength;
|
||||||
while(length)
|
|
||||||
{
|
// Feature (set feature report)
|
||||||
// Dont receive more than the USB EP has to offer
|
if(setup.wValueH == HID_REPORT_TYPE_FEATURE){
|
||||||
// TODO use fixed 64 because control EP always have 64 bytes even on 16 u2. Test!
|
// No need to check for negative featureLength values,
|
||||||
auto recvLength = length;
|
// except the host tries to send more then 32k bytes.
|
||||||
if(recvLength > USB_EP_SIZE){
|
// We dont have that much ram anyways.
|
||||||
recvLength = USB_EP_SIZE;
|
if (length == featureLength) {
|
||||||
}
|
USB_RecvControl(featureReport, featureLength);
|
||||||
if(recvLength > int(sizeof(data))){
|
|
||||||
recvLength = int(sizeof(data));
|
// Block until data is read (make length negative)
|
||||||
}
|
disableFeatureReport();
|
||||||
length -= recvLength;
|
return true;
|
||||||
|
}
|
||||||
// Only receive data if the last one was read fully.
|
}
|
||||||
// Discard data if it wasnt read yet.
|
|
||||||
// To not miss any data you can use the (weak) event function.
|
// Output (set out report)
|
||||||
if(!dataLength)
|
else if(setup.wValueH == HID_REPORT_TYPE_OUTPUT){
|
||||||
{
|
if(!dataAvailable && length <= dataLength){
|
||||||
// Write data to fit to the end (not the beginning) of the array
|
// Write data to fit to the end (not the beginning) of the array
|
||||||
USB_RecvControl(data + (sizeof(data) - recvLength), recvLength);
|
USB_RecvControl(data + dataLength - length, length);
|
||||||
dataLength = recvLength;
|
dataAvailable = length;
|
||||||
RawHIDEvent();
|
return true;
|
||||||
}
|
|
||||||
// Do not read the data, flag an error to the USB Host
|
|
||||||
// TODO always return no error, even if data was discarded? -> use break then
|
|
||||||
else{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag no error
|
|
||||||
// TODO this is required to get hyperion working
|
|
||||||
// however this blocks the CDC serial!?
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawHID_::SendReport(void* data, int length){
|
|
||||||
USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawHID_ RawHID;
|
RawHID_ RawHID;
|
||||||
|
|
|
||||||
|
|
@ -54,17 +54,17 @@ THE SOFTWARE.
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// a RAWHID_TX_SIZE byte buffer for tx
|
// a RAWHID_TX_SIZE byte buffer for tx
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
uint8_t buff[RAWHID_TX_SIZE];
|
uint8_t buff[RAWHID_TX_SIZE];
|
||||||
} HID_RawKeyboardTXReport_Data_t;
|
} HID_RawKeyboardTXReport_Data_t;
|
||||||
|
|
||||||
typedef union{
|
typedef union{
|
||||||
// a RAWHID_TX_SIZE byte buffer for rx
|
// a RAWHID_TX_SIZE byte buffer for rx
|
||||||
uint8_t whole8[];
|
uint8_t whole8[0];
|
||||||
uint16_t whole16[];
|
uint16_t whole16[0];
|
||||||
uint32_t whole32[];
|
uint32_t whole32[0];
|
||||||
uint8_t buff[RAWHID_RX_SIZE];
|
uint8_t buff[RAWHID_RX_SIZE];
|
||||||
} HID_RawKeyboardRXReport_Data_t;
|
} HID_RawKeyboardRXReport_Data_t;
|
||||||
|
|
||||||
|
|
@ -73,36 +73,77 @@ class RawHID_ : public PluggableUSBModule, public Stream
|
||||||
public:
|
public:
|
||||||
RawHID_(void);
|
RawHID_(void);
|
||||||
|
|
||||||
void begin(void){
|
void setFeatureReport(void* report, int length){
|
||||||
// empty
|
if(length > 0){
|
||||||
|
featureReport = (uint8_t*)report;
|
||||||
|
featureLength = length;
|
||||||
|
|
||||||
|
// Disable feature report by default
|
||||||
|
disableFeatureReport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int availableFeatureReport(void){
|
||||||
|
if(featureLength < 0){
|
||||||
|
return featureLength & ~0x8000;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableFeatureReport(void){
|
||||||
|
featureLength &= ~0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableFeatureReport(void){
|
||||||
|
featureLength |= 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void begin(void* report, int length){
|
||||||
|
if(length > 0){
|
||||||
|
data = (uint8_t*)report;
|
||||||
|
dataLength = length;
|
||||||
|
dataAvailable = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void end(void){
|
void end(void){
|
||||||
// empty
|
disable();
|
||||||
|
dataLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enable(void){
|
||||||
|
dataAvailable = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable(void){
|
||||||
|
dataAvailable = -1;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int available(void){
|
virtual int available(void){
|
||||||
return dataLength;
|
if(dataAvailable < 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return dataAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int read(){
|
virtual int read(){
|
||||||
// Check if we have data available
|
// Check if we have data available
|
||||||
if(dataLength)
|
if(dataAvailable > 0)
|
||||||
{
|
{
|
||||||
// Get next data byte (from the start to the end)
|
// Get next data byte (from the start to the end)
|
||||||
return data[sizeof(data) - dataLength--];
|
return data[dataLength - dataAvailable--];
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int peek(){
|
virtual int peek(){
|
||||||
// Check if we have data available
|
// Check if we have data available
|
||||||
if(dataLength){
|
if(dataAvailable > 0){
|
||||||
return data[sizeof(data) - dataLength];
|
return data[dataLength - dataAvailable];
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void flush(void){
|
virtual void flush(void){
|
||||||
// Writing will always flush by the USB driver
|
// Writing will always flush by the USB driver
|
||||||
}
|
}
|
||||||
|
|
@ -114,40 +155,25 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t write(uint8_t *buffer, size_t size){
|
virtual size_t write(uint8_t *buffer, size_t size){
|
||||||
// TODO this will split the data into proper USB_EP_SIZE packets already
|
return USB_Send(pluggedEndpoint | TRANSFER_RELEASE, buffer, size);
|
||||||
SendReport(buffer, size);
|
|
||||||
return size;
|
|
||||||
|
|
||||||
size_t bytesleft = size;
|
|
||||||
// First work through the buffer thats already there
|
|
||||||
while (bytesleft >= RAWHID_TX_SIZE){
|
|
||||||
SendReport(&buffer[size - bytesleft], RAWHID_TX_SIZE);
|
|
||||||
bytesleft -= RAWHID_TX_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write down the leftover bytes and fill with zeros
|
|
||||||
if (bytesleft){
|
|
||||||
SendReport(&buffer[size - bytesleft], bytesleft);
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendReport(void* data, int length);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implementation of the PUSBListNode
|
// Implementation of the PUSBListNode
|
||||||
int getInterface(uint8_t* interfaceCount);
|
int getInterface(uint8_t* interfaceCount);
|
||||||
int getDescriptor(USBSetup& setup);
|
int getDescriptor(USBSetup& setup);
|
||||||
bool setup(USBSetup& setup);
|
bool setup(USBSetup& setup);
|
||||||
|
|
||||||
uint8_t epType[1];
|
uint8_t epType[1];
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
uint8_t idle;
|
uint8_t idle;
|
||||||
|
|
||||||
// Buffer pointers to hold the received data
|
// Buffer pointers to hold the received data
|
||||||
int dataLength;
|
int dataLength;
|
||||||
uint8_t data[RAWHID_RX_SIZE];
|
int dataAvailable;
|
||||||
|
uint8_t* data;
|
||||||
|
|
||||||
|
uint8_t* featureReport;
|
||||||
|
int featureLength;
|
||||||
};
|
};
|
||||||
extern RawHID_ RawHID;
|
extern RawHID_ RawHID;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ public:
|
||||||
SingleNKROKeyboard_(void);
|
SingleNKROKeyboard_(void);
|
||||||
uint8_t getLeds(void);
|
uint8_t getLeds(void);
|
||||||
uint8_t getProtocol(void);
|
uint8_t getProtocol(void);
|
||||||
|
|
||||||
|
virtual int send(void) final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implementation of the PUSBListNode
|
// Implementation of the PUSBListNode
|
||||||
|
|
@ -49,8 +51,6 @@ protected:
|
||||||
uint8_t idle;
|
uint8_t idle;
|
||||||
|
|
||||||
uint8_t leds;
|
uint8_t leds;
|
||||||
|
|
||||||
virtual inline int send(void) override;
|
|
||||||
};
|
};
|
||||||
extern SingleNKROKeyboard_ SingleNKROKeyboard;
|
extern SingleNKROKeyboard_ SingleNKROKeyboard;
|
||||||
|
|
||||||
|
|
|
||||||
BIN
virtualkeyb.jpg
Normal file
BIN
virtualkeyb.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in a new issue