Open dhalbert opened 1 year ago
@dhalbert I've looked over Blinka HID support and my understanding is that it is implemented only for boards running Linux. Before I go any further, do you know if USB ports on any of these Raspberry Pi boards will work for testing: Pi 4, Pi Zero, Pi Zero 2? The USB ports on at least the Zeroes are suitable for use as devices. So, do I understand the limitation of Blinka HID support correctly?
Raspberry Pi Zeros definitely support OTG (USB gadget). RPI 4 does, but it appears to be only through the USB-C port. RPi 3 and older do not.
@dhalbert The good news is that Adafruit_CircuitPython_HID
works fine with the existing 1 second timeout or with no timeout at all. USB gadget
allows instantiation and initialization of a HID device with no host connection. We get into the weeds when attempting to use a HID device with no connection. For example, keyboard.press()
fails with:
Traceback (most recent call last):
File "/home/rabeles/hid_kbd_demo.py", line 62, in <module>
keyboard.press(control_key, key) # "Press"...
File "/home/rabeles/.local/lib/python3.9/site-packages/adafruit_hid/keyboard.py", line 96, in press
self._keyboard_device.send_report(self.report)
File "/home/rabeles/.local/lib/python3.9/site-packages/usb_hid.py", line 66, in send_report
fd.write(report)
BrokenPipeError: [Errno 108] Cannot send after transport endpoint shutdown
We could wrap fd
calls in Blinka's usb_hid
with a try
and throw a more informative error? For a use case where keeping the HID device alive across disconnects/connects is important, the user code could catch
and retry. This would push the fail/retry decision to user code.
@eightycc You could wrap the calls, but the user code is still going to need to do something, as you point out. But even if you can create the device when it's not plugged in, is there some way to test whether an enumeration happened with a USB host so we can implement .usb_connected
?
@dhalbert The best we can do is implement a .usb_connected
inside usb_hid
. The reason is that until usb_hid
starts, there is no USB gadget
filesystem that we can look into and libcomposite
is just hanging there quietly waiting for one to get built.
I think we'll still need some wrapping. It's not uncommon for a USB HID device to get hot plugged/unplugged.
The reason is that until
usb_hid
starts, there is noUSB gadget
filesystem
So if there is no gadget tree in the fileystem, then could supervisor.runtime.usb_connected
check for its existence an d then confidently return false if there isn't one? And if there is one, then it could check something there?
Believe me, I'm not trying to belabor this issue, just trying to think it through. Checking for the existence of the gadget fs is certainly feasible, getting it to tell us the state of the host connection short of pushing a null report is problematical. I'm looking at libcomposite
in the Linux kernel source now to see what it exposes. Assuming there is something there that can be queried, there could be more than one HID device represented in the filesystem. Which one would we query?
Not trying to give you a hard time :laughing: . I haven't looked at this stuff at all, and it can be quite arcane. Trying to find out things about USB device was also arcane when I had to look at that. Pushing a null report is device-specific, and I was glad we got rid of that in the latest release.
I haven't looked at this stuff at all, and it can be quite arcane.
Yes, it really is. The USB designers must have had access to some really good herb.
A cursory look at drivers/usb/gadget
in the Linux kernel source tree leads me to think there is a way to get what we need. It's not going to win any prizes for clarity as it involves exchanging binary reports.
I don't want to burn up too many of your cycles on this, and I'm anxious to look into a more interesting issue, so let me put this aside for a few days (I don't think there's any urgency) and I'll get back to it later.
usb_hid
is supported in a limited way in Blinka, usingusb_gadget
.https://github.com/adafruit/Adafruit_CircuitPython_HID/pull/118 would like to test for USB enumeration having happened. Right now there is no support at all for
supervisor
in Blinka. But it would be nice to add some support for the USB-related supervisor operations.