cancel
Showing results for 
Search instead for 
Did you mean: 

USBX on STM32H5 CDC - Can't open port.

Jin454
Associate III

Hi. Unfortunately, after several days of struggling with USBX, I'm forced to ask for your help. I'm using custom boards with the STM32h503RB and STM32h563VI. I tested the old library according to forum guides – no response when connected to a PC. The closest I've gotten is following the guide for USBX C0. Windows recognizes the CDC device and assigns a COM port, but there's no response when attempting to open the port.

USBX standalone,interrupt enabled, Clock 48MHz, CRS enabled, mempoll size 8*1024, stack size 6*1024

https://www.youtube.com/watch?v=43gcc2dGnxQ 

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USBX_Device_Init();
  MX_RAMCFG_Init();
  MX_ICACHE_Init();
  /* USER CODE BEGIN 2 */

  _ux_dcd_stm32_initialize((ULONG)NULL, (ULONG)&hpcd_USB_DRD_FS);


   HAL_PCD_Start(&hpcd_USB_DRD_FS);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	 // USBX_Device_Process();
	  ux_device_stack_tasks_run();
  USBD_CDC_ACM_Receive(buffer,BUFFER_SIZE,&received);
  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);

HAL_Delay(500);
  if(received!=0){
    USBD_CDC_ACM_Transmit(buffer, received, &sent);
    received=0;
  }

//HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    ux_device_cdc_acm.c
  * @author  MCD Application Team
  * @brief   USBX Device applicative file
  ******************************************************************************
    * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "ux_device_cdc_acm.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */


/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
UX_SLAVE_CLASS_CDC_ACM  *cdc_acm=NULL;

/* Data to send over USB CDC are stored in this buffer   */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */

/**
  * @brief  USBD_CDC_ACM_Activate
  *         This function is called when insertion of a CDC ACM device.
  *   cdc_acm_instance: Pointer to the cdc acm class instance.
  * @retval none
  */
VOID USBD_CDC_ACM_Activate(VOID *cdc_acm_instance)
{
  /* USER CODE BEGIN USBD_CDC_ACM_Activate */
  UX_PARAMETER_NOT_USED(cdc_acm_instance);
  cdc_acm = (UX_SLAVE_CLASS_CDC_ACM*) cdc_acm_instance;


  /* USER CODE END USBD_CDC_ACM_Activate */

  return;
}

/**
  * @brief  USBD_CDC_ACM_Deactivate
  *         This function is called when extraction of a CDC ACM device.
  *   cdc_acm_instance: Pointer to the cdc acm class instance.
  * @retval none
  */
VOID USBD_CDC_ACM_Deactivate(VOID *cdc_acm_instance)
{
  /* USER CODE BEGIN USBD_CDC_ACM_Deactivate */
  UX_PARAMETER_NOT_USED(cdc_acm_instance);
  cdc_acm = UX_NULL;
  /* USER CODE END USBD_CDC_ACM_Deactivate */

  return;
}

/**
  * @brief  USBD_CDC_ACM_ParameterChange
  *         This function is invoked to manage the CDC ACM class requests.
  *   cdc_acm_instance: Pointer to the cdc acm class instance.
  * @retval none
  */
VOID USBD_CDC_ACM_ParameterChange(VOID *cdc_acm_instance)
{
  /* USER CODE BEGIN USBD_CDC_ACM_ParameterChange */
  UX_PARAMETER_NOT_USED(cdc_acm_instance);
  /* USER CODE END USBD_CDC_ACM_ParameterChange */

  return;
}

/* USER CODE BEGIN 1 */
uint32_t USBD_CDC_ACM_Transmit(uint8_t* buffer, uint32_t size, uint32_t* sent){
    UINT retVal;
    if(cdc_acm!=NULL){
      do
      {
        retVal = ux_device_class_cdc_acm_write_run(cdc_acm,buffer,size,sent);
      }while(UX_STATE_NEXT != retVal);
      return 0;
    }else{
      return 1;
    }
}

uint32_t USBD_CDC_ACM_Receive(uint8_t* buffer, uint32_t size, uint32_t* received){
  if(cdc_acm!=NULL){
    ux_device_class_cdc_acm_read_run(cdc_acm,buffer,size,received);
    return 0;
  }else{
   return 1;
  }

}
/* USER CODE END 1 */
void MX_USB_PCD_Init(void)
{

  /* USER CODE BEGIN USB_Init 0 */

  /* USER CODE END USB_Init 0 */

  /* USER CODE BEGIN USB_Init 1 */

  /* USER CODE END USB_Init 1 */
  hpcd_USB_DRD_FS.Instance = USB_DRD_FS;
  hpcd_USB_DRD_FS.Init.dev_endpoints = 8;
  hpcd_USB_DRD_FS.Init.speed = USBD_FS_SPEED;
  hpcd_USB_DRD_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
  hpcd_USB_DRD_FS.Init.Sof_enable = DISABLE;
  hpcd_USB_DRD_FS.Init.low_power_enable = DISABLE;
  hpcd_USB_DRD_FS.Init.lpm_enable = DISABLE;
  hpcd_USB_DRD_FS.Init.battery_charging_enable = DISABLE;
  hpcd_USB_DRD_FS.Init.vbus_sensing_enable = DISABLE;
  hpcd_USB_DRD_FS.Init.bulk_doublebuffer_enable = DISABLE;
  hpcd_USB_DRD_FS.Init.iso_singlebuffer_enable = DISABLE;
  if (HAL_PCD_Init(&hpcd_USB_DRD_FS) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USB_Init 2 */
  HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS , 0x00 , PCD_SNG_BUF, 0x20);//EP0 OUT
  HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS , 0x80 , PCD_SNG_BUF, 0x60);//EP0 IN
  HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS , 0x81 , PCD_SNG_BUF, 0xA0);//EP1 IN
  HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS , 0x82 , PCD_SNG_BUF, 0xE0);//EP2 IN
  HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS , 0x03 , PCD_SNG_BUF, 0xF0);//EP3 OUT

  /* USER CODE END USB_Init 2 */

}

 

4 REPLIES 4
Sourabh15
Associate

Hi,

I have faced this issue on STM32H503RBT6 as it doesn't support USB_FS Mode. Hence it is recognized by the system but couldn't effectively start the code.

Did you try debug using the SWD Pins?

Transmission to the PC works with ThreadX. The other way around is worse.

Generally speaking, after changing the Endpoints, the standalone version opens the port, but transmission doesn't work at all.

From my perspective, there are missing code fragments that should be generated by default with MX.





With the above code, only 4 bytes are allocated for each CDC data endpoint. In EP buffer overlaps OUT ep buffer and notification/status in (incorrectly called CMD) overlaps both. Both data EP buffer sizes should be 64 bytes.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Jin454
Associate III

These memory addresses for endpoints are from ST's examples... after working through the threadX example and the C0 example, I was able to get bidirectional transmissions working without an RTOS. It's no surprise to me that so many people still use the previous library...