Open
Description
Board
ESP32-S3
Device Description
DevKitC
Hardware Configuration
Currently nothing else connected to any pins
Version
latest development Release Candidate (RC-X)
IDE Name
CLion with PlatformIO Plugin
Operating System
Windows and Linux
Flash frequency
40 MHz
PSRAM enabled
yes
Upload speed
115200
Description
I'm trying to use the example sketch USBVendor.ino from the examples folder. Everything works good, I can connect with the demo HTML page and communicate both ways and it's good. But the vendorRequestCallback method never seems to be hit. None of the Serial logs from it ever appear in the console.
Sketch
#ifndef ARDUINO_USB_MODE
#error This ESP32 SoC has no Native USB interface
#elif ARDUINO_USB_MODE == 1
#warning This sketch should be used when USB is in OTG mode
void setup() {}
void loop() {}
#else
#include "USB.h"
#include "USBVendor.h"
USBVendor Vendor;
const int buttonPin = 0;
//CDC Control Requests
#define REQUEST_SET_LINE_CODING 0x20
#define REQUEST_GET_LINE_CODING 0x21
#define REQUEST_SET_CONTROL_LINE_STATE 0x22
//CDC Line Coding Control Request Structure
typedef struct __attribute__((packed)) {
uint32_t bit_rate;
uint8_t stop_bits; //0: 1 stop bit, 1: 1.5 stop bits, 2: 2 stop bits
uint8_t parity; //0: None, 1: Odd, 2: Even, 3: Mark, 4: Space
uint8_t data_bits; //5, 6, 7, 8 or 16
} request_line_coding_t;
static request_line_coding_t vendor_line_coding = {9600, 0, 0, 8};
// Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
static uint8_t vendor_line_state = 0;
//USB and Vendor events
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: Serial.println("USB PLUGGED"); break;
case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB UNPLUGGED"); break;
case ARDUINO_USB_SUSPEND_EVENT: Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en); break;
case ARDUINO_USB_RESUME_EVENT: Serial.println("USB RESUMED"); break;
default: break;
}
} else if (event_base == ARDUINO_USB_VENDOR_EVENTS) {
arduino_usb_vendor_event_data_t *data = (arduino_usb_vendor_event_data_t *)event_data;
switch (event_id) {
case ARDUINO_USB_VENDOR_DATA_EVENT:
Serial.printf("Vendor RX: len:%u\n", data->data.len);
for (uint16_t i = 0; i < data->data.len; i++) {
Serial.write(Vendor.read());
}
Serial.println();
break;
default: break;
}
}
}
static const char *strRequestDirections[] = {"OUT", "IN"};
static const char *strRequestTypes[] = {"STANDARD", "CLASS", "VENDOR", "INVALID"};
static const char *strRequestRecipients[] = {"DEVICE", "INTERFACE", "ENDPOINT", "OTHER"};
static const char *strRequestStages[] = {"SETUP", "DATA", "ACK"};
//Handle USB requests to the vendor interface
bool vendorRequestCallback(uint8_t rhport, uint8_t requestStage, arduino_usb_control_request_t const *request) {
Serial.printf(
"Vendor Request: Stage: %5s, Direction: %3s, Type: %8s, Recipient: %9s, bRequest: 0x%02x, wValue: 0x%04x, wIndex: %u, wLength: %u\n",
strRequestStages[requestStage], strRequestDirections[request->bmRequestDirection], strRequestTypes[request->bmRequestType],
strRequestRecipients[request->bmRequestRecipient], request->bRequest, request->wValue, request->wIndex, request->wLength
);
bool result = false;
if (request->bmRequestDirection == REQUEST_DIRECTION_OUT && request->bmRequestType == REQUEST_TYPE_STANDARD
&& request->bmRequestRecipient == REQUEST_RECIPIENT_INTERFACE && request->bRequest == 0x0b) {
if (requestStage == REQUEST_STAGE_SETUP) {
// response with status OK
result = Vendor.sendResponse(rhport, request);
} else {
result = true;
}
} else
//Implement CDC Control Requests
if (request->bmRequestType == REQUEST_TYPE_CLASS && request->bmRequestRecipient == REQUEST_RECIPIENT_DEVICE) {
switch (request->bRequest) {
case REQUEST_SET_LINE_CODING: //0x20
// Accept only direction OUT with data size 7
if (request->wLength != sizeof(request_line_coding_t) || request->bmRequestDirection != REQUEST_DIRECTION_OUT) {
break;
}
if (requestStage == REQUEST_STAGE_SETUP) {
//Send the response in setup stage (it will write the data to vendor_line_coding in the DATA stage)
result = Vendor.sendResponse(rhport, request, (void *)&vendor_line_coding, sizeof(request_line_coding_t));
} else if (requestStage == REQUEST_STAGE_ACK) {
//In the ACK stage the response is complete
Serial.printf(
"Vendor Line Coding: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", vendor_line_coding.bit_rate, vendor_line_coding.data_bits,
vendor_line_coding.stop_bits, vendor_line_coding.parity
);
}
result = true;
break;
case REQUEST_GET_LINE_CODING: //0x21
// Accept only direction IN with data size 7
if (request->wLength != sizeof(request_line_coding_t) || request->bmRequestDirection != REQUEST_DIRECTION_IN) {
break;
}
if (requestStage == REQUEST_STAGE_SETUP) {
//Send the response in setup stage (it will write the data to vendor_line_coding in the DATA stage)
result = Vendor.sendResponse(rhport, request, (void *)&vendor_line_coding, sizeof(request_line_coding_t));
}
result = true;
break;
case REQUEST_SET_CONTROL_LINE_STATE: //0x22
// Accept only direction OUT with data size 0
if (request->wLength != 0 || request->bmRequestDirection != REQUEST_DIRECTION_OUT) {
break;
}
if (requestStage == REQUEST_STAGE_SETUP) {
//Send the response in setup stage
vendor_line_state = request->wValue;
result = Vendor.sendResponse(rhport, request);
} else if (requestStage == REQUEST_STAGE_ACK) {
//In the ACK stage the response is complete
bool dtr = (vendor_line_state & 1) != 0;
bool rts = (vendor_line_state & 2) != 0;
Serial.printf("Vendor Line State: dtr: %u, rts: %u\n", dtr, rts);
}
result = true;
break;
default:
// stall unknown request
break;
}
}
return result;
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(115200);
Serial.setDebugOutput(true);
Vendor.onEvent(usbEventCallback);
Vendor.onRequest(vendorRequestCallback);
Vendor.begin();
USB.onEvent(usbEventCallback);
USB.webUSB(true);
// Set the URL for your WebUSB landing page
USB.webUSBURL("https://docs.espressif.com/projects/arduino-esp32/en/latest/_static/webusb.html");
USB.begin();
}
void loop() {
static int previousButtonState = HIGH;
int buttonState = digitalRead(buttonPin);
if (buttonState != previousButtonState) {
previousButtonState = buttonState;
if (buttonState == LOW) {
Serial.println("Button Pressed");
Vendor.println("Button Pressed");
Vendor.flush(); //Without flushing the data will only be sent when the buffer is full (64 bytes)
} else {
Serial.println("Button Released");
Vendor.println("Button Released");
Vendor.flush(); //Without flushing the data will only be sent when the buffer is full (64 bytes)
}
delay(100);
}
while (Serial.available()) {
size_t l = Serial.available();
uint8_t b[l];
l = Serial.read(b, l);
Vendor.write(b, l);
Vendor.flush(); //Without flushing the data will only be sent when the buffer is full (64 bytes)
}
}
#endif /* ARDUINO_USB_MODE */
Debug Message
I am not getting output from the method mentioned above, that's the problem.
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.