cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 F2/F4 USB Host issues

miro_atc
Associate II
Posted on October 16, 2014 at 11:30

.ExternalClass11B1744985E14676887C8F042F0B5239 p {margin-bottom:0.1in;line-height:120%;}

Hi,

I am writing a host stack and I have noticed various issues with the documentation and the hardware.

Issue #1

The pdf index of the Reference Manual (RM) for F2 series (DocID15403 Rev 6) is broken. If you open the index (contents) for the OTG FS and OTG HS registers it shows tables and notes instead of registers.

Issue #2

According to the RM the PENA bit in the OTG_HS_HPRT is rc_w0.

“The application cannot set this bit by a register write. It can only clear it to disable the port.�?

I had checked all the usb libraries I could find on internet and indeed they NEVER write this bit with 1.

But they all write it with 0 even when the port is obviously powered (e.g. when performing a bus reset).

So the libraries treat this bit as rc_w1 while the RM says it is rc_w0.

Which is correct?

Issue #3

The power up sequence of the OTG controller is not documented well. There are some complication when using the OTG HS with the internal FS PHY and it is even more complicated when the ID pin is not used. The software is supposed to reset the core and phy domain when changing the PHY. Then some configuration needs to be done until we are able to detect a connection. And then if we have configured different speed than the one that the device requires we need to change the PHY clock.

With other words several resets may be required, and after each reset some registers are cleared and needs to be reconfigured. But all this needs to be done with caution if we do not want to loop forever with resets.

I did it somehow, but it will be nice to have some documentation about the steps – in which order to change the PHYs, the host/device mode, power, clocks... how long each step can take etc.

Issue #4

CHENA and CHDIS bits in OTG_HS_HCCHARx / OTG_FS_HCCHARx register.

Again bits which can be modified from both the software and hardware and again contradictory documentation and practice. The definition is “rs�? but how can you explain “HCCHARx = CHDIS�? and “HCCHARx = CHENA | CHDIS�??

Btw it is not very clear how the core modifies these bits and when. I have noticed that on the control IN endpoints the core disables the channel on the first NAK, while for the interrupt IN type it does not disables the channel.

Issue #5

The NAK processing is not documented well.

I think it is worth mentioning that the host must send regularly IN tokens to poll the in channels. And most of the time the device is not ready or has no data, so we can expect some NAKs....

There is a section “NAK and NYET handling with internal DMA�? but what about without DMA?

Cheers,

Miro

8 REPLIES 8
miro_atc
Associate II
Posted on October 16, 2014 at 14:14

.ExternalClass1E00B791F63449EF8045CAE6FC47773E p {margin-bottom:0.1in;line-height:120%;}

About issue#4

It seems CHENA and CHDIS are not exactly memory registers. I mean if you write “1�? to a register bit the write operation will have no effect if the bit is already “1�?.

While writing CHENA multiples times for an IN channel actually schedules multiple IN tokens. For example the following code will actually re-activate twice in most of the cases:

/* re-activate the channel */

USBx_HC(chnum)->

HCCHAR

&= ~USB_OTG_HCCHAR_CHDIS;

USBx_HC(chnum)->

HCCHAR

|= USB_OTG_HCCHAR_CHENA;

This

is from the stm32Cube and I don't know if this is what they expect,

probably not..

.

I have tested with a control endpoint and standard IN Request. If I use the above code in the NAK processing I do not need to re-enable the channel on RXFLVL. I just read my data and do not touch HCCHAR at all. After a while I get another NAK interrupt (the device is not ready with the next data packet).

However if I change the above code to use single write access then on RXFLVL I must re-enable the channel otherwise it stops.

miro_atc
Associate II
Posted on October 16, 2014 at 14:55

.ExternalClass30FCE68B09684A65A136EF83C82FEF2B p {margin-bottom:0.1in;line-height:120%;}

Issue # 6

Errata:

OTG host blocks the receive channel when receiving IN packets and no

TxFIFO is configured

