cancel
Showing results for 
Search instead for 
Did you mean: 

How to select a USB device at startup?

paolog
Associate III

Hi everyone.

I need to activate a different USB device (one only, no multi role) at startup, depending for example on a GPIO status. I have two versions of an application on a STM32WB55 Nucleo board working as MSC in a version and CDC in the other. I tried to combine the codes creating two different descriptors, registering the requested device in function MX_USB_Device_Init() and allocating PMA's in USBD_LL_Init() according to the device.

As I integrated the CDC code in MSC code, the MSC device works well, but the CDC startup code CDC_Init_FS() is never called. My USB init function is:

void MX_USB_Device_Init(void)
{
 /* USB Clock Initialization */
  USBD_Clock_Config();  // MSC and CD codes are the same
 
 /* Init Device Library, add supported class and start the library. */
	switch (USBDmode) {
		case USB_DEVICE_MSC:
			if (USBD_Init(&hUsbDeviceFS, &MSC_Desc, DEVICE_FS) != USBD_OK) {
				Error_Handler();
			}
			if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK) {
				Error_Handler();
			}
			if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK) {
				Error_Handler();
			}
			break;
	
		case USB_DEVICE_CDC:
			if (USBD_Init(&hUsbDeviceFS, &CDC_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();
			}
			break;
	}
 
	 if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
	  Error_Handler();
	 }
}
 

I already increased stack and heap, with no success. Any suggestion will be welcome.

1 ACCEPTED SOLUTION

Accepted Solutions
paolog
Associate III

As expected, there was an error in the integration of the two devices... In usbd_desc.c I didn't notice I had to duplicate the function Get_SerialNum() to return the ID's in the correct device serial string.

I therefore added a Get_CDC_SerialNum() returning the values into USBD_CDC_StringSerial[].

All is working now and I finally have a different device on startup as I wanted!

View solution in original post

3 REPLIES 3
TDK
Guru

If they work separately, but don't work when you integrate both into the same project, there is likely an error in how you've integrated them. I don't see any issues in the code you presented but I doubt the problem is there.

If you feel a post has answered your question, please click "Accept as Solution".
paolog
Associate III

Well, I've been checking source differences several times and I couldn't find other differences then the ones I've been integrating, especially because as you did that was my first guess. I'll try to debug the USB communication to find out where it gets blocked.

paolog
Associate III

As expected, there was an error in the integration of the two devices... In usbd_desc.c I didn't notice I had to duplicate the function Get_SerialNum() to return the ID's in the correct device serial string.

I therefore added a Get_CDC_SerialNum() returning the values into USBD_CDC_StringSerial[].

All is working now and I finally have a different device on startup as I wanted!