AnsweredAssumed Answered

Real bug in the USB CDC

Question asked by kukhtin.sergey on Sep 15, 2014
Latest reply on Dec 24, 2014 by w.j.001
USBD_CDC_TransmitPacket() function contains a bug:

it sets the 'transmission in progress' flag AFTER starting the actual transmission, so if the 'transmission done' interrupt happens too early, the flag will be set AFTER the interrupt and hence will never be cleared.
To fix this, move "hcdc->TxState = 1" line before the call to USBD_LL_Transmit() :

uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
{      
  USBD_CDC_HandleTypeDef   *hcdc = pdev->pClassData;
 
  if(pdev->pClassData != NULL)
  {
    if(hcdc->TxState == 0)
    {

      /* Tx Transfer in progress */
      hcdc->TxState = 1;

      /* Transmit next packet */
      USBD_LL_Transmit(pdev,
                       CDC_IN_EP,
                       hcdc->TxBuffer,
                       hcdc->TxLength);

      return USBD_OK;
    }
    else
    {
      return USBD_BUSY;
    }
  }
  else
  {
    return USBD_FAIL;
  }
}


This bug we found in practice, and it was described http://visualgdb.com/tutorials/arm/stm32/usb/

Outcomes