Skip to main content
Visitor II
March 6, 2025
Solved

STM32L452RE -> USB CDC Transmit Stuck, hcdc->TxState Never Resets

  • March 6, 2025
  • 1 reply
  • 573 views

Hello ST,
I'm developing a USB CDC communication project on an STM32L452RE microcontroller using STM32CubeIDE.

I can successfully receive data from a PC using the Hercules SETUP utility by HW-group.com.
I'm facing a challenge with transmitting data back to the PC using the CDC_Transmit_FS function.

Environment:

  • MCU: STM32L452RE
  • IDE: STM32CubeIDE
  • CUBEMX: STM32CubeL4 Firmware Package V1.18.1
  • USB Configuration: Configured as a CDC Virtual COM Port
  • OS: Windows 11
  • USB Interface: Hercules 3.2.8

Issue Description: 

Data reception from the PC works flawlessly. However, when attempting to transmit data back using CDC_Transmit_FS, the function seems to never complete. The code gets indefinitely stuck waiting for hcdc->TxState to reset to 0, which, based on my understanding, should happen via an interrupt once the transmission completes.

Troubleshooting Done:

  • Create a new ST board project using this video USB tutorial:
    https://www.youtube.com/watch?v=92A98iEFmaA&t=212s
  • Confirmed correct USB descriptor configurations.
  • Debugged to pinpoint that the halt occurs during data transmission, specifically waiting for hcdc->TxState.
  • The hUsbDeviceFS.pClassData return the “USB Device handle structure” there is a USB communication problem with the device's startup as a result. 

Questions:

  • Are there any known issues with USB CDC on STM32L452RE that might cause this behaviour?
  • Could there be any CubeMX configuration or USER CODE that I might have overlooked that could lead to this issue?

MaromMeir_0-1741255967633.png

MaromMeir_1-1741255967634.png

The computer recognizes the card on COM12:

 
 MaromMeir_2-1741255967634.png

 

 

BAUND 115200
Data bits 8
Parity None
Stop bits 1
Flow Control None

The Hercules SETUP utility opens the COM12, but the MCU does not send the object.
char *data ="HELLO LUMUS!\n" to the USB buffer.

 

Code Snippets:

main.c While loop:

/* USER CODE BEGIN 0 */

uint8_t ret =0;

char *data ="HELLO LUMUS!\n";

/* USER CODE END 0 */



 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

 /* USER CODE END WHILE */

 ret = CDC_Transmit_FS((uint8_t *) data, strlen(data));

 if(ret)

 printf("CDC_Transmit_FS ERROR TYPE:%d",ret);

 HAL_Delay(1000);

 /* USER CODE BEGIN 3 */

 }

 /* USER CODE END 3 */

}

 

CDC Transmit Function:

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)

{

 uint8_t result = USBD_OK;

 /* USER CODE BEGIN 7 */

 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;

 if (hcdc->TxState != 0){

 return USBD_BUSY;

 }

 USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);

 result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);

 /* USER CODE END 7 */

 return result;

}

 

Device Init for the USB:

void MX_USB_DEVICE_Init(void)

{

 /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */



 /* USER CODE END USB_DEVICE_Init_PreTreatment */



 /* Init Device Library, add supported class and start the library. */

 if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)

 {

 Error_Handler();

 }

 if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)

 {

 Error_Handler();

 }

 if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK)

 {

 Error_Handler();

 }

 if (USBD_Start(&hUsbDeviceFS) != USBD_OK)

 {

 Error_Handler();

 }

 /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */



 /* USER CODE END USB_DEVICE_Init_PostTreatment */

}

 

The Register Class Link class driver to device core:

USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)

{

 uint16_t len = 0U;

 if (pclass == NULL)

 {

#if (USBD_DEBUG_LEVEL > 1U)

 USBD_ErrLog("Invalid Class handle");

#endif /* (USBD_DEBUG_LEVEL > 1U) */

 return USBD_FAIL;

 }

 /* link the class to the USB Device handle */

 pdev->pClass[0] = pclass;

 /* Get Device Configuration Descriptor */

#ifdef USE_USB_HS

 if (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL)

 {

 pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len);

 }

#else /* Default USE_USB_FS */

 if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL)

 {

 pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);

 }

#endif /* USE_USB_FS */

 /* Increment the NumClasses */

 pdev->NumClasses++;



 return USBD_OK;

}

 

The function USBD_RegisterClass returns USBD_OK, so I don’t know the root of the USB communication problem.

 

Any insights or recommendations would be immensely appreciated.

I appreciate your support!

Marom.

 

    This topic has been closed for replies.
    Best answer by MaromMeir

    Solution:
    Connect USB cable to pinA12 and pinA11 of the NUCLEO-

    PA12 -> USB_DP Green color

    PA11 -> USB_DM White coler

     

    1 reply

    MaromMeirAuthorAnswer
    Visitor II
    March 6, 2025

    Solution:
    Connect USB cable to pinA12 and pinA11 of the NUCLEO-

    PA12 -> USB_DP Green color

    PA11 -> USB_DM White coler