cancel
Showing results for 
Search instead for 
Did you mean: 

High Speed USB Split transaction. STM32F723.

NotSoMega
Associate III

Hello,

I recently tried to use a stm32 controller as an full speed USB host to communicate with low speed devices over a full speed hub. To my regret I had to figure out that the stm32 controller have issues with the Preamble PID which makes communication with low speed devices over full speed hubs almost impossible. (https://community.st.com/s/question/0D50X0000BHydBQSQZ/stm32f429-discovery-as-usb-host-problems-enumerating-lowspeed-device-over-fullspeed-hub

Since no one could help me with the preamble PID I figured to move from full speed to high speed (using the stm32f723 with integrated high speed PHY). The idea was that full and low speed devices connected to a high speed hub dont require for the host to use preamble PID. Instead the split protocol is used.

If you are going to read up about the split transaction in the usb specification you are already going to have a bad time, because it is so tricky. Combine that with ST's documentation of half a page of implemantion guide and its starting to get really tricky.

What I've done so far:

-I expanded the host library to support the hub class (works fine in high speed only enviroment).

-I initialized and enabled a host channel for Split Transaction (SPLITEN BIT, Port Number, Hub Address)

After I connect a Low Speed device to my hub which is connected to the controller I try to enumerate the device. After sending the first Setup packet with the StartSplit Token I get an ACK. I also see the Setup packet arriving on the device side. I now activate the complete Split. I would expect and ACK followed by an XFRC and CHH interrupt. Instead the communication seems to halt. What am I supposed to do? Has anyone managed to get the split protocol working?

Also the description of implementation in the f7reference manual (p. 1329) is different from the statement from one of ST employes, so what is true here? (https://community.st.com/s/question/0D50X00009Xkdgf/usb-split-transaction-in-high-speed-for-stm32f769idisco-board)

14 REPLIES 14
KPunj.1
Associate II

@NotSoMega​ Honestly, it was the same for me and control mode. For OUT transactions calling the HCD_HC_Submit_Request function twice worked fine but with IN transactions I needed to check for SOF and halt the channel between calls for it to work. I have put figuring out interrupt mode on hold and am currently working on running two USB ports simultaneously. It is only a temporary fix though. I am considering writing my own usb library in place of what ST has provided, considering third party packages like that of HCC Embedded's supposedly works. It might just have to do with the way their HAL code is written.

NotSoMega
Associate III

@KPunj.1​ Did you check the behaviour of your code when NYET is recieved? I am still trying to figure out NYET in general and especially with hal. But my guess is what happend for me with Control IN transaction was that I revieved a NYET which disturbed my state machine. I don't think HAL has implemented a routine for that. So what I did was to wait a bit for the next IN Transfer so that NYET would not occure, which solved enumeration for me for now.

(This might be just a coincidence and has nothing to do with NYET, because I am still learning High Speed USB so take this with a grain of salt)

Edit: I checked the USB doc and it says for USB Control IN Complete Split transaction you have to retry the comp split if you get a NYET. The question is now is this something we have to implement or is it handled by hardware ?

KPunj.1
Associate II

@NotSoMega​ Yes, it has basically been failing because of NYETs. I have been clearing the complete split bit every time that happens. I think what you're saying makes sense and I will try that. Thanks for the tip! I will let you know how that goes.

We will mostly have to implement it because the Complete Split is controlled from the host end.

Edit 1: I just found out that for me NYETs are only being generated in Interrupt IN mode. The USB manual says to go to the next complete split bit. I have no idea what that means, so current trying to set it to 0 and then, after a 5 ms delay back to 1.

Edit 2: I tried what I said in edit 1. It does work to an extent but I keep missing packets because of the delay, even with a 1 ms delay. I am now atleast able to receive information in interrupt mode. I will try and see what I can work on, to make the code more robust.

TWald.3
Associate

If you are still working through these issues you will find hints in the Linux driver for the STM32MP which appears to use the same Synopsys IP. The repository is at https://github.com/STMicroelectronics/linux/tree/v5.10-stm32mp/drivers/usb/dwc2/, created and managed by ST personal.

@TWald.3​ I had put this project on hold as it was working intermittently. Thank you for this, I will check it out! It'll hopefully help me iron out whatever issues are left. 🙂