cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4R9: Switching from USB Device to USB Host fails

TJvV
Associate

Hi,

 

I'm using an STM32L4R9 on a custom board with USB.

The project has the Host Only and Device Only implementations of the CDC Device and a MSC Host stacks.

As we don't have a USB-ID pin, we can't really use the normal OTG behaviour, so the project is configured for Host Only mode.

In my default FreeRTOS task I start out in one mode, and after being disconnected for a certain timeout, I will switch to the other mode, to see if that one does find a device/host.

 

The default task looks a bit like this:

void StartDefaultTask(void *argument)
{
  appState.isUSBDEVICE = false;
  MX_USB_HOST_Init();

  for(;;){
    if (appState.isUSBDEVICE) {
      // Running CDC Device stack
      if ((hUsbDeviceFS.dev_state == USBD_STATE_DEFAULT) || ((hUsbDeviceFS.dev_state == USBD_STATE_SUSPENDED))) {
        // No active connection
        if( timeout ){
          USBD_Stop(&hUsbDeviceFS);
          USBD_DeInit(&hUsbDeviceFS);

          appState.isUSBDEVICE = false;
          MX_USB_HOST_Init();
        }
      }
    }
    else {
      // Running MSC Host stack
      if( hUsbHostFS.gState == HOST_IDLE){
        // No active connection
        if( timeout ){
          USBH_Stop(&hUsbHostFS);
          USBH_DeInit(&hUsbHostFS);

          appState.isUSBDEVICE = true;
          MX_USB_DEVICE_Init();
        }
      }
    }
  }

 

What I have noticed here, is that the CDC Device stack seems to work pretty reliably with some mode switches in between.

The MSC Host however, does not get any interrupts after the first iteration.

Digging through the stack with my debugger, I stumbled upon a call in HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd): USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);

This call keeps returning HAL_ERROR after the first time.

 

I saw in the Reference Manual a note about the OTG_GUSBCFG register:

This register can be used to configure the core after power-on or a changing to host mode
or device mode. It contains USB and USB-PHY related configuration parameters. The
application must program this register before starting any transactions on either the AHB or
the USB. Do not make changes to this register after the initial programming.

 

But I didn't find anything about how to reset the peripheral beyond the USB_CoreReset(USBx) call that's already done before trying to switch the mode.

 

What am I missing for properly switching back to HOST mode?

 

 

 

2 REPLIES 2
Imen.D
ST Employee

Hello @TJvV,

You need to stop ("xxxDeinit") the stack in one mode and switch the mode.

Then, start the whole stack of the other mode, when the ID pin state changes.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hi, @Imen.D 

Thank you for your reply.

I thought my calls to

USBH_Stop(&hUsbHostFS);
USBH_DeInit(&hUsbHostFS);

 and

USBD_Stop(&hUsbDeviceFS);
USBD_DeInit(&hUsbDeviceFS);

were the functions you are talking about for stopping the stack?

Are there other stop functions I'm not aware of?

 

Also, as I mentioned, I have no ID pin in use (there's also none on the connector used).

Do I need to manually emulate the ID pin (by writing GPIO)?