I am quite confusing here... As far as I know each USB device starts in default state and will NEVER send any data unless is being asked from the host. With other words if the host has not send any data, no IN token will be ever acknowledged. So the question is how you know you cannot receive IN packets when no such IN packets are allowed by the standard?

Workaround

Set at least one TxFIFO equal to the maximum packet size. In this way, the host application,

which intends to supports only IN traffic, also has to allocate some space for the TxFIFO.

It is getting more confusing... How many TxFIFOs we have? As far as I know - only 2 in host mode. One for periodic and one for non-periodic transfers... Which one we are suppose to set?

Perhaps I am missing something here because it looks to me like a confusing workaround for impossible problem....

miro_atc
Associate II
Posted on October 16, 2014 at 15:11

.ExternalClass9C006420E7B447A398C4A25B5B3E330E p {margin-bottom:0.1in;line-height:120%;}

Issue #7

talking about TxFifo's do you see something wrong in this code:

USBx->

GRSTCTL

= ( USB_OTG_GRSTCTL_TXFFLSH |(

uint32_t

)( num << 5 ));

(stm32f2xx_ll_usb.c line 333)

Issue #8

and here:

/* Check for space in the request queue to issue the halt. */

if

(((USBx_HC(hc_num)->

HCCHAR

) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->

HCCHAR

) & (HCCHAR_BULK << 18)))

(same file line 1550)

miro_atc
Associate II
Posted on November 20, 2014 at 11:52

Issue #8

The USB host transactions fail (always) with transaction error interrupt when the core is in sleep mode. The USB device mode seems OK.
gene23
Associate II
Posted on April 09, 2015 at 22:00

Thank you so much kostadinov for pointing out these issues. I have ran into at least half of them, and wasted hours and hours of development time and frustration trying to solve them. It would be nice if after this was originally posted about 5 months ago, ST representatives would in some way acknowledge your posts instead of ignoring them. 

gene23
Associate II
Posted on April 09, 2015 at 22:06

As far as issue 2, one library I was using had this  comment, '' Note: STM ref manual error about PENA bit. A ''1'' clears PENA, not a ''0''. 

miro_atc
Associate II
Posted on August 30, 2016 at 09:42

About Issue #5

The NAK processing in slave mode (without DMA).

In OUT direction the documentation suggests (as well as some libraries) that multiple packets can be queued. However this creates several implications. First of all, the target device can NAK a packet from the sequence. It seems that in such case the controller drains out the rest of the packets automatically, so there is no need to flush the TX fifo. However, the sequence must be retried from the NAK-ed paket and it is hard to tell which one exactly is that packet.

Another implication is that the TX FIFO (non-periodic one was tested) can get full if we write multiple packets. So the transmitting channel must wait for fifo empty (half empty) interrupt. Then the GNPTXSTS is supposed to tell us which is the current channel, but it's value is not always correct. At least when there is a NAKed sequence and the fifo is drained the NPTXQTOP field is not correct, so the software cannot rely on it.

Anyway, the implications can be avoided if software sends only single packets and waits for ACK/NAK before sending the next one or retrying. In case of NAK the same packet needs to be retried. Also the FIFO size can be programmed with enough space for all the channels (at least for Full Speed) so there will be no need to check for the space or fifo empty conditions.

Back to NAKs - when OUT packet gets NAK-ed it seems the software must halt the channel before the retry. For IN channels it is enough to rewrite the HCCHAR register with it's value (see issue 4 and CHENA).

Even though the retry can be done immediately it is recommended to wait some time before retrying. Some 10-20ms sleeps give the best results. Note that the fast retries can cause avalanche of interrupts (NAKs) and CPU usage not only on the host side but also they can kill the device side too. So the total transaction time can be significantly reduced if the bus is not flooded.

dsheludko
Associate II
Posted on September 28, 2016 at 07:03

Thanks so much for confirming what has taken me months of trial and error figuring out NAK handling! (see also

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Correct%20handling%20of%20NPTXFEM%20USB%20host%20interrupt&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506...

)This is key:

''Even though the retry can be done immediately it is recommended to wait some time before retrying. Some 10-20ms sleeps give the best results. ''