cancel
Showing results for 
Search instead for 
Did you mean: 

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

MaromMeir
Visitor

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.

 

1 ACCEPTED SOLUTION

Accepted Solutions
MaromMeir
Visitor

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

PA12 -> USB_DP Green color

PA11 -> USB_DM White coler

 

View solution in original post

1 REPLY 1
MaromMeir
Visitor

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

PA12 -> USB_DP Green color

PA11 -> USB_DM White coler