Skip to content
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

Support supervisor.runtime.usb_connected, at least #711

Open
dhalbert opened this issue Sep 13, 2023 · 9 comments
Open

Support supervisor.runtime.usb_connected, at least #711

dhalbert opened this issue Sep 13, 2023 · 9 comments
Labels
enhancement New feature or request

Comments

@dhalbert
Copy link
Contributor

usb_hid is supported in a limited way in Blinka, using usb_gadget.

adafruit/Adafruit_CircuitPython_HID#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.

@eightycc
Copy link

eightycc commented Sep 15, 2023

@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?

@dhalbert
Copy link
Contributor Author

dhalbert commented Sep 15, 2023

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.

@eightycc
Copy link

eightycc commented Sep 21, 2023

@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.

@dhalbert
Copy link
Contributor Author

@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?

@eightycc
Copy link

eightycc commented Sep 21, 2023

@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.

@dhalbert
Copy link
Contributor Author

dhalbert commented Sep 21, 2023

The reason is that until usb_hid starts, there is no USB 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?

@eightycc
Copy link

eightycc commented Sep 21, 2023

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?

@dhalbert
Copy link
Contributor Author

dhalbert commented Sep 21, 2023

Not trying to give you a hard time 😆 . 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.

@eightycc
Copy link

eightycc commented Sep 21, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants