Electronic – STM32 USB VCP bug

stm32usb

I have been working on a project for the past two weeks now and debugging this one issue has taken up this entire week. Wondering if anyone can help, I will try to be as explicit and clear as possible.

I am trying to implement a USB Virtual Comm Port on a MicroController based on the STM32F302K8 (Cortex M4). I have used STM32CubMX to generate the code needed to set up a USB Full Speed Device implementing a CDC class. My device shows up in both Windows (Device Manager) and Linux. I am able to implement a simple echo function based on the example code but when I now try to use the function USBD_CDC_SetTxBuffer to send data to the PC, this sets off a Hard Fault Handler. I have narrowed this down to the fact that the UsbDeviceFS.pClass (which is needed by USBD_CDC_SetTxBuffer) field is never initialized because USBD_CDC_Init() is never called in the initialization of the USB Device.

I have implemented fixes to several bugs (including changing the heap size, fixing the transmission flag in USBD_CDC_TransmitPacket, and changing the size of CDC_DATA_HS_MAX_PACKET_SIZE to 256 from 512) in the example code as documented on the ST forum but still getting the same errror.

My device setup code is

* USB Device Core handle declaration */
USBD_HandleTypeDef hUsbDeviceFS;

/* init function */                    
void MX_USB_DEVICE_Init(void)
{
  /* Init Device Library,Add Supported Class and Start the library*/
  USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);

  USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);

  USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);

  USBD_Start(&hUsbDeviceFS);

}

Best Answer

To answer my own question, the problem is that my code didn't wait for the USB to finish initialization and immediately began sending data. Inserting an active wait on a boolean or adding a delay (as pointed out by @ramez) solves the problem.

UPDATE This bug has been fixed in subsequent USB CDC driver versions from ST. There is now a HAL_Delay in the setup. Caveat is that if for any reason Sys_Tick does not work/is deactivated/not yet initialised, your code will hang.