Merge pull request #67 from NicoHood/dev

Release 2.4.1
This commit is contained in:
Nico 2015-12-19 01:46:47 +01:00
commit df98686d03
26 changed files with 473 additions and 264 deletions

View file

View file

@ -1,5 +1,5 @@
Arduino HID Project 2.4
=======================
Arduino HID Project 2.4.1
=========================
![Header Picture](header.jpg)
@ -49,6 +49,12 @@ www.nicohood.de
Version History
===============
```
2.4.1 Release (19.12.2015)
* RawHID Improvements
* Added Keyboard Feature Report
* NKRO and Keyboard API fixes
* Arduino library manager fix
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)

View file

@ -35,17 +35,17 @@ void loop() {
// Do not press to many at once or some OS will have problems.
// Note that the resulting pressed order might differ,
// because all keys are pressed at the same time.
NKROKeyboard.addKeyToReport('0');
NKROKeyboard.addKeyToReport('1');
NKROKeyboard.addKeyToReport('2');
NKROKeyboard.addKeyToReport('3');
NKROKeyboard.addKeyToReport('4');
NKROKeyboard.addKeyToReport('5');
NKROKeyboard.addKeyToReport('6');
NKROKeyboard.addKeyToReport('7');
NKROKeyboard.addKeyToReport('8');
NKROKeyboard.addKeyToReport('9');
NKROKeyboard.send_now();
NKROKeyboard.add('0');
NKROKeyboard.add('1');
NKROKeyboard.add('2');
NKROKeyboard.add('3');
NKROKeyboard.add('4');
NKROKeyboard.add('5');
NKROKeyboard.add('6');
NKROKeyboard.add('7');
NKROKeyboard.add('8');
NKROKeyboard.add('9');
NKROKeyboard.send();
// Release all keys and hit enter
NKROKeyboard.releaseAll();

View file

@ -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);
}
}

View file

@ -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();
}
}
}

View 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);
}
}

View 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);
}
}

View 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"

View file

@ -144,7 +144,7 @@ int rawhid_send(int num, void *buf, int len, int timeout)
if (hid->ep_out) {
return usb_interrupt_write(hid->usb, hid->ep_out, buf, len, timeout);
} 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);
}
}

View file

@ -13,6 +13,8 @@
begin KEYWORD2
end KEYWORD2
press KEYWORD2
add KEYWORD2
remove KEYWORD2
release KEYWORD2
releaseAll KEYWORD2
@ -22,13 +24,10 @@ moveTo KEYWORD2
isPressed KEYWORD2
getLeds KEYWORD2
pressKeycode KEYWORD2
releaseKeycode KEYWORD2
writeKeycode KEYWORD2
addKeyToReport KEYWORD2
addKeycodeToReport KEYWORD2
removeKeyFromReport KEYWORD2
removeKeycodeFromReport KEYWORD2
setFeatureReport KEYWORD2
availableFeatureReport KEYWORD2
enableFeatureReport KEYWORD2
disableFeatureReport KEYWORD2
write_unicode KEYWORD2
set_modifier KEYWORD2
@ -39,7 +38,7 @@ set_key4 KEYWORD2
set_key5 KEYWORD2
set_key6 KEYWORD2
set_media KEYWORD2
send_now KEYWORD2
send KEYWORD2
buttons KEYWORD2
xAxis KEYWORD2

View file

@ -1,10 +1,10 @@
name=HID-Project
version=2.4
version=2.4.1
author=NicoHood
maintainer=NicoHood <blog@NicoHood.de>
sentence=Extended HID Functions for Arduino
paragraph=Includes Consumer, System and Gamepad. Also compatible with Arduino Uno/Mega via HoodLoader2.
category=Device Control
paragraph=Includes BootKeyboard/Mouse, Consumer, System, Gamepad, RawHID and more features. Also compatible with Arduino Uno/Mega via HoodLoader2.
category=Communication
url=https://github.com/NicoHood/HID
architectures=*
architectures=avr
dot_a_linkage=true

View file

@ -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": []
}
]
}

View file

@ -25,13 +25,10 @@ THE SOFTWARE.
#pragma once
// Software version
#define HID_PROJECT_VERSION 240
#define HID_PROJECT_VERSION 241
// TODO remove https://github.com/arduino/arduino-builder/issues/33
#include <Arduino.h>
#if ARDUINO < 10606
#error HID Project requires Arduino IDE 1.6.6 or greater. Please update your IDE.
#if ARDUINO < 10607
#error HID Project requires Arduino IDE 1.6.7 or greater. Please update your IDE.
#endif
#if !defined(USBCON)

View file

@ -37,8 +37,7 @@ public:
Keyboard_(void);
void wakeupHost(void);
protected:
virtual inline int send(void) override;
virtual inline int send(void) final;
};
extern Keyboard_ Keyboard;

View file

@ -36,8 +36,7 @@ class NKROKeyboard_ : public NKROKeyboardAPI
public:
NKROKeyboard_(void);
protected:
virtual inline int send(void) override;
virtual int send(void) final;
};
extern NKROKeyboard_ NKROKeyboard;

View file

@ -71,7 +71,7 @@ static const uint8_t _hidReportDescriptorKeyboard[] PROGMEM = {
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;
PluggableUSB().plug(this);
@ -120,10 +120,12 @@ bool BootKeyboard_::setup(USBSetup& setup)
return true;
}
if (request == HID_GET_PROTOCOL) {
// TODO improve
UEDATX = protocol;
return true;
}
if (request == HID_GET_IDLE) {
// TODO improve
UEDATX = idle;
return true;
}
@ -141,10 +143,39 @@ bool BootKeyboard_::setup(USBSetup& setup)
}
if (request == HID_SET_REPORT)
{
// Check if data has the correct length
auto length = setup.wLength;
if(length == sizeof(leds)){
USB_RecvControl(&leds, length);
// Check if data has the correct length afterwards
int length = setup.wLength;
// 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;
}
}
}
}

View file

@ -38,6 +38,33 @@ public:
uint8_t getLeds(void);
uint8_t getProtocol(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:
// Implementation of the PUSBListNode
@ -51,7 +78,8 @@ protected:
uint8_t leds;
virtual int send(void) override;
uint8_t* featureReport;
int featureLength;
};
extern BootKeyboard_ BootKeyboard;

View file

@ -47,13 +47,7 @@ static const uint8_t _hidReportDescriptorRawHID[] PROGMEM = {
0xC0 /* end collection */
};
// Weak implementation of the Event function
void RawHIDEvent(void) __attribute__ ((weak));
void RawHIDEvent(void){
// Empty
}
RawHID_::RawHID_(void) : PluggableUSBModule(1, 1, epType), protocol(HID_REPORT_PROTOCOL), idle(1), dataLength(0)
RawHID_::RawHID_(void) : PluggableUSBModule(1, 1, epType), protocol(HID_REPORT_PROTOCOL), idle(1), dataLength(0), dataAvailable(0), featureReport(NULL), featureLength(0)
{
epType[0] = EP_TYPE_INTERRUPT_IN;
PluggableUSB().plug(this);
@ -120,50 +114,36 @@ bool RawHID_::setup(USBSetup& setup)
}
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;
while(length)
{
// Dont receive more than the USB EP has to offer
// TODO use fixed 64 because control EP always have 64 bytes even on 16 u2. Test!
auto recvLength = length;
if(recvLength > USB_EP_SIZE){
recvLength = USB_EP_SIZE;
}
if(recvLength > int(sizeof(data))){
recvLength = int(sizeof(data));
}
length -= recvLength;
// 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.
if(!dataLength)
{
// Write data to fit to the end (not the beginning) of the array
USB_RecvControl(data + (sizeof(data) - recvLength), recvLength);
dataLength = recvLength;
RawHIDEvent();
}
// 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;
// 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;
}
}
// Output (set out report)
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
USB_RecvControl(data + dataLength - length, length);
dataAvailable = length;
return true;
}
}
// Flag no error
// TODO this is required to get hyperion working
// however this blocks the CDC serial!?
return true;
}
}
return false;
}
void RawHID_::SendReport(void* data, int length){
USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, length);
}
RawHID_ RawHID;

View file

@ -73,32 +73,73 @@ class RawHID_ : public PluggableUSBModule, public Stream
public:
RawHID_(void);
void begin(void){
// empty
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;
}
void begin(void* report, int length){
if(length > 0){
data = (uint8_t*)report;
dataLength = length;
dataAvailable = 0;
}
}
void end(void){
// empty
disable();
dataLength = 0;
}
void enable(void){
dataAvailable = 0;
}
void disable(void){
dataAvailable = -1;
}
virtual int available(void){
return dataLength;
if(dataAvailable < 0){
return 0;
}
return dataAvailable;
}
virtual int read(){
// Check if we have data available
if(dataLength)
if(dataAvailable > 0)
{
// Get next data byte (from the start to the end)
return data[sizeof(data) - dataLength--];
return data[dataLength - dataAvailable--];
}
return -1;
}
virtual int peek(){
// Check if we have data available
if(dataLength){
return data[sizeof(data) - dataLength];
if(dataAvailable > 0){
return data[dataLength - dataAvailable];
}
return -1;
}
@ -114,27 +155,9 @@ public:
}
virtual size_t write(uint8_t *buffer, size_t size){
// TODO this will split the data into proper USB_EP_SIZE packets already
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;
return USB_Send(pluggedEndpoint | TRANSFER_RELEASE, buffer, size);
}
void SendReport(void* data, int length);
protected:
// Implementation of the PUSBListNode
int getInterface(uint8_t* interfaceCount);
@ -147,7 +170,11 @@ protected:
// Buffer pointers to hold the received data
int dataLength;
uint8_t data[RAWHID_RX_SIZE];
int dataAvailable;
uint8_t* data;
uint8_t* featureReport;
int featureLength;
};
extern RawHID_ RawHID;

View file

@ -37,6 +37,8 @@ public:
SingleNKROKeyboard_(void);
uint8_t getLeds(void);
uint8_t getProtocol(void);
virtual int send(void) final;
protected:
// Implementation of the PUSBListNode
@ -49,8 +51,6 @@ protected:
uint8_t idle;
uint8_t leds;
virtual inline int send(void) override;
};
extern SingleNKROKeyboard_ SingleNKROKeyboard;