espressif/esp32-arduino-lib-builder

ESP32-S3 - Broken USB Keyboard LEDs events (Caps Lock, Num Lock, etc.)

TheCrypt0 opened this issue · 1 comments

NOTE: I already posted this issue on arduino-esp32 but since the TinyUSB driver integration happens in this repo, I figured this could be reposted here and it might spark an interesting conversation and maybe some ideas for a workaround. :)

I'm currently building a USB keyboard using the ESP32-S3 and when upgrading to the latest Arduino Core (3.0.0-3.0.4), the reporting of LEDs (Caps Lock, Num Lock, etc.) did not happen anymore, even though the typing works. Downgrading to 2.0.13 makes the code work again.

I attached a minimum reproducible example with the expected output when the devkit is connected to a PC.

Is this is something already known or do you know any workaround I could implement?

Sketch

#include <USB.h>
#include <USBCDC.h>
#include <USBHIDKeyboard.h>

USBHIDKeyboard m_keyboard;
USBCDC         m_serial;
ESPUSB*        m_usb;

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:
        m_serial.println("USB PLUGGED");
        break;
      case ARDUINO_USB_STOPPED_EVENT:
        m_serial.println("USB UNPLUGGED");
        break;
      case ARDUINO_USB_SUSPEND_EVENT:
        m_serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n",
                        data->suspend.remote_wakeup_en);
        break;
      case ARDUINO_USB_RESUME_EVENT:
        m_serial.println("USB RESUMED");
        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:
        m_serial.printf("HID SET PROTOCOL: %s\n",
                        data->set_protocol.protocol ? "REPORT" : "BOOT");
        break;
      case ARDUINO_USB_HID_SET_IDLE_EVENT:
        m_serial.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:
        m_serial.printf(
          "HID KEYBOARD LED: NumLock:%u, CapsLock:%u, ScrollLock:%u\n",
          data->numlock,
          data->capslock,
          data->scrolllock);
        break;

      default:
        break;
    }
  }
}

void
setup()
{
  // put your setup code here, to run once:
  // m_serial.begin(115200);

  USB.onEvent(usbEventCallback);
  m_keyboard.onEvent(usbEventCallback);
  m_serial.onEvent(usbEventCallback);

  m_keyboard.begin();
  m_serial.begin(115200);
  // m_serial.enableReboot(false);

  m_usb = &USB; // get the USB object
  m_usb->manufacturerName("TEST MAN");
  m_usb->productName("TEST DEV");

  m_usb->begin();
}

void
loop()
{
  // put your main code here, to run repeatedly:
  m_serial.println("Hello World!");

  delay(1000);
  m_keyboard.press(KEY_CAPS_LOCK);
  delay(1000);
  m_keyboard.release(KEY_CAPS_LOCK);

  delay(1000);
}

Debug Message

--- CORRECT OUTPUT WITH ARDUINO ESP32 VER 2.0.13 ---
KEYBOARD LED: NumLock:0, CapsLock:1, ScrollLock:0
Hello World!
HID KEYBOARD LED: NumLock:0, CapsLock:0, ScrollLock:0
Hello World!
HID KEYBOARD LED: NumLock:0, CapsLock:1, ScrollLock:0
Hello World!
etc...
--- OUTPUT WITH ARDUINO ESP32 VER 3.0.0 and 3.0.4 ---
Hello World!
Hello World!
Hello World!
etc...

Board

ESP32-S3

Device Description

Custom ESP32-S3 keyboard but it should work on any ESP32-S3 devkit with USB connection.

Version

v3.0.4

IDE Name

Arduino IDE

Operating System

macOS 14.6.1

Flash frequency

80MHz

PSRAM enabled

no

Upload speed

921600

here is actually a small portion of it all. Mainly config and small changes to the low level driver. Let's continue in Arduino :)