cancel
Showing results for 
Search instead for 
Did you mean: 

USB_OTG_FS - The STSPHST bit - To bit, or not to bit, that is the question.

PhucXDoan
Associate II

The latest RM for STM32L4 I could find mentions the STSPHST bit on page 1702, but makes no mention of how to actually use this bit. Granted, I'm working on a STM32L476 and given table 318, the STSPHST bit is not supported anyways. Nonetheless, I don't find this bit to be defined at all in the CMSIS header file stm32l496xx.h, so what gives? Is this bit deprecated?

The only reason why I'm interested in this bit is because I'm trying to perform a control write transfer on the device side. I got to the point where I'm decoding the SETUP request of SET_LINE_CODING for CDC, configuring the default OUT endpoint to receive a single packet, waiting for RXFLVL, popping off the packet status using GRXSTSP, reading in the RX-FIFO data, and then finally popping off the "OUT transfer completed" status word pattern.

The weird thing however is that -- shortly after popping off the last word -- RXFLVL then gets set again and it's apparently another "OUT transfer completed" pattern. The only difference between these two "OUT transfer completed" statuses is in bit 27 (with the latter status have the bit set), but this is where STSPHST would be... but RM claims that this bit is not supported, so I should be ignoring this bit... oh what a dilemma!

But suppose we ignore table 318 for a moment and read the description of STSPHST: "Indicates the start of the status phase for a control write transfer. This bit is set along with the OUT transfer completed PKTSTS pattern." This would then explain my observation of receiving two "OUT transfer completed" statuses; one is for the completion of an OUT transfer of the data stage in the control write, while the second is to indicate the start of the status stage to finalize this control write.

Of course this just begs the question: why is the USB core designed like this?

My theory is that it's so the application can know when to enable the IN endpoint to send the status packet to the host. Despite there being the ITTXFEMSK bit ("IN token received when Tx FIFO empty mask"), this interrupt does not trigger unless the IN endpoint is already enabled (if I recall my observations correctly). In other words, there isn't really a way to know when the host has sent the IN token in order to, let's say, terminate the control write transfer early. The second "OUT transfer completed" status combined with the STSPHST bit, however, gives a way for the application to know when the host has sent the IN token to begin the status stage of the control write transfer.

This to me all sounds plausible, but the issue then is the documentation, because after all, the STSPHST bit is supposedly not even supported on the STM32L476!

Any clarifications on this would be greatly appreciated.

3 REPLIES 3
nouirakh
ST Employee

Hello @PhucXDoan ,

The issue  is reported internally.
Internal ticket number: 185311 (This is an internal tracking number and is not accessible or usable by customers).

PhucXDoan
Associate II

After a mild crisis, I managed to resolve a bug relating to this poorly documented STSPHST bit, to which I'll describe here for any future tinkerers who are also in the same position as I am:

As it turns out, the USB core blocks any further receptions of packets (RXFLVL) while certain interrupt flags are asserted, and one of these flags is the STSPHSRX bit of DOEPINT. This flag is set when the status stage of the control write transfer has begun, as described in the above post, but if this STSPHSRX bit is never cleared, then events such as STUP end up being blocked. Thus, the control flow of handling SETUP requests end up falling apart inexplicably like I observed in my own USB stack. It's a very subtle thing that's not mentioned at all in the operational procedure of reference manual. To make matters worse, the CMSIS headers fail to document the bits properly.

For instance, on page 1732, DOEPMSK has STSPHSRXM on bit 5, but the only definition for bit 5 in the CMSIS stm32l476xx.h file is "USB_OTG_DOEPEACHMSK1_INEPNMM" with a comment saying "IN token received with EP mismatch mask", and this is apparently a legacy definition!

nouirakh
ST Employee

Hello @PhucXDoan 

Thanks for the feedback and the detailed description. I will incorporate this information into the ticket descriptions so that we may consider it in our future actions.