You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# A simplified (no UART output) version of # examples/usb_host_midi_simpletest_rp2040usbfeather.py# SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries## SPDX-License-Identifier: Unlicense# pylint: disable=unused-importimportusb.coreimportadafruit_midi# from adafruit_midi.note_on import NoteOn# from adafruit_midi.note_off import NoteOff# from adafruit_midi.control_change import ControlChange# from adafruit_midi.pitch_bend import PitchBendimportadafruit_usb_host_midiprint("Looking for midi device")
raw_midi=Nonewhileraw_midiisNone:
fordeviceinusb.core.find(find_all=True):
try:
raw_midi=adafruit_usb_host_midi.MIDI(device)
print("Found", hex(device.idVendor), hex(device.idProduct))
exceptValueError:
continue# output not needed for this demo/test# # This setup is to use TX pin on Feather RP2040 with USB Type A Host as MIDI out# # You must wire up the needed resistors and jack yourself# # This will forward all MIDI messages from the device to hardware uart MIDI# uart = busio.UART(rx=board.RX, tx=board.TX, baudrate=31250, timeout=0.001)midi_device=adafruit_midi.MIDI(midi_in=raw_midi, in_channel=0)
# midi_uart = adafruit_midi.MIDI(midi_out=uart, midi_in=uart)whileTrue:
msg=midi_device.receive()
ifmsg:
print("midi msg:", msg)
# midi_uart.send(msg)
Behavior
Run the code with a Roland FP30X MIDI keyboard attached and you get the following output, but which never returns from the constructor to adafruit_usb_host_midi.MIDI:
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Looking for midi device
Found 0x582 0x29c
CTRL-C gets the following:
Traceback (most recent call last):
File "code.py", line 7, in
File "usb_host_midi_simpletest_rp2040usbfeather.py", line 40, in
File "adafruit_midi/init.py", line 128, in receive
File "/lib/adafruit_usb_host_midi.py", line 99, in read
KeyboardInterrupt:
Code done running.
Press any key to enter the REPL. Use CTRL-D to reload.
Description
This error happens intermittently, along with succeeding perhaps 50% of the time. (It also gets a "usb.core.USBError: No configuration set" error, which is something else but perhaps a clue as to why nulls are being returned that cause the problem at hand.)
Here are 3 runs:
Success:
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Looking for midi device
Found 0x582 0x29c
midi msg: NoteOn(note=84, velocity=43, channel=0)
midi msg: NoteOn(note=86, velocity=42, channel=0)
...
Failure with usb**.core.USBError: No configuration set** error:
code.py output:
Looking for midi device
Found 0x582 0x29c
Traceback (most recent call last):
File "code.py", line 7, in
File "usb_host_midi_simpletest_rp2040usbfeather.py", line 40, in
File "adafruit_midi/init.py", line 128, in receive
File "/lib/adafruit_usb_host_midi.py", line 99, in read
usb.core.USBError: No configuration set
Code done running.
Failure but with my added null catcher:
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Looking for midi device
Traceback (most recent call last):
File "code.py", line 7, in
File "usb_host_midi_simpletest_rp2040usbfeather.py", line 24, in
File "/lib/adafruit_usb_host_midi.py", line 55, in init
Exception: adafruit_usb_host_descriptors has a null!
Code done running.
Additional information
If you make the following change to adafruit_usb_host_midi.py (starting at line 53, duplicated here)
descriptor_len = config_descriptor[i]
if descriptor_len == 0: # cran
raise Exception("adafruit_usb_host_descriptors has a null!") # cran
you will see that previously the constructor got stuck in an infinite loop because config_descriptor[0] (as well as all the others!) has a value of 0, and the code i += descriptor_len
at the end of the loop here never increments.
I'm not sure what the best way to handle this null value from config_descriptor is, but this works for me.
The text was updated successfully, but these errors were encountered:
Can you print out what the library is getting from the core? I suspect it is returning bad data and the library can't handle it. The fix would be to correct the core.
Can you print out what the library is getting from the core? I suspect it is returning bad data and the library can't handle it. The fix would be to correct the core.
The usb_host_descriptor is indeed a bunch of nulls - zeros. I can print that for ya if you want. :-) So yes, it's returning garbage. But it does seem like a Bad Thing for that iterator to assume it's nonzero. I realize one can only do so much error checking, but this seems like an easy one.
My project - and anyone else who connects to a similar MIDI device - is going to have to use patched code if this isn't fixed. Which yes, maybe usb_host_descriptor needs to have some way of saying "I got bad USB data", but we still need an error handler down the line, no?
CircuitPython version
Code/REPL
Behavior
Run the code with a Roland FP30X MIDI keyboard attached and you get the following output, but which never returns from the constructor to adafruit_usb_host_midi.MIDI:
CTRL-C gets the following:
Description
This error happens intermittently, along with succeeding perhaps 50% of the time. (It also gets a "usb.core.USBError: No configuration set" error, which is something else but perhaps a clue as to why nulls are being returned that cause the problem at hand.)
Here are 3 runs:
Success:
Failure with usb**.core.USBError: No configuration set** error:
Failure but with my added null catcher:
Additional information
If you make the following change to adafruit_usb_host_midi.py (starting at line 53, duplicated here)
you will see that previously the constructor got stuck in an infinite loop because config_descriptor[0] (as well as all the others!) has a value of 0, and the code
i += descriptor_len
at the end of the loop here never increments.
I'm not sure what the best way to handle this null value from config_descriptor is, but this works for me.
The text was updated successfully, but these errors were encountered: