cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5 USB Interrupt Based Approach

Rajendra_2002
Associate II

I am using the STM32U585RIT6 microcontroller with the B-U585I-IOT02A development kit. I need to implement USB functionality using an interrupt-based approach.

In my project, I have configured USB_OTG_FS in Device-only mode, enabled the NVIC global interrupt, and enabled USBX CDC-ACM. I am using bare-metal code (no RTOS or ThreadX).

After completing all the USB configurations, inside the MX_USBX_Device_Init() function I added the following initialization:

RX FIFO and TX FIFO configurations

USBX DCD initialization using _ux_dcd_stm32_initialize()

Started the PCD using HAL_PCD_Start()

In the main while loop, I am calling ux_device_stack_tasks_run(). With this setup, the USB device starts correctly and is detected as a Virtual COM Port.

Now, I want to handle USB connect and disconnect events using interrupts. For this, VBUS sensing may need to be enabled. While referring to the B-U585I-IOT02A schematic, the USB_VBUS_SENSE pin is shown as PF14. However, in the MCU datasheet and in STM32CubeIDE, PA9 is assigned as the VBUS sense pin.

Please clarify what the correct solution is in this case, and how to properly implement interrupt-based USB connect/disconnect handling? If there are any reference examples related to this scenario, it would be helpful, as I could only find CDC-ACM–related examples.

2 REPLIES 2
Gyessine
ST Employee

Hello @Rajendra_2002 
Since you are using the B-U585I-IOT02A board, use the PF14 pin because it already includes the hardware required for VBUS sensing.
And to handle connect and disconnect events, you basically just need to manipulate these two functions.

HAL_HCD_Connect_Callback(hhcd);
HAL_HCD_Disconnect_Callback(hhcd);

Here is an example of an HID host example where these functions are used:

static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
{
  const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  uint32_t USBx_BASE = (uint32_t)USBx;
  __IO uint32_t hprt0;
  __IO uint32_t hprt0_dup;

  /* Handle Host Port Interrupts */
  hprt0 = USBx_HPRT0;
  hprt0_dup = USBx_HPRT0;

  hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
                 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);

  /* Check whether Port Connect detected */
  if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  {
    if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
    {
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
      hhcd->ConnectCallback(hhcd);
#else
      HAL_HCD_Connect_Callback(hhcd);
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
    }
    hprt0_dup |= USB_OTG_HPRT_PCDET;
  }

  /* Check whether Port Enable Changed */
  if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  {
    hprt0_dup |= USB_OTG_HPRT_PENCHNG;

    if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
    {
      if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
      {
        if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
        {
          (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
        }
        else
        {
          (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
        }
      }
      else
      {
        if (hhcd->Init.speed == HCD_SPEED_FULL)
        {
          USBx_HOST->HFIR = HFIR_60_MHZ;
        }
      }
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
      hhcd->PortEnabledCallback(hhcd);
#else
      HAL_HCD_PortEnabled_Callback(hhcd);
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */

    }
    else
    {
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
      hhcd->PortDisabledCallback(hhcd);
#else
      HAL_HCD_PortDisabled_Callback(hhcd);
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
    }
  }

  /* Check for an overcurrent */
  if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  {
    hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  }

  /* Clear Port Interrupts */
  USBx_HPRT0 = hprt0_dup;
}

You can also read STM32Cube USB host library It may also help you.
Hope that helps.
BR
Gyessine

 

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.

Thanks for the information. I tested multiple scenarios to handle USB connect and disconnect events. First, I enabled VBUS sensing for USB_OTG_FS using PA9 and tried to capture interrupts, but the code did not enter HAL_PCD_ConnectCallback() or HAL_PCD_DisconnectCallback().
Next, I disabled VBUS sensing and configured PF14 as a GPIO EXTI with NVIC global interrupts enabled, but the interrupt was not triggered.
I then tried enabling both VBUS sensing on PA9 and configuring PF14 as GPIO EXTI, but unfortunately none of the interrupts were triggered. Additionally, in all scenarios the USB virtual COM port failed to start, and the code still did not enter either HAL_PCD_ConnectCallback() or HAL_PCD_DisconnectCallback()