This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bug in HS USB device driver for STM32F4xxx (Middleware)

There's a nasty bug hidden in USBD_HS_STM32F4xx.c driver code.
It ALWAYS enables on-chip HSUSB PHY even if device is configured to use external PHY,
making PB15 wrongly routed to PHY instead of another configured peripheral (SPI2 MOSI in my case).

Fix is very simple:

static int32_t USBD_DeviceConnect (void) {
  if (!(otg_hs_state & OTG_HS_USBD_DRIVER_POWERED) ) { return ARM_DRIVER_ERROR; }
  if (  otg_hs_state & OTG_HS_USBD_DRIVER_CONNECTED) { return ARM_DRIVER_OK; }

  OTG->DCTL    &= ~OTG_HS_DCTL_SDIS;    // Soft disconnect disabled
#ifndef RTE_USB_OTG_HS_PHY
  OTG->GCCFG   |=  OTG_HS_GCCFG_PWRDWN;
#endif

  otg_hs_state |=  OTG_HS_USBD_DRIVER_CONNECTED;
  return ARM_DRIVER_OK;
}

It caused me a lot of headache, so I would like to share it with anyone that might have the similar
problem.

Parents
  • Talking about latest released STM32F4xx_DFP pack v2.10.0, and assuming Classic Framework is used.

    From expectation of functionality currently driver looks as expected.
    If External ULPI high-speed PHY is selected with RTE_USB_OTG_HS_PHY = 1 in OTG_HS_STM32F4xx.h header file the MX_USB_OTG_HS_ULPI_D7_Pin will get defined, else if On-chip full-speed PHY is selected in RTE_Device.h then MX_USB_OTG_HS_ULPI_D7_Pin will not get defined thus it is used in driver to figure out at compile time if external PHY or on-chip PHY is used.

    So, if MX_USB_OTG_HS_ULPI_D7_Pin is not defined means on-chip PHY is used and code should address that in driver (it looks like it does).

    BTW, in your suggestion you have twice same condition "!defined(RTE_USB_OTG_HS_ULPI_D7_PIN)" && "!defined(RTE_USB_OTG_HS_ULPI_D7_PIN)", probably an overlook. Also, in your suggestion RTE_USB_OTG_HS_ULPI_D7_PIN is always defined as it is done so by RTE_Device.h so your suggestion is same if you would have written

    #if 1
      OTG->GCCFG &= ~OTG_HS_GCCFG_PWRDWN;   // Enable power down
    #endif
    
    

    unless you manually change RTE_USB_OTG_HS_ULPI_D7_PORT_ID to value different than 0, in which case preprocessor would throw an error.

    It might be that there is some problem with functionality that you expect, we can try to clarify that?

    Best regards, Milorad

Reply
  • Talking about latest released STM32F4xx_DFP pack v2.10.0, and assuming Classic Framework is used.

    From expectation of functionality currently driver looks as expected.
    If External ULPI high-speed PHY is selected with RTE_USB_OTG_HS_PHY = 1 in OTG_HS_STM32F4xx.h header file the MX_USB_OTG_HS_ULPI_D7_Pin will get defined, else if On-chip full-speed PHY is selected in RTE_Device.h then MX_USB_OTG_HS_ULPI_D7_Pin will not get defined thus it is used in driver to figure out at compile time if external PHY or on-chip PHY is used.

    So, if MX_USB_OTG_HS_ULPI_D7_Pin is not defined means on-chip PHY is used and code should address that in driver (it looks like it does).

    BTW, in your suggestion you have twice same condition "!defined(RTE_USB_OTG_HS_ULPI_D7_PIN)" && "!defined(RTE_USB_OTG_HS_ULPI_D7_PIN)", probably an overlook. Also, in your suggestion RTE_USB_OTG_HS_ULPI_D7_PIN is always defined as it is done so by RTE_Device.h so your suggestion is same if you would have written

    #if 1
      OTG->GCCFG &= ~OTG_HS_GCCFG_PWRDWN;   // Enable power down
    #endif
    
    

    unless you manually change RTE_USB_OTG_HS_ULPI_D7_PORT_ID to value different than 0, in which case preprocessor would throw an error.

    It might be that there is some problem with functionality that you expect, we can try to clarify that?

    Best regards, Milorad

Children
No data