2022-02-17 08:42 AM
Hi,
I am working on a functionFS usb gadget based on gmidi. Following the gadget_configfs.rst and using stm32_usbotg_eth_config.sh as starting point was straight forward. After writing the shell script and modifying my device tree configuration to support high-speed OTG in the usb-c port as explained in the USB device tree guide, the usb gadget loaded with no errors and it was recognised by Mac, Windows and Linux hosts as usb-midi.
USB-MIDI Shell script:
configfs="/sys/kernel/config/usb_gadget"
g=g1 #Gadget name
c=c.1 #Configuration name
d="${configfs}/${g}" #gadget path
func_midi=midi.usb0 #Midi Function declaration
#Product and Vendor for getting recognised
VENDOR_ID="0x1d6b"
PRODUCT_ID="0x0104"
#Take the serial from the MP1 and make it a serial for our USB MIDI
get_mac_address_from_serial_number(){
sha1sum /proc/device-tree/serial-number \
| fold -1 \
| sed -n '1{h;d};2{y/1235679abdef/000444888ccc/;H;d};13{g;s/\n//g;p;q};s/^/:/;N;H;d'
}
#To call the gadget
do_start() {
#Call dependacy. We are using FunctionFS so only libcomposite is needed
if [ ! -d ${configfs} ]; then #Check if dependancy is already enabled
modprobe libcomposite
if [ ! -d ${configfs} ]; then
exit 1
fi
fi
if [ -d ${d} ]; then
exit 0
fi
udc=$(ls -1 /sys/class/udc/) #Check if there is a UDC driver
if [ -z $udc ]; then
echo "No UDC driver registered"
exit 1
fi
#Create main file structure
mkdir "${d}"
echo ${VENDOR_ID} > "${d}/idVendor"
echo ${PRODUCT_ID} > "${d}/idProduct"
echo 0x0200 > "${d}/bcdUSB"
echo "0xEF" > "${d}/bDeviceClass"
echo "0x02" > "${d}/bDeviceSubClass"
echo "0x01" > "${d}/bDeviceProtocol"
echo "0x0100" > "${d}/bcdDevice"
#Sign the driver
mkdir -p "${d}/strings/0x409"
tr -d '\0' < /proc/device-tree/serial-number > "${d}/strings/0x409/serialnumber"
echo "xxxx" > "${d}/strings/0x409/manufacturer"
echo "***" > "${d}/strings/0x409/product"
# Config
mkdir -p "${d}/configs/${c}"
mkdir -p "${d}/configs/${c}/strings/0x409"
echo "Config 1: MIDI" > "${d}/configs/${c}/strings/0x409/configuration"
echo 500 > "${d}/configs/${c}/MaxPower"
echo 0xC0 > "${d}/configs/${c}/bmAttributes" # self powered device
#MIDI function configuration
mkdir -p "${d}/functions/${func_midi}"
# Set up the midi device and serial after RNDIS
ln -s "${d}/functions/${func_midi}" "${d}/configs/${c}"
echo "${udc}" > "${d}/UDC" #Enable the driver
sleep 0.2 # Wait a bit
}
#To eject the gadget
do_stop() {
echo "" > "${d}/UDC" #Empty the UDC
#Delete all contents based on their priorities
rm -f "${d}/os_desc/${c}"
[ -d "${d}/configs/${c}/${func_midi}" ] &&rm -f "${d}/configs/${c}/${func_midi}"
[ -d "${d}/strings/0x409/" ] && rmdir "${d}/strings/0x409/"
[ -d "${d}/configs/${c}/strings/0x409" ] && rmdir "${d}/configs/${c}/strings/0x409"
[ -d "${d}/configs/${c}" ] && rmdir "${d}/configs/${c}"
[ -d "${d}/functions/${func_midi}" ] && rmdir "${d}/functions/${func_midi}"
[ -d "${d}" ] && rmdir "${d}"
}
case $1 in
start)
echo "Starting midi-usb gadget"
do_start $2
;;
stop)
echo "Stoping midi-usb gadget"
do_stop
;;
*)
echo "Usage: $0 (stop | start)"
;;
esac
The issue is that every few minutes the host stops sending and receiving messages. I tried multiple cables and hosts and the result is that midi data will stop arriving to the host and the MP1 in the same time, after a couple of minutes. If I reset the usb cable or stop and start the usb gadget data will flow again for a similar period of time.
In order to debug this issue I used usbmon on the MP1 and wireshark on a host Mac. On the host mac I could see that when the driver freezes it receives a URB with an unknown request and then a URB with an abort request. After these two messages no midi messages can go in or out but the device is still seen as a connected usb-midi device on the host.
Trying to understand why this happens I looked at f_midi.c. There I could see that an abort URB is send when hardware forces ep reset.
/* this endpoint is normally active while we're configured */
case -ECONNABORTED: /* hardware forced ep reset */
case -ECONNRESET: /* request dequeued */
case -ESHUTDOWN: /* disconnect from host */
At this point I am looking for ways to debug why the hardware forces ep reset and when but I can not find a way to debug this. Any ideas or points will be highly appreciated.
Solved! Go to Solution.
2022-04-08 03:48 AM
@KChar.1 ,
Is it possible to give me the exact entire reference of your board ?
Thanx !
Erwan.
2022-04-08 04:33 AM
@Erwan SZYMANSKI ,
Sure my full board reference is: MB1272-DK1-C02 A202500219
Based on your setup and results I started thinking that could be an issue with my board specifically or my monitor.
I ordered another identical board to test it out and do some more tests with different monitors next week. I will keep you updated on that.
Thanks again for your great work! Really appreciated!
2022-04-08 04:40 AM
@KChar.1 ,
Thank you for your quick reply, we strongly appreciate your feedback too.
Do not hesitate to let us know when you will have more results with your new board, and your other monitors.
Have a nice day.
Erwan.
2022-04-08 04:42 AM
For sure, I will keep you posted. Please keep me updated in case that you figure any potential issue sources from the reference board too.
Have a great day too :)
2022-04-28 06:56 AM
Hello @KChar.1 ,
Do you have any update concerning your tests ?
Best regards.
Erwan.
2022-06-03 09:03 AM
Hello @KChar.1 ,
Just a ping to know if you made some progress with the new board?
Best Regards,
Kevin
2022-06-06 07:09 AM
Hi @Kevin HUBER ,
My sincere apologies for my very late response. I had some issues with getting a D-DK1 board in my hands. A few days ago I decided to get an F-DK2 board and I did a few tests today. After almost 5 hours I was not able to reproduce the issue. At the moment I can not confirm if this was a model specific or board specific issue. My old D-DK1 board still has the same behaviour so I will proceed with the F board.
Thank you very much for your help!
All the best,
Kyr
2022-06-07 08:03 AM
Hello @KChar.1 ,
Ok good news, thank you for having done all our requested test very quickly :).
Best Regards,
Kevin