AnsweredAssumed Answered

STM32L476 USB FIFO Settings

Question asked by Murphy.Colton on Oct 31, 2015
Latest reply on Nov 5, 2015 by Leopold.Milan

Hopefully this question has a simple answer. 

Currently I am writing some USB firmware (driver) for this device. All I am trying to do is complete a GetDescriptor command from the USB host. I seem to have no problem getting the setup packet, reading it, and then outputting my device descriptor in the IN data stage when the host asks for it. All the data goes out the pipe and all is well. However, the issue lies when the host tries to complete the Data1 0 length status stage. The micro just seemed to NAK this no matter what.

After several hours of debugging, I seemed to have the endpoints for IN and OUT transactions enabled during the various stages. There was no reason why the micro would just NAK the status stage, but no matter what I tried, it kept sending a NAK.

I never thought something as simple as the data FIFOs could cause the issue. Surely, something as simple as the FIFOs could not cause the issue. I mean.. writing and reading them are easy. Well... I started messing with the RX FIFO size and TX start address for IN EP 0 and... what do you know, my GetDescriptor request completed as the micro sent an ACK response. 

I am incredibly baffled by this. I need clarification. In the manual it says GRXFSIZ is allocated in 32 bit words. Does this not mean that if I want a 64 byte packet size, I need to input 16 into this register? How about the TFSIZ registers for the RAM start address? The way I understand the manual, the start address is not word based but byte based. This means IN EP 0 RAM address should be 64, Correct? The TX FIFO bits should then be programmed with 16 again for a 64 byte packet size.

The above programming failed and kept sending the NAK on the zero length status stage of the setup transaction. I changed the above programming to 64 for GRXFSIZ and kept the TXF settings the same and the micro sent an ACK. 

The manual says that it is required to allocated some 'extra space' in the RX FIFO for setup packets and status information. Even running all the calculations, with GRXFSIZ set to 16 (64 byte), if the RXFIFO was to be overflowed, this would not happen in the GetDescriptor command.  Setup stage : 3 words + 1 for setup complete, then maybe 1 more for OUT complete. I mean... that just doesn't add up to 16 words let alone 64 bytes.

Can someone clarify the settings of the FIFO registers?

Also, for the sake of argument, let's say that GRXFSIZ is set to 16 and means 16 bytes, not words.. If I process each stage of the transaction, the maximum bytes to the RXFIFO on the GetDescriptor command is 12 (3 words). Those get popped off. The FIFO pointer should then be back to 0. Then I get an OUT complete at some point in the FIFO. That gets popped off; FIFO pointer back to 0. From where I am standing, I am popping the FIFO as I am getting the various stage interrupts. There should be no chance to overflow. However, if in fact it is 16 bytes for the RXFIFO, and my "popping" action is not really popping, then the FIFO would reach maximum and overflow after the status stage. That would explain why the NAK was sent on the zero length OUT stage. However... I also tried increasing the GRXFSIZ value in increments of 4. 32 did not work and the only one that seemed to work was a value of 64 or above. 

Just to be clear, I am following what I think the manual intends for the RXFIFO. When I get an RXFLVL interrupt, I read the STSP register to 'pop' the first word off the FIFO and get the status. I then look at the packet status and pop additional words off if the byte count is not 0. To pop additional words, I read from address 0x50001000 and do not use the STSP for subsequent words.