We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.
Problem still presists in V2.xx drivers. That is, if RTE_Device.h is used for configuration, MX_USB_OTG_HS_ULPI_D7_Pin is not defined at all, so it won't work. I suggest following solution:
static int32_t USBD_DeviceDisconnect (void) { if (hw_powered == false) { return ARM_DRIVER_ERROR; } OTG->DCTL |= OTG_HS_DCTL_SDIS; // Soft disconnect enabled #if !defined(RTE_USB_OTG_HS_ULPI_D7_PIN) && !defined(RTE_USB_OTG_HS_ULPI_D7_PIN) OTG->GCCFG &= ~OTG_HS_GCCFG_PWRDWN; // Enable power down #endif return ARM_DRIVER_OK; }
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