Skip to content

Implement USB HID Device Support for ESP32-S2 #5538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ set(LIBRARY_SRCS
libraries/Ticker/src/Ticker.cpp
libraries/Update/src/Updater.cpp
libraries/Update/src/HttpsOTAUpdate.cpp
libraries/USB/src/USBHID.cpp
libraries/USB/src/USBHIDMouse.cpp
libraries/USB/src/USBHIDKeyboard.cpp
libraries/USB/src/USBHIDGamepad.cpp
libraries/USB/src/USBHIDConsumerControl.cpp
libraries/USB/src/USBHIDSystemControl.cpp
libraries/USB/src/USBHIDVendor.cpp
libraries/WebServer/src/WebServer.cpp
libraries/WebServer/src/Parsing.cpp
libraries/WebServer/src/detail/mimetable.cpp
Expand Down
Empty file.
Empty file.
213 changes: 213 additions & 0 deletions libraries/USB/examples/CompositeDevice/CompositeDevice.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
#include "USB.h"
#include "USBHIDMouse.h"
#include "USBHIDKeyboard.h"
#include "USBHIDGamepad.h"
#include "USBHIDConsumerControl.h"
#include "USBHIDSystemControl.h"
#include "USBHIDVendor.h"
#include "FirmwareMSC.h"

#if !ARDUINO_USB_MSC_ON_BOOT
FirmwareMSC MSC_Update;
#endif
#if ARDUINO_USB_CDC_ON_BOOT
#define HWSerial Serial0
#define USBSerial Serial
#else
#define HWSerial Serial
USBCDC USBSerial;
#endif

USBHID HID;
USBHIDKeyboard Keyboard;
USBHIDMouse Mouse;
USBHIDGamepad Gamepad;
USBHIDConsumerControl ConsumerControl;
USBHIDSystemControl SystemControl;
USBHIDVendor Vendor;

const int buttonPin = 0;
int previousButtonState = HIGH;

static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
if(event_base == ARDUINO_USB_EVENTS){
arduino_usb_event_data_t * data = (arduino_usb_event_data_t*)event_data;
switch (event_id){
case ARDUINO_USB_STARTED_EVENT:
HWSerial.println("USB PLUGGED");
break;
case ARDUINO_USB_STOPPED_EVENT:
HWSerial.println("USB UNPLUGGED");
break;
case ARDUINO_USB_SUSPEND_EVENT:
HWSerial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en);
break;
case ARDUINO_USB_RESUME_EVENT:
HWSerial.println("USB RESUMED");
break;

default:
break;
}
} else if(event_base == ARDUINO_USB_CDC_EVENTS){
arduino_usb_cdc_event_data_t * data = (arduino_usb_cdc_event_data_t*)event_data;
switch (event_id){
case ARDUINO_USB_CDC_CONNECTED_EVENT:
HWSerial.println("CDC CONNECTED");
break;
case ARDUINO_USB_CDC_DISCONNECTED_EVENT:
HWSerial.println("CDC DISCONNECTED");
break;
case ARDUINO_USB_CDC_LINE_STATE_EVENT:
HWSerial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts);
break;
case ARDUINO_USB_CDC_LINE_CODING_EVENT:
HWSerial.printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity);
break;
case ARDUINO_USB_CDC_RX_EVENT:
HWSerial.printf("CDC RX [%u]:", data->rx.len);
{
uint8_t buf[data->rx.len];
size_t len = USBSerial.read(buf, data->rx.len);
HWSerial.write(buf, len);
}
HWSerial.println();
break;

