Showing results for 
Search instead for 
Did you mean: 

How to perform a control IN endpoint transfer with the USB OTG FS core?

Associate II

I'm attempting to write myself a USB stack on the STM32L476RG, and the reference manual has been pretty subpar so far, which is nothing new apparently. I've gotten to the point where I can receive a SETUP packet request from the host (GetDescriptor for the Device descriptor), but I seemingly cannot find a way then to respond back with more than one packet. The first packet (of eight bytes) is sent successfully and can be seen in WireShark, but the transfer then stops there even after filling the TX-FIFO again for the second packet. Obviously, I'm doing something wrong, and perhaps it'd be clearer if I had a hardware analyzer to decode the raw signals, but alas, I'm empty handed.

I haven't tried increasing the size of the default endpoint beyond 8 bytes (maybe 64 bytes, so thus only one packet is only ever needed to be sent), but even if that did solve the issue, I feel like that'd be ignoring the actual underlying problem.

Here is a simplified sample of the current state of the code.

Any gurus have any ideas?

PS. The reference manual really need to be updated; it makes mention of a "B2BSTUP" bit in "OTG_DOEPINTx" but no such bit exists (but is defined in CMSIS).

Lead III

No easy answer but my USB stack source might be helpful:

There are some undocumented bits in control registers. Also not the non-obvious handling sequence of set_address request in OTG core.

ST Employee

Hi @PhucXDoan 

I have forwarded your request to dedicated team.

Internal ticket 184011 has been submitted to update the reference manual.

If you have issues with current ST USB stack, we appreciate your notifications since we cannot support everyone writing his own stack. 

@gbm please don't hesitate to report the undocumented bits.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

DOEPINTx register, bit 15 - STPKTRX.

> since we cannot support everyone writing his own stack

But of course you can! By both you (ST) and Synopsys providing concise and complete documentation - including properly documenting the OTG module's variants, their differences and quirks. Ditto for the attached PHYs (which are outside of Synopsys scope); ditto for the related fabric (e.g. the HS PHY's PLLs where applicable).

> DOEPINTx register, bit 15 - STPKTRX.

Heh...  and the partially rotten (courtesy of ST persistence of using inappropriate "customer satisfaction whatever" instead of proper forum software, and the inevitable subsequent migrations) links/posts from there.

That was the point where I gave up on the idea of using the OTG module across families, and focused on 'F4 exclusively.


Associate II

I think I pinned down the issue: it was the fact that my host machine -- for some reason -- always expects the default endpoint to have a maximum size of 64 right after plugging in the device, even if the device doesn't support it. This ends up appearing as a malformed packet in WireShark, and it is only after another Reset is performed again that the host handles the expected packet size properly. This in combination with me sending dummy data (8 byte packet of 0xFFs) to debug in WireShark, it confused the host even further since this would make the bMaxPacketSize0 be 255. I confirm this by testing a previous USB project I worked on using the ATmega32U4 and WireShark reports a malformed packet, but after another Reset, things all enumerate out just fine.

In other words, I was being too conservative and ended up chasing a lot of red herrings. Doesn't help that the reference manual is pretty vague about the initialization process, so it could've been thousands of other possible issues (foolish me thinking that having 160 pages to go through would mean that it'd be well-documented).