2019-09-23 03:15 PM
Board stm32h743i-eval - STM32Cube_FW_H7_V1.5.0
I am using OTG1_HS in dedicated Host mode. It is connected to a single device that contains a built in HUB with 2 devices attached. The main device I am communicating with is an ASIC based image sensor from a 3rd party. The control channel works great. The images are transferred over a bulk IN endpoint as a stream of data. The sensor sends 6 packets of 512 bytes and then waits for a couple frames (processing time) and then sends the next 6 packets. It does this until the sensor is told to stop (I.E. forever). My initial issue is with the rate of IN tokens sent on the Bulk channel. The rate is high enough to flood the ASIC. This significantly impacts the ASICS ability to process the control channel (To the point that the stop command is unacceptably delayed). I have a USB 2.0 analyzer and it shows the host sending between 8 and 12 In tokens per 128 uS frame for the Bulk channel. Of course 99.9% get NAK’s by the ASIC. I would like to reduce this to 1 per 128 uS Frame. What I have done is modify HCD_HC_IN_IRQHandler to not call USB_HC_Halt() when the NAK is received on that channel. USB_HC_Halt() just re-enables the channel which in turn sends another IN token. It does this by setting CHDIS and CHENA. I then added code to the SOF interrupt to call USB_HC_Halt() for that channel if the state is HC_NAK. I expected 1 IN token per frame but I get 2. I do not understand exactly why. The ASIC can handle 2 per frame without slowing the control channel processing down so I am good with that. Now the issue is the Bulk IN channel gets Halted / turned off after the receipt of the first 6 packets (Note; the RX buffer is large enough for 120 packets of 512 bytes, so the HC_XFRC is not triggered). I get the RXFLVL interrupt for all 6 packets. After the 6th packet another IN token is never sent. The last HCINT for that channel happens before the RX of the 6 packets and is never seen again. The control channels work fine before and after this. I do see many more RXFLVL interrupts (They are spread out over time) from that channel with the PKTSTS set to Channel Halted. I believe these are generated when the SOF calls USB_HC_Halt(). I can run this 1000 times and it does the exact same thing every time.
The data sheet lacks a good explanation of the OTG_HCINTx::HCC interrupt. I can tell it gets triggered on every RXFLVL interrupt with a PKTSTS of Channel halted. I assume the USB engine is posting these to the RX buffer because these do not always correspond with something on the wire. I want to understand why these get posted and how to re-enable the channel in my situation.
I have attached an ods spread sheet. Each row is a call to HAL_HCD_IRQHandler. Everything out to Column BQ is the state at the start of the IRQHandler and every thing at and after BQ is the state at the end of the IRQ Handler. The event I am speeking of is at row with the Int Count == 4669. I have also attached an image of the USB analyzer output filtered down just to the Bulk channel.
2019-09-24 06:56 AM
You may want to search for "host flood" on this forum, e.g. https://community.st.com/s/question/0D50X00009XkfssSAB/stm32f4-stm32f7-usb-host-core-interrupt-flood
[EDIT] okay sorry I reread your post and see you are already at the next step [/EDIT]
I understand that the Synopsys OTG IP in 'H7 may have already implemented the NAK/retransmission throttle, but I doubt you will get any more detailed answer to your question here.
JW