default:
break;
}
} else if(event_base == ARDUINO_FIRMWARE_MSC_EVENTS){
arduino_firmware_msc_event_data_t * data = (arduino_firmware_msc_event_data_t*)event_data;
switch (event_id){
case ARDUINO_FIRMWARE_MSC_START_EVENT:
HWSerial.println("MSC Update Start");
break;
case ARDUINO_FIRMWARE_MSC_WRITE_EVENT:
//HWSerial.printf("MSC Update Write %u bytes at offset %u\n", data->write.size, data->write.offset);
HWSerial.print(".");
break;
case ARDUINO_FIRMWARE_MSC_END_EVENT:
HWSerial.printf("\nMSC Update End: %u bytes\n", data->end.size);
break;
case ARDUINO_FIRMWARE_MSC_ERROR_EVENT:
HWSerial.printf("MSC Update ERROR! Progress: %u bytes\n", data->error.size);
break;
case ARDUINO_FIRMWARE_MSC_POWER_EVENT:
HWSerial.printf("MSC Update Power: power: %u, start: %u, eject: %u\n", data->power.power_condition, data->power.start, data->power.load_eject);
break;

default:
break;
}
} else if(event_base == ARDUINO_USB_HID_EVENTS){
arduino_usb_hid_event_data_t * data = (arduino_usb_hid_event_data_t*)event_data;
switch (event_id){
case ARDUINO_USB_HID_SET_PROTOCOL_EVENT:
HWSerial.printf("HID SET PROTOCOL: %s\n", data->set_protocol.protocol?"REPORT":"BOOT");
break;
case ARDUINO_USB_HID_SET_IDLE_EVENT:
HWSerial.printf("HID SET IDLE: %u\n", data->set_idle.idle_rate);
break;

default:
break;
}
} else if(event_base == ARDUINO_USB_HID_KEYBOARD_EVENTS){
arduino_usb_hid_keyboard_event_data_t * data = (arduino_usb_hid_keyboard_event_data_t*)event_data;
switch (event_id){
case ARDUINO_USB_HID_KEYBOARD_LED_EVENT:
HWSerial.printf("HID KEYBOARD LED: NumLock:%u, CapsLock:%u, ScrollLock:%u\n", data->numlock, data->capslock, data->scrolllock);
break;

default:
break;
}
} else if(event_base == ARDUINO_USB_HID_VENDOR_EVENTS){
arduino_usb_hid_vendor_event_data_t * data = (arduino_usb_hid_vendor_event_data_t*)event_data;
switch (event_id){
case ARDUINO_USB_HID_VENDOR_GET_FEATURE_EVENT:
HWSerial.printf("HID VENDOR GET FEATURE: len:%u\n", data->len);
for(uint16_t i=0; i<data->len; i++){
HWSerial.write(data->buffer[i]?data->buffer[i]:'.');
}
HWSerial.println();
break;
case ARDUINO_USB_HID_VENDOR_SET_FEATURE_EVENT:
HWSerial.printf("HID VENDOR SET FEATURE: len:%u\n", data->len);
for(uint16_t i=0; i<data->len; i++){
HWSerial.write(data->buffer[i]?data->buffer[i]:'.');
}
HWSerial.println();
break;
case ARDUINO_USB_HID_VENDOR_OUTPUT_EVENT:
HWSerial.printf("HID VENDOR OUTPUT: len:%u\n", data->len);
for(uint16_t i=0; i<data->len; i++){
HWSerial.write(Vendor.read());
}
HWSerial.println();
break;

default:
break;
}
}
}

void setup() {
HWSerial.begin(115200);
HWSerial.setDebugOutput(true);

USB.onEvent(usbEventCallback);
USBSerial.onEvent(usbEventCallback);
MSC_Update.onEvent(usbEventCallback);
HID.onEvent(usbEventCallback);
Keyboard.onEvent(usbEventCallback);
Vendor.onEvent(usbEventCallback);

USBSerial.begin();
MSC_Update.begin();
Vendor.begin();
Mouse.begin();
Keyboard.begin();
Gamepad.begin();
ConsumerControl.begin();
SystemControl.begin();
USB.begin();
}

