cancel
Showing results for 
Search instead for 
Did you mean: 

How to create USB FS device with DFU, AUDIO (MIDI) and CDC using stm32_mw_usb_device v2.11.1?

SloBlo
Associate II

Hi community,

I am desperately trying to implement a 3 interface device (DFU, AUDIO (shell become MIDI later) and CDC) using the most recent version of the usbd_composite_builder found at github -> /STMicroelectronics/stm32_mw_usb_device (v2.11.1 at the time of writing). Here is my approach:

1) collect all the files generated by STM32CubeIDE 1.12.1 applying one USB Device class after the other. That way I get some worthful interface and device code generated into the USB_DEVICE folder in the hope I don't need to write everything from scratch using the empty templates

2) patch the contents from the stm32_mw_usb_device into Middlewares/ST/STM32_USB_Device_Library

3) apply some modifications to get things compiled:

usbd_desc.c:

/* USER CODE BEGIN INCLUDE */
#include "usbd_composite_builder.h"
/* USER CODE END INCLUDE */
 
...
 
#define USBD_VID                      1155
#define USBD_LANGID_STRING            1033
#define USBD_MANUFACTURER_STRING      "STMicroelectronics"
#if (USBD_CMPSIT_ACTIVATE_CDC == 1)
#define USBD_PID_FS                   57105 // for DFU PID must be 57105, ST proprietary modification
#else
#define USBD_PID_FS                   21156
#endif
#define USBD_PRODUCT_STRING_FS        "STM32 COMPOSITE DEVICE"
#define USBD_CONFIGURATION_STRING_FS  "CONFIGURATION 0"
#define USBD_INTERFACE_STRING_FS      "COMPOSITE INTERFACE"
 
...
 
in USBD_FS_DeviceDesc:
 
  0xEF,                       /*bDeviceClass*/
  0x02,                       /*bDeviceSubClass*/
  0x01,                       /*bDeviceProtocol*/
...
 
 // how to deal with that part anyhow?
void *USBD_static_malloc(uint32_t size)
{
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
  //static uint32_t mem[(sizeof(USBD_DFU_HandleTypeDef)/4)+1];/* On 32-bit boundary */
  //static uint32_t mem[(sizeof(USBD_AUDIO_HandleTypeDef)/4)+1];/* On 32-bit boundary */
  return mem;
}

usbd_cdc_if.c:

// To conform to new interface design in stm32_mw_usb_device v2.11.1
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0, hUsbDeviceFS.classId);
...
 
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, hUsbDeviceFS.classId);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, hUsbDeviceFS.classId);
  /* USER CODE END 7 */
  return result;
}

usb_device.c:

/* USER CODE BEGIN PV */
 
/* Private variables ---------------------------------------------------------*/
 
uint8_t AUDIO_EpAdd = AUDIO_OUT_EP;    /* AUDIO Endpoint Adress */
 
uint8_t CDC_EpAdd_Inst1[3] = {CDC_IN_EP, CDC_OUT_EP, CDC_CMD_EP}; /* CDC Endpoint Adress First Instance */
 
uint8_t DFU_EpAdd[2] = {DFU_IN_EP, DFU_OUT_EP}; /* DFU Endpoint Adress */
 
/* USER CODE END PV */
 
...
 
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_CMPSIT) != USBD_OK)
//  {
//    Error_Handler();
//  }
 
#if USBD_CMPSIT_ACTIVATE_AUDIO == 1
  if (USBD_RegisterClassComposite(&hUsbDeviceFS, &USBD_AUDIO, CLASS_TYPE_AUDIO, &AUDIO_EpAdd) != USBD_OK)
  {
    Error_Handler();
  }
 
  if (USBD_AUDIO_RegisterInterface(&hUsbDeviceFS, &USBD_AUDIO_fops_FS) != USBD_OK)
  {
    Error_Handler();
  }
#endif
#if USBD_CMPSIT_ACTIVATE_CDC == 1
  if (USBD_RegisterClassComposite(&hUsbDeviceFS, &USBD_CDC, CLASS_TYPE_CDC, CDC_EpAdd_Inst1) != USBD_OK)
  {
    Error_Handler();
  }
  /* Add CDC Interface Class First Instance */
  if (USBD_CMPSIT_SetClassID(&hUsbDeviceFS, CLASS_TYPE_CDC, 0) != 0xFF)
  {
    USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_CDC_Interface_fops_FS);
  }
