Created
May 5, 2024 01:24
-
-
Save todbot/72689cd1a3f847785314bdcebc3c3586 to your computer and use it in GitHub Desktop.
CircuitPython midi, usb.core and max3421 blocking issues
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# demonstrate blocking of usb.core.Device.read() | |
# 4 May 2024 - @todbot and @jedgarpark | |
""" | |
This sketch demonstrates how `device.read()` blocks infinitely, which is different from established behavior. | |
The normal semantics of `device.read()` when using either `busio.UART` or `usb_midi.PortIn` | |
is that the read() does not noticably block if a `timeout` is given. | |
(Explicitly in the constructor of `busio.UART` and apparently implicitly in just how `usb_midi` works) | |
But for the `usb.core.Device` that is returned (as demo'd below), the `device.read()` blocks forever. | |
Using `asyncio` or `select` does not help with this. | |
There is a non-standard `timeout` argument to the `usb.core.Device.read()` | |
and `usb.core.Device.write()` methods, but when specifying a timeout on `.read()`, | |
an unattributed `usb.core.USBError` is thrown, instead of the expected return value of None or 0. | |
Since the exception is unattributed, there's no wayt to distinguish a read timeout | |
from a device unplug or other USB error. | |
""" | |
import time | |
import board | |
import usb | |
import max3421e | |
import adafruit_usb_host_midi | |
spi = board.SPI() | |
cs = board.D10 | |
irq = board.D9 | |
host_chip = max3421e.Max3421E(spi, chip_select=cs, irq=irq) | |
while True: | |
midi_usb_device = None | |
for device in usb.core.find(find_all=True): | |
try: | |
midi_usb_device = adafruit_usb_host_midi.MIDI(device) | |
print("Found vid/pid %04x/%04x" % (device.idVendor, device.idProduct), | |
device.manufacturer, device.product) | |
except ValueError: | |
print("bad device:", device) | |
while True: | |
print("this should print continuously") | |
time.sleep(0.1) | |
b = midi_usb_device.read(1) | |
if b: | |
print("should only print when data received:",b) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment