AnsweredAssumed Answered

[STM32F407 - USB/FS] Bulk endpoint transmits corrupt USB package

Question asked by tberlinghoff on Nov 8, 2016
Latest reply on Apr 29, 2017 by Kalle Raiskila
I have created a "Virtual COM-Port" implementation, based on the CP210x datasheet, and try getting it running on the STM32F4Discovery board. The implementation uses the following endpoints:

- Control-endpoint 0x00, 0x80
- Bulk-endpoint (in) 0x81
- Bulk-endpoint (out) 0x82

Initialization and enumeration works fine, the virtual comport is shown as "/dev/ttyUSB0" on my linux box and I can connect to it , set baudrate, ... . The current implementation simply receives data and send it back to the host. While receiving data is working fine, sending it back only works for packages having a size of 4 byte. If I try to send more data, the controller sends packages that are too short and have a wrong CRC.

Configuration:
RxFIFO: 256 Byte (64 words)
TxFIFO #0: Start=256 Byte, Size=128 Byte
TxFIFO #1: Start=512 Byte, Size=128 Byte
TxFIFO #2: Start=286 Byte, Size=128 Byte
TxFIFO #3: Start=832 Byte, Size=128 Byte

- TxFIFO #2 and #3 are unused, so initialization should not be necessary and is just done to ensure they do not cause any problems.
- I added some space between TxFIFO #0 (used by the EP-0) and TxFIFO #1 (used by bulk IN-EP 1) just to ensure that there is no collision of both fifo's causing the mentioned issue.

The values of the correspondent register is shown in the following picture: http://85.214.211.57/stm32_cp210x/0_fifo_config.jpg

In the following pictures a transfer of 10 byte data is shown (data=0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x30)

When the firmware tries to send data back to the host, it performs the following steps:

1) Configure register DIEPTSIZ1 (Device Endpoint Transfer Size Register): PKTCNT=1, XFRSIZ=10
2) Enable "TxFIFO empty" interrupt for EP-1
3) In the ISR fill FIFO #1 (associated with EP-1) with the data to transfer.

The following picture shows the register DIEPTSIZ1 (Device Endpoint Transfer Size Register), DTXFSTS1 (Device IN endpoint transmit FIFO register) and the hexdump of TxFIFO #1 after 8 bytes has been pushed to the FIFO:
http://85.214.211.57/stm32_cp210x/1_in_fifo_partly_filled.jpg

- DIEPTSIZ1 shows that 10 Bytes need to be transferred
- DTXFSTS1 shows that 30 words are still available on the FIFO (the FIFO has 32 words in total and 2 words are being used at this point)
- The hexdump shows the data has correctly being pushed to the FIFO

The following picture shows how the content changes when the last word, required to transfer the package, is being added to the fifo:
http://85.214.211.57/stm32_cp210x/2_in_fifo_filled.jpg
- DIEPSIZ1 shows that 0 bytes need to transferred (so the controller has started the transfer)
- DTXFSTS1 shows that 29 words are still available on the FIFO (the FIFO has 32 words in total and 3 words are being used at this point)
- The hexdump shows the data has correctly being pushed to the FIFO


So the USB-FS controller waited for all necessary data being available and then starts the transfer. As described above the transfer is incomplete, as you can see in the following picture the IN packages consists of only 5 byte (instead of 10 byte) and also a wrong CRC (the host does not ACK the package and retries):
http://85.214.211.57/stm32_cp210x/4_usb_trace.jpg

So what could cause the USB controller to transmit less data and wrong CRC?

Any help is appreciated,

Thomas

Outcomes