Electronic – STM32 USB – Delayed transmit when payload length = 256 (or 512, or 768…) bytes

cortex-m3stm32stm32f10xusbusb device

I am implementing USB communications on a STM32F105, using ST's USB Library v2.1.0. It communicates as a CDC class Virtual COM Port ("VCP"). I'm using the embedded Full Speed PHY.

I've started with ST's VCP example project, which is a serial-to-USB converter. I have it working well except for one issue that I suspect may be a bug in their library code.

Their USB driver exposes a circular buffer and buffer pointer. The application is supposed to put data into this buffer, which gets noticed by the driver and is acted upon. Here is the function to populate the buffer:

uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
{
    uint32_t i;
    for (i=0; i<Len; i++)
    {
        APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i];
        APP_Rx_ptr_in++;

        /* To avoid buffer overflow */
        if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
        {
            APP_Rx_ptr_in = 0;
        }
    }
    return USBD_OK;
 }

This works to send up to (at least) 1024 bytes of data, except if the data length is an even multiple of 256 bytes. In other words, I can use this function to send 255 or 257 bytes just fine (or even 1023), but if I try to send 256 bytes it fails. Or 512, or 768, etc.

The failure mode is that no data is sent over USB until there has been a total of 4096 bytes passed into their buffer, and then it all gets transmitted at once. When it's working correctly, of course, the data gets transferred immediately.

There is a list of known bugs here. I've incorporated them, but it hasn't fixed this problem.

Does anyone know a solution? I would prefer not to debug ST's driver code…

Best Answer

except if the data length is an even multiple of 256 bytes

Its 64 bytes actually (MaxPacketSize). USB bulk transfers "end" with transfers that are not MaxPacketSize - normally 64 bytes long. If your transfer is an integer multiple of that, you send a zero packet after the data. This signals the transfer end to upper USB software stacks, which will return your data at once.

Most VCP example code omits this for simplicity.

Related Topic