Skip to main content
KChar.1
Senior
February 17, 2022
Solved

Debugging methods for FunctionFS Usb gadget in STM32MP1: HDMI-USB C PA10 pin conflict

  • February 17, 2022
  • 5 replies
  • 8876 views

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.

This topic has been closed for replies.
Best answer by KChar.1

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

5 replies

KChar.1
KChar.1Author
Senior
February 21, 2022

UPDATE: After a bit of research I found out that in the default STM32MP157D-DK2 IOC file there is a warning when enabling USB_OTG high speed. It seems that the pin AP10 is assigned to both USB ID and HDMI_NRSET. I tested the USB gadget implementation with the HDMI disconnected and indeed works as intended. From a short research I was not able to figure out if there is a way to avoid the pin conflict by assigning a different pin to either USB or HDMI or changing the OTG configuration. Any ideas or directions will be really helpful.

Kevin HUBER
Technical Moderator
February 21, 2022

Hello @KChar.1​ ,

Since you are talking about "STM32MP157D-DK2" and that this board doesn't exist, I think your board is a STM32MP157D-DK1 right?

----------------------

When you have a pin assignment issue, there is most of the time two possibilities to find the pin that is doing the same thing than the one is conflict:

CubeMX

By using CubeMx you can see the alternative pin by pressint ctrl + left click on the pin function:

0693W00000KZymAQAT.png 

Documentation

You can check the datasheet DS12505 v5.0 from page 65:

https://www.st.com/resource/en/datasheet/stm32mp157c.pdf

Unfortunately, you will see that USB_OTG_HS_ID is only available on PA10 (page 80):

0693W00000KZyicQAD.png 

And by looking at the User Manual of the Discovery board, UM2534 rev 1.0 page 21:

0693W00000KZyjQQAT.pngPA10 is connected to HDMI_NRST.

So you can't use the PA10 PIN for the two configurations at the same time if you are using the Discovery board.

If you create your own board, you will not have this conflict.

----------------------

Regarding the "solution", CubeMx warns you that this PIN conflict is only a problem if you want to use OTG in dual role device, in host and device at the same time.

0693W00000KZymeQAD.png 

I tried multiple cables and hosts and the result is that midi data will stop arriving to the host and the MP1

If I understand correctly your setup, you don't need to be at the same time the host and the device in your example, right?

In this case, you can select "Device_Only" in CubeMx and you will not need the PA10 pin.

The PA10 pin is needed for the DT configuration example 3.3.1 and 3.3.2 of the wiki, but not for the 3.3.3 DT configuration example as high speed OTG, with Type-C connector

or 3.3.4 DT configuration example as high-speed OTG in Host or Peripheral mode, with micro-B or Type-C connector, and with VBUS and ID left unconnected

https://wiki.st.com/stm32mpu/wiki/OTG_device_tree_configuration#DT_configuration_example_as_high-speed_OTG_in_Host_or_Peripheral_mode-2C_with_micro-B_or_Type-C_connector-2C_and_with_VBUS_and_ID_left_unconnected

In the last example, you can see that dr_mode is set to "peripheral", it forces the controller in Device only mode.

Hope it helps,

Regards,

Kevin

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.NEW ! Sidekick STM32 AI agent, see here
Kevin HUBER
Technical Moderator
February 21, 2022

I advise you to also have a look at this wiki page to configure the DTS of U-Boot without the ID pin:

https://wiki.st.com/stm32mpu/wiki/How_to_configure_U-Boot_for_your_board#USB_OTG_node

Regards,

Kevin

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.NEW ! Sidekick STM32 AI agent, see here
Olivier GALLIEN
Technical Moderator
February 21, 2022

Hi @KChar.1​ ,

Just to be sure, did you already refer to https://wiki.st.com/stm32mpu/wiki/USB_overview#How_to_debug and exhaust all solutions proposed ?

Thanks

Olivier

Olivier GALLIEN In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
KChar.1
KChar.1Author
Senior
February 21, 2022

Hi @Community member​ ,

Thanks for the reply and suggestion. I did follow the How to debug article thoroughly and through usbmon logging and Wireshark on host machine I got the indication of the pin conflict. At this point I am looking for solutions to resolve the AP10 pin conflict as explained above.

Erwan SZYMANSKI
Technical Moderator
April 1, 2022

Hello @KChar.1​ 

I try to reproduce your bug from my side to make some investigations on this point.

As a starting point, I took your different device trees in order to have the same setup as yours. I confirm that USB Multicomposite Gadget is well recognized by the Linux host PC.

First, using wireshark to monitor messages, I pinged the USB interface activated on the board in loop (without HDMI connected) and the ping works well. If I stop the usb-gadget on the board, the ping is blocked (so the activity looks OK for now).

Now I have connected an HDMI screen to be it in the same situation that produces troubles from your side, but the communication looks not interrupted after 10 minutes. Could you explain how do you test your setup exactly (in term of communication), just to help me reproducing the bug ? Or maybe this situation is already supposed to make my usb-gadget down ?

Kind regards.

Erwan.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
KChar.1
KChar.1Author
Senior
April 1, 2022

Hi @Erwan SZYMANSKI​ ,

Thank so much you for looking into this! To reproduce the behaviour I am using a usb-midi gadget (the script from my original post) and alsaplayer or pure-data for generating continuous midi messages. I think that alsa is more convenient for reproducing this issue since it is coming with the wenston image.

You can download any midi file and then run it through alsa

aplaymidi -p 20:0 /home/root/miditest.mid

to find the gadget port you can use

amidi -l

On the host side I am using Midi Monitor and wireshark. The timing of the behaviour is not consistent. Some times the connection will drop after a couple of minutes and some others it can crash even after 45 minutes to an hour. When the connection is dropped I receive a URB drop request on wireshark.

Please let me know if I can provide any other information or files for making this easier.

Erwan SZYMANSKI
Technical Moderator
April 6, 2022

Hello @KChar.1​ ,

Well I think I have something very close to your setup right now. Find below my Wireshark packet when we can identify USB packet when I plug to the USB-midi gadget, and then the MIDI packets that pass through when I want to play my midi piano file.

0693W00000Lx6zqQAB.pngOn board side, I plugged an HDMI monitor, quite standard, to make some HDMI activity. Should it be enough to replicate ? Do you need to have some screen activity to make it crash ?

Rgs.

Erwan

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Kevin HUBER
Technical Moderator
June 3, 2022

Hello @KChar.1​ ,

Just a ping to know if you made some progress with the new board?

Best Regards,

Kevin

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.NEW ! Sidekick STM32 AI agent, see here
KChar.1
KChar.1AuthorBest answer
Senior
June 6, 2022

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

Kevin HUBER
Technical Moderator
June 7, 2022

Hello @KChar.1​ ,

Ok good news, thank you for having done all our requested test very quickly :).

Best Regards,

Kevin

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.NEW ! Sidekick STM32 AI agent, see here