void loop() {
int buttonState = digitalRead(buttonPin);
if (HID.ready() && buttonState != previousButtonState) {
previousButtonState = buttonState;
if (buttonState == LOW) {
HWSerial.println("Button Pressed");
USBSerial.println("Button Pressed");
Vendor.println("Button Pressed");
Mouse.move(10,10);
Keyboard.pressRaw(HID_KEY_CAPS_LOCK);
Gamepad.leftStick(100,100);
ConsumerControl.press(CONSUMER_CONTROL_VOLUME_INCREMENT);
//SystemControl.press(SYSTEM_CONTROL_POWER_OFF);
} else {
Keyboard.releaseRaw(HID_KEY_CAPS_LOCK);
Gamepad.leftStick(0,0);
ConsumerControl.release();
//SystemControl.release();
Vendor.println("Button Released");
USBSerial.println("Button Released");
HWSerial.println("Button Released");
}
delay(100);
}

while(HWSerial.available()){
size_t l = HWSerial.available();
uint8_t b[l];
l = HWSerial.read(b, l);
USBSerial.write(b, l);
if(HID.ready()){
Vendor.write(b,l);
}
}
}
Empty file.
Empty file.
20 changes: 20 additions & 0 deletions libraries/USB/examples/ConsumerControl/ConsumerControl.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "USBHIDConsumerControl.h"
USBHIDConsumerControl ConsumerControl;

const int buttonPin = 0;
int previousButtonState = HIGH;

void setup() {
pinMode(buttonPin, INPUT_PULLUP);
ConsumerControl.begin();
USB.begin();
}

void loop() {
int buttonState = digitalRead(buttonPin);
if ((buttonState != previousButtonState) && (buttonState == LOW)) {
ConsumerControl.press(CONSUMER_CONTROL_VOLUME_INCREMENT);
ConsumerControl.release();
}
previousButtonState = buttonState;
}
Empty file.
Empty file.
79 changes: 79 additions & 0 deletions libraries/USB/examples/CustomHIDDevice/CustomHIDDevice.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include "USB.h"
#include "USBHID.h"
USBHID HID;

static const uint8_t report_descriptor[] = { // 8 axis
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x04, // Usage (Joystick)
0xa1, 0x01, // Collection (Application)
0xa1, 0x00, // Collection (Physical)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x09, 0x35, // Usage (Rz)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7f, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0xC0, // End Collection
};

class CustomHIDDevice: public USBHIDDevice {
public:
CustomHIDDevice(void){
static bool initialized = false;
if(!initialized){
initialized = true;
HID.addDevice(this, sizeof(report_descriptor));
}
}

void begin(void){
HID.begin();
}

uint16_t _onGetDescriptor(uint8_t* buffer){
memcpy(buffer, report_descriptor, sizeof(report_descriptor));
return sizeof(report_descriptor);
}

bool send(uint8_t * value){
return HID.SendReport(0, value, 8);
}
};

CustomHIDDevice Device;

const int buttonPin = 0;
int previousButtonState = HIGH;
uint8_t axis[8];

void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
pinMode(buttonPin, INPUT_PULLUP);
Device.begin();
USB.begin();
}

void loop() {
int buttonState = digitalRead(buttonPin);
if (HID.ready() && buttonState != previousButtonState) {
previousButtonState = buttonState;
if (buttonState == LOW) {
Serial.println("Button Pressed");
axis[0] = random() & 0xFF;
Device.send(axis);
} else {
Serial.println("Button Released");
}
delay(100);
}
}
Empty file.
Empty file.
20 changes: 20 additions & 0 deletions libraries/USB/examples/Gamepad/Gamepad.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "USBHIDGamepad.h"
USBHIDGamepad Gamepad;

const int buttonPin = 0;
int previousButtonState = HIGH;

void setup() {
pinMode(buttonPin, INPUT_PULLUP);
Gamepad.begin();
USB.begin();
}

void loop() {
int buttonState = digitalRead(buttonPin);
if ((buttonState != previousButtonState) && (buttonState == LOW)) {
Gamepad.pressButton(BUTTON_START);
Gamepad.releaseButton(BUTTON_START);
}
previousButtonState = buttonState;
}
Empty file.
Empty file.
Loading