Skip to main content
Visitor II
October 16, 2025
Solved

Unable to run MSC and CDC in composite mode

  • October 16, 2025
  • 2 replies
  • 421 views

BOARD: STM32H743IITX
ACTICLE FOLLOWED: https://community.st.com/t5/stm32-mcus/how-to-implement-a-usb-device-composite-in-stm32h5/ta-p/708078

Hello everyone,
I was trying to use USB CDC+MSC in composite mode. After following the article mentioned above, i was able to build the project. But after running i was able to only get MSC (as shown in pc) and getting the CDC port with windows error 10.

Few things i have changed, in usbd_desc.c updated these lines

 
 0xEF, /* bDeviceClass */

 0x02, /* bDeviceSubClass */

 0x01, /* bDeviceProtocol */



Also i have updated CDC_IN_EP, CDC_OUT_EP, CDC_CMD_EP so it should not match MSC_EPIN_ADDR and MSC_EPOUT_ADDR

 
 
#ifndef CDC_IN_EP

#define CDC_IN_EP 0x82U /* EP1 for data IN */

#endif /* CDC_IN_EP */

#ifndef CDC_OUT_EP

#define CDC_OUT_EP 0x02U /* EP1 for data OUT */

#endif /* CDC_OUT_EP */

#ifndef CDC_CMD_EP

#define CDC_CMD_EP 0x83U /* EP2 for CDC commands */

#endif /* CDC_CMD_EP */

 

#ifndef MSC_EPIN_ADDR

#define MSC_EPIN_ADDR 0x81U

#endif /* MSC_EPIN_ADDR */



#ifndef MSC_EPOUT_ADDR

#define MSC_EPOUT_ADDR 0x01U

#endif /* MSC_EPOUT_ADDR */



Also i can individually, use cdc and msc from this code.
For CDC, i have to use bDeviceClass as 0x02
For MSC, i have to use bDeviceClass as 0xEF,

The windows error is

This device cannot start. (Code 10)

A device which does not exist was specified.

Any help will be appreciated.
Thanks

Devjeet Mandal



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

    Hello @devjeetmandal09 

    Thank you for your effort.

    Please try to increase the size of the buffer to 0x174 in the following line:

    HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x174); // EP3 IN (CDC CMD/interrupt IN)

    Additionally, after reviewing your code, increase the number of interfaces by updating this definition:

    #define USBD_MAX_NUM_INTERFACES 5U

    add the following definitions in usbd_conf.h:

    #define USBD_MAX_SUPPORTED_CLASS 2U
    #define USBD_MAX_CLASS_INTERFACES 2U

    For more examples and support, visit the dedicated branch for STM32H7. It provides many examples of composite builder applications with the CDC class.

    Best Regards
    Hamdi Teyeb

    2 replies

    ST Employee
    October 20, 2025

    Hello @devjeetmandal09 

    After reviewing your main application, I noticed that you assigned the same class ID (0) to multiple classes. This is incorrect. You must assign different IDs to each class instance.

    Below is the correct implementation for adding classes:

    uint8_t CDC_EpAdd_Inst[3] = {CDC_IN_EP, CDC_OUT_EP, CDC_CMD_EP}; /* CDC Endpoint Adress */
    uint8_t MSC_EpAdd_Inst[2] = {MSC_EPIN_ADDR,MSC_EPOUT_ADDR}; /*MSC Endpoint Adress */
    uint8_t CDC_InstID= 0;
    uint8_t MSC_InstID= 0;
     /* Init Device Library */
     USBD_Init(&USBD_Device, &COMPOSITE_Desc, 0);
    /* Store CDC Instance Class ID */
    	CDC_InstID = USBD_Device.classId;
     /* Register CDC class first instance */
     USBD_RegisterClassComposite(&USBD_Device, USBD_CDC_CLASS, CLASS_TYPE_CDC, CDC_EpAdd_Inst);
    /* Store MSC Instance Class ID */
    	MSC_InstID = USBD_Device.classId;
     /* Register CDC class second instance */
     USBD_RegisterClassComposite(&USBD_Device, USBD_MSC_CLASS, CLASS_TYPE_MSC, MSC_EpAdd_Inst);
    
     /* Add CDC Interface Class */
     if (USBD_CMPSIT_SetClassID(&USBD_Device, CLASS_TYPE_CDC, 0) != 0xFF)
     {
     USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops);
     }
    
     /* Add CDC Interface Class */
     if (USBD_CMPSIT_SetClassID(&USBD_Device, CLASS_TYPE_MSC, 1) != 0xFF)
     {
     USBD_CDC_RegisterInterface(&USBD_Device, &USBD_MSC_Template_fops);
     }
     /* Start Device Process */
     USBD_Start(&USBD_Device);

    Additionally, add the necessary configurations in the usbd_conf.h file to enable the composite class, including both MSC and CDC:

    /* Activate the composite builder */
    #define USE_USBD_COMPOSITE
    
    /* Activate HID and MSC classes in composite builder */
    #define USBD_CMPSIT_ACTIVATE_CDC					1U
    #define USBD_CMPSIT_ACTIVATE_MSC					1U

    Set the media packet for MSC:

    /* MSC Class Config */
    #define MSC_MEDIA_PACKET 512U

    The setup of this media packet ensures efficient reading and writing of data blocks during USB communication.

     

    For further guidance, refer to the article How to implement a USB composite device application with MSC and HID classes 

    It provides detailed instructions and example for setting up the mass storage class (MSC) alongside other classes in a composite USB device.

     

    Visitor II
    October 22, 2025

    Hello T_Hamdi, 
    Thanks for your reply. I have updated few things in code.

    1. MX_USB_DEVICE_Init

    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();
     }
    
     /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
     cdcClassId = hUsbDeviceFS.classId;
     if(USBD_RegisterClassComposite(&hUsbDeviceFS, USBD_CDC_CLASS, CLASS_TYPE_CDC, cdcEpInst) != USBD_OK)		{
    	 Error_Handler();
     }
    
     mscClassId = hUsbDeviceFS.classId;
     if(USBD_RegisterClassComposite(&hUsbDeviceFS, USBD_MSC_CLASS, CLASS_TYPE_MSC, mscEpInst) != USBD_OK)		{
    	 Error_Handler();
     }
    
     if (USBD_CMPSIT_SetClassID(&hUsbDeviceFS, CLASS_TYPE_CDC, cdcClassId) == 0xFF)		{
    	 Error_Handler();
     }
    
     if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK)
     {
     Error_Handler();
     }
    
     if (USBD_CMPSIT_SetClassID(&hUsbDeviceFS, CLASS_TYPE_MSC, mscClassId) == 0xFF)		{
    	 Error_Handler();
     }
    
     if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
     {
     Error_Handler();
     }
     /* USER CODE END USB_DEVICE_Init_PreTreatment */
    
     if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
     {
     Error_Handler();
     }
    
     /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
     HAL_PWREx_EnableUSBVoltageDetector();
    
     /* USER CODE END USB_DEVICE_Init_PostTreatment */
    }

     

    2. USBD_LL_Init

    USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
    {
     /* Init USB Ip. */
     if (pdev->id == DEVICE_FS) {
     /* Link the driver to the stack. */
     hpcd_USB_OTG_FS.pData = pdev;
     pdev->pData = &hpcd_USB_OTG_FS;
    
     hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
     hpcd_USB_OTG_FS.Init.dev_endpoints = 9;
     hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
     hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
     hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.battery_charging_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
     if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
     {
     Error_Handler( );
     }
    
    #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
     /* Register USB PCD CallBacks */
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback);
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback);
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback);
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback);
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback);
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback);
     HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback);
    
     HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_OTG_FS, PCD_DataOutStageCallback);
     HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_OTG_FS, PCD_DataInStageCallback);
     HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOOUTIncompleteCallback);
     HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback);
    #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
     /* USER CODE BEGIN TxRx_Configuration */
     HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); // shared for all OUT EPs
    
     HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); // EP0 IN
     HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); // EP1 IN (CDC bulk IN)
     HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 0x80); // EP2 IN (MSC bulk IN)
     HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40); // EP3 IN (CDC CMD/interrupt IN)
     /* USER CODE END TxRx_Configuration */
     }
     return USBD_OK;
    }


    I have added `HAL_PCDEx_SetTxFiFo` according to endpoints.

    #ifndef CDC_IN_EP
    #define CDC_IN_EP 0x81U /* EP1 for data IN */
    #endif /* CDC_IN_EP */
    #ifndef CDC_OUT_EP
    #define CDC_OUT_EP 0x01U /* EP1 for data OUT */
    #endif /* CDC_OUT_EP */
    #ifndef CDC_CMD_EP
    #define CDC_CMD_EP 0x83U /* EP2 for CDC commands */
    #endif /* CDC_CMD_EP */
    
    
    #ifndef MSC_EPIN_ADDR
    #define MSC_EPIN_ADDR 0x82U
    #endif /* MSC_EPIN_ADDR */
    
    #ifndef MSC_EPOUT_ADDR
    #define MSC_EPOUT_ADDR 0x02U
    #endif /* MSC_EPOUT_ADDR */

     

    3. USBD_FS_DeviceDesc

    __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
    {
     0x12, /*bLength */
     USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
     0x00, /*bcdUSB */
     0x02,
     0xEF, /*bDeviceClass*/
     0x02, /*bDeviceSubClass*/
     0x01, /*bDeviceProtocol*/
     USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
     LOBYTE(USBD_VID), /*idVendor*/
     HIBYTE(USBD_VID), /*idVendor*/
     LOBYTE(USBD_PID_FS), /*idProduct*/
     HIBYTE(USBD_PID_FS), /*idProduct*/
     0x00, /*bcdDevice rel. 2.00*/
     0x02,
     USBD_IDX_MFC_STR, /*Index of manufacturer string*/
     USBD_IDX_PRODUCT_STR, /*Index of product string*/
     USBD_IDX_SERIAL_STR, /*Index of serial number string*/
     USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
    };


    Here i have updated 

     0xEF, /*bDeviceClass*/
     0x02, /*bDeviceSubClass*/
     0x01, /*bDeviceProtocol*/

     

    After running the firmware i can see msc device on pc. But in case of cdc, its showing code 28 and code 10. I have attached the image,

    cdc_err.png

     

     

     

     

     

     

     

    Also i am updating the latest files with this post. 

    I believe i am missing something. 
    Any help will be appreciated.

    Best Regards
    Devjeet Mandal

    T_HamdiAnswer
    ST Employee
    October 23, 2025

    Hello @devjeetmandal09 

    Thank you for your effort.

    Please try to increase the size of the buffer to 0x174 in the following line:

    HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x174); // EP3 IN (CDC CMD/interrupt IN)

    Additionally, after reviewing your code, increase the number of interfaces by updating this definition:

    #define USBD_MAX_NUM_INTERFACES 5U

    add the following definitions in usbd_conf.h:

    #define USBD_MAX_SUPPORTED_CLASS 2U
    #define USBD_MAX_CLASS_INTERFACES 2U

    For more examples and support, visit the dedicated branch for STM32H7. It provides many examples of composite builder applications with the CDC class.

    Best Regards
    Hamdi Teyeb