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
QI.1
Associate

@NotSoMega​ I'm currently trying to implement split transactions myself and what I found is that after setting COMPLSPLT bit you need to send the corresponding token again (in your case, Setup token) to actually generate the Complete Split token on the line. Then you will receive expected interrupts, and after those you need to unset COMPLSPLT and proceed normally.

That said, I haven't been able to fully implement split transactions yet, since I am now struggling with multiple-packet IN transactions, so my understating of the process may be incomplete or plain wrong.

NotSoMega
Associate III

thank you @QI.1​ for your input. I apologize for the late answer, but I didn't have much time recently to work on this project.

Your answer helped me to understand the process of implementing split transactions better. I managed to issue a GET_DESCRIPTOR request and recieve the first 8 bytes of the device descriptors (1st step in Hal for enumeration). This transaction looks perfectly fine in my sniffing tool. (So there is hope!)

I think I am now at the same problem that you described. In order to get the complete device descriptor I have to issue 3 in requests. (2x 8 bytes and 1x 2 bytes) . This is also looking good on the low-speed-device side. But on the host side the RXQLV_IRQ gets only triggered twice. This means I'm not recieving the 2nd In Data (8 bytes). Have you had any success in this?

Edit:

By hardcoding the data IN reports that are not detected by the host I managed to completely enumerate the mouse up to the point where I want to recieve the interrupt IN data. The mouse is already putting the data on the bus (I can see it with my sniffing tool), but I did not had any success in recieving the interrupt in data whatsoever. Maybe you also have an idea what the issue could be here.

Edit 2:

Solution to recieving only every second data packet: Since I'm now manually transmitting every IN -token I also have to toggle the DATA PID manually. I now recieve every Data IN as expected (control transfer only)

QI.1
Associate

@NotSoMega​ Sorry for late reply, I was busy doing something else too. I'm using the USB controller in DMA mode, so my use-case is a bit different. I encountered the problem you described, but in somewhat bizzare form, where DMA sometimes skips the second Data packet and sometimes fills the buffer with copies of the first 8 bytes of In Data. I'm pretty sure my DATA PIDs are okay, but I'll try to look more closely into this, thanks for the suggestion.

Anyways, it seems like I don't have any more useful input for you at this point. I'll let you know if I find anything useful.

NotSoMega
Associate III

Thanks to Corona I didn't have any time to work on this project. But now I am back at it. The enumeration process is working good now. I really struggle with the Interrupt IN Split Transactions now. I am not able to revieve data or expected interrupts at the moment. Did you have any success in this? @QI.1​ 

NotSoMega
Associate III

A few more weeks have passed and I was able to work on this again and make some progress.

Everything works now as expected as long as only one device is connected to the hub. For example when I connect a mouse to the hub the enumeration is always successful and I am also able to recieve the Interrupt IN data packages from the mouse. Thats why I believe my understanding and implementation of the SPLIT protocol to be correct.

When I try to connect more than one device to the hub I get strange behaviour. I found that the problem partly lies in the way CubeMX handles the ClassHandler Structure (USBH_ClassTypeDef). CubeMX uses the same global structure for each HID device even though some instances of it needs to be unique to each device. I worked around this by creating one ClassHandler for each device. Now at least both devices gets enumerated and I can see the IN packages of both devices on the bus (with my sniffing tool). The only major problem that remains now is the fact that I cant retrieve the IN packages anymore as soon as more then 1 device is connected to the hub. I am currently clueless regarding this and would appreciate any help or ideas.

KPunj.1
Associate II

@NotSoMega​ @QI.1​ I am currently working on split transaction and this thread helped me progress quite a bit, thank you so much!

I am currently stuck with Control IN transactions where I faced the same problem that the two of you had previously faced. While connected to both LS/FS mouse and keyboard having maximum packet size of 8, only the first 8 bytes of descriptor data are read while the remaining 10 are ignored. Were you able to deal with this issue without hardcoding the descriptor information?

Also, as an additional note, split transaction works fine in control mode with full speed barcode scanners where the maximum packet size is 64 bytes. I am working on interrupt mode transactions for these devices.

Any suggestions would be greatly appreciated!

Edit: I have resolved CONTROL mode based issues. Now I am just stuck at interrupt mode. If you have tips to resolve this, it would be greatly appreciated.

NotSoMega
Associate III

Hello @KPunj.1​ ,

I am glad that I could help you somehow getting started. Interestingly I picked this project up myself again recently. Can you explain your problem a bit more regarding the interrupt transactions?

KPunj.1
Associate II

0693W00000D1hqnQAB.jpgHi @NotSoMega​,

The main reason for interrupt transactions failing is that NAK is not being generated which subsequently causes the IN interrupt to not be triggered after a few attempts. I tried a workaround for that by clearing the complete split bit when there's no nak or complete transfer generated. However, that works sporadically and only when I insert breakpoints. An additional point to this is that while doing this, NAKs are generated for a while.

I am currently doing all my testing with a full speed barcode scanner because it is easier for me to see the issues rather than with a mouse or a keyboard and have attached the sequence I am currently seeing in interrupt mode. What was the issue you were facing with interrupt mode?

NotSoMega
Associate III

Hi @KPunj.1​ 

I had the same issue. No NAK Generation after completed enumeration. Sometimes it worked by using breakpoints. I managed to get a stable build with NAK generation but I have no idea why it started working suddenly. I can't help you at the moment. I am still investigating this and let you know when I come to a solution.