Also, if this is an obvious solution, I do apologize. I have years of coding experience but this is my first project with a Qt Py board and the Arduino IDE, so it was not so obvious to me.
Goal: Use my Qt Py ESP32-S2 to emulate a USB keyboard and upon some condition (I used a special UDP packet) wakeup the PC that is attached via USB.
I was able to follow examples easy enough to emulate a keyboard, but I could not initially figure out how to execute the wakeup. I had started programming my Qt Py with Circuit Python, but upon hitting this snag and doing a little digging, I decided Circuit Python might not have everything needed to make it work. So I switched to the Arduino IDE and the arduino-esp32 core (there were instructions on how to set this up on the Qt Py board overview page).
Again, I was able to get the basic USB keyboard emulation setup, but no luck on wakeup. I then tried installing the Adafruit TinyUSB library via the IDE library manager. Although the core seemed to already include TinyUSB, the core USB classes (ex: USBHIDKeyboard) didn't seem to expose any methods to actually wake the host. The Adafruit TinyUSB classes (ex: Adafruit_USBD_Device) exposed a method called remoteWakeup(). Looked very promising but did not work.
Upon doing some investigation (Windows 10 Device Manager), found that my USB keyboard could not be selected to "Allow Device to Wake Computer". This option was greyed out. A little research informed me that this was probably because the Remote Wakeup configuration descriptor was not being applied to the USB device when created. So I went digging for a way to set this config.
I eventually traced the code back to a core USB class ESPUSB (in packages/esp32/hardware/esp32/2.0.4/cores/esp32/USB.cpp). In this file, the ESPUSB constructor creates the config descriptors upon instantiation through its initializers. This line:
Code: Select all
usb_attributes(TUSB_DESC_CONFIG_ATT_SELF_POWERED)
I eventually ended up modifying that line in the core USB.cpp file to this:
Code: Select all
usb_attributes(TUSB_DESC_CONFIG_ATT_SELF_POWERED | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP)
I'm not an expert in this SDK, but I suspect the USB gets initialized and configured right away because the USB is such an integrated function of the ESP32-S2. I also believe that since I modified this line, any USB device that I create will now show wakeup as an option to the host.
Anyway, I wouldn't call it good practice to modify core SDK files, but that was the only way I could get it to work and now it's documented for others. If you know of a better way, please feel free to add on.