//  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)
//  {
//    Error_Handler();
//  }
  if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_CDC_Interface_fops_FS) != USBD_OK)
  {
    Error_Handler();
  }
#endif
#if USBD_CMPSIT_ACTIVATE_DFU == 1
  if (USBD_RegisterClassComposite(&hUsbDeviceFS, &USBD_DFU, CLASS_TYPE_DFU, DFU_EpAdd) != USBD_OK)
  {
    Error_Handler();
  }
 
//  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_DFU) != USBD_OK)
//  {
//    Error_Handler();
//  }
  if (USBD_DFU_RegisterMedia(&hUsbDeviceFS, &USBD_DFU_fops_FS) != USBD_OK)
  {
    Error_Handler();
  }
#endif
  if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
  {
    Error_Handler();
  }

usbd_audio.c:

in USBD_AUDIO_Init
 
// To conform to new interface design in stm32_mw_usb_device v2.11.1
 
#ifdef USE_USBD_COMPOSITE
 
  /* Get the Endpoints addresses allocated for this class instance */
 
  AUDIOOutEpAdd  = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, pdev->classId);
 
#endif /* USE_USBD_COMPOSITE */
...
 
in USBD_AUDIO_DeInit
 
// To conform to new interface design in stm32_mw_usb_device v2.11.1
 
#ifdef USE_USBD_COMPOSITE
 
  /* Get the Endpoints addresses allocated for this class instance */
 
  AUDIOOutEpAdd  = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, pdev->classId);
 
#endif /* USE_USBD_COMPOSITE */
...
 
in USBD_AUDIO_DataOut
 
// To conform to new interface design in stm32_mw_usb_device v2.11.1 
#ifdef USE_USBD_COMPOSITE 
  /* Get the Endpoints addresses allocated for this class instance */
 
  AUDIOOutEpAdd  = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, pdev->classId);
 
#endif /* USE_USBD_COMPOSITE */

4) This is compiled and flashed to a NUCLEO-F429ZI . Without plugging to host, the application (flashing LEDs when USER button is pressed) runs fine.

5) Plugging in to a Windows 10, the usb device shows up in device manager as "STM32 COMPOSITE DEVICE", but there are no further devices listed. Using USBPcap, I gathered the following descriptors communicated to the host:

DeviceDescriptor:

12010002EF020140830411DF00020102

0301

ConfigurationDescriptor1:

0902B700040104C032

ConfigurationDescriptor2:

0902B700040104C032080B0002010100

00090400000001010000092401000127

0001010C240201010100010000000009

24060201010100000924030301030002

00090401000001020000090401010101

020000072401010101000B2402010202

100180BB0009050101C0000100000725

0100000000080B020202020100090402

00010202010005240010010524010003

04240202052406020307058203080010

09040300020A00000007058102400000

07050202400000

The application does not run anymore after plugging to the host.

6) The full project can be found at github -> SloBloLabs/NUF429ZIGNUCMTC/tree/feature/usbdevice .

I am somewhat stuck at this point due to my limited knowledge on the subject. Could someone out there kindly share some advice how to move on with this? That would be very much appreciated. Is it possible to run 3 interfaces under the same device using this technology, anyhow?

Thank you so much in advance :)

Best,

Oliver

3 REPLIES 3
Piranha
Chief II

Don't waste your time on a broken bloatware and look at an USB stack developed by people, who understand what they are doing:

https://github.com/hathach/tinyusb/tree/master/examples/device

SloBlo
Associate II

Hi everyone,

so I've got this composite device descriptor ready and MIDI + CDC are happily working together. You may inspect github -> /SloBloLabs/NUF429ZIGNUCMTC/tree/feature/usbdevice for more details.

However, though the DFU-device is configured, the pulling BOOT0 high and resetting the device, no USB device for DFU upload is created. Would someone have a hint where to look at to get the DFU programming device firing up? CDC and MIDI would not be required in that mode, of course!

SloBlo
Associate II

Totally got this wrong. The ROM DFU bootloader is totally sufficient for my purpose. So, DFU is removed from the composite device. If anyone is interested, CDC + MIDI using stm32_mw_usb_device v2.11.1 is available at the location shared above. This request is closed from my end.