cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to run MSC and CDC in composite mode

devjeetmandal09
Associate II

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



1 ACCEPTED SOLUTION

Accepted Solutions

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb

View solution in original post

3 REPLIES 3
T_Hamdi
ST Employee

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.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb
devjeetmandal09
Associate II

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

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb