AnsweredAssumed Answered

STM32L476RG CubeMX generated USB CDC code stops transmitting out of the blue

Question asked by Sven Köhler on Feb 24, 2018
Latest reply on Feb 26, 2018 by Bogdan Golab

I soldered a USB cable to pins PA12 and PA11 on the Nucleo-L476RG board. In CubeMX I enabled USB with its default settings, disabled DMA (it's not supported for FullSpeed USB anyway) and generated the code. I used the latest CubeMX (4.24) as well as the latest CubeL4 (v1.11.0) available.

 

I adjusted main.c so that it sends data in a loop. This is the code inside the main method:

 

uint32_t x = 0;
static char buf[1024];

while (1) {
  size_t len = sprintf(buf,
    "0123456789" "0123456789" "0123456789" "0123456789" "0123456789"
   "0123456789" "0123456789" "0123456789" "0123456789" "0123456789"
   "0123456789" "0123456789" "0123456789" "0123456789" "0123456789"
   "0123456789" "0123456789" " %u\r\n", x++);
  uint8_t ret = CDC_Transmit_FS(buf, len);
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin,
    ret == USBD_OK ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

 

The CDC_Transmit_FS function is as generated by CubeMX. It checks the TxState and returns USBD_BUSY if the USB is busy sending. If the USB is not busy, it calls USBD_CDC_SetTxBuffer and transmits the packet via USBD_CDC_TransmitPacket.

 

The CDC_Receive_FS function is also as generated by CubeMX. It simply calls USBD_CDC_SetRxBuffer and USBD_CDC_ReceivePacket. The data written into the buffer is never actually used.

 

On the PC (Linux in this case), I start a terminal program (picocom) to display all the text that arrives on the virtual COM port /dev/ttyACM1. The lines are displayed in my terminal window just fine - but then stop inexplicably. When it stops, the output usually looks something like this:

 

01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 121520
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 121521
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 121522
4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 121523
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 121525

 

As you can see, line 121523 is shorter than the others and doesn't start with a zero. The last line is complete, but after that line, the transmission has stopped. Sometimes it takes a while to fail. Sometimes it stops working after just a few lines.

 

I know that CDC_Transmit_FS doesn't wait until the transmission has finished. However, as long as transmission is in progress, it should return USBD_BUSY and it should not disturb any ongoing transmission.

 

Does somebody have a similar experience? Did somebody get USB to work reliably?

I could very that TxState stays 1 and is not reset to zero.

 

I have read horrible things here about ST's USB CDC code (race conditions have been found in the past) and it looks like the L4 code still contains such a race condition. 

Outcomes