# STM32 USB host will not return from reset request

Note: I have edited this question from its original content since I was able to find a deeper cause/symptom for the problem. I have re-written it to focus on that instead.

I am using a pretty basic configuration for the STM32F405 using the CubeMX configuration system.

Something (a clock, a setting.. something) is not configured correctly, and I can't tell how I could have possibly caused it. Though it could be a problem with the PCB I designed, that seems unlikely as the code runs and debugs and the SysTick interrupt is advancing the timing counter just fine.

I have tracked part of the problem down to this function

/* Reset after a PHY select and set Host mode */
USB_CoreReset(USBx)


Which times out, presumably because the core never comes out of reset (OTG_FS_GRSTCTL:CSRST == 1 always, after being set in that function. USB_CoreReset() tries to read CSRST==0 200,000 times, and if it fails it returns unsuccessfully).

If you would like to generate this file and look at the output (or adapt it to your board), you can take this text and paste it into a file called "USB CSRST Problem.ioc". Note: It will probably require some tweaking for your board since I have some pins assigned to outputs for an LCD display.

I have tracked a discussion down that describes similar symptoms, but I can confirm that my code does set OTG_HS_GUSBCFG:PHYSEL properly (confirmed setting bit 6 before the reset is performed), and generally adheres to the recommended startup procedure as outlined in that thread.

Clocks configuration:

• Check if have you have been using the latest stm32cube hal libraries , they constantly update them because they contain bugs mainly in USB , CAN and ethernet . and if you are using compiler like KEIL MDK then install the latest library package . The current state of software development for stm32 is a mess IMO. – ElectronS Mar 25 '16 at 12:05
• I did this. Unfortunately they haven't fixed the VBUS activate bug, so I had to fix that again. (ie in the library: //this function turns on VBUS, next line: calls function with parameter that turns off VBUS). And semihosting quit working again. And my problem didn't budge. Legit tip though. – Daniel Mar 25 '16 at 19:55
• Got semihosting back. Forgot that you have to \n every printf, or you have to setbuf(stdout, NULL); for it to actually flush the buffer promptly. – Daniel Mar 25 '16 at 21:00
• Are u debugging using simulator or real time? – Akshay Immanuel D Mar 29 '16 at 7:42
• how are you so sure that your hardware is ok and the whole problem is in software ? when you face such problems , you have to start all over from capacitors and resistors to oscillators to see if you missed anything in schematic or in soldering the PCB . – ElectronS Apr 4 '16 at 11:15

Since you didnot upload the whole cubemx and generated code for the project i cannot fully try to replicate and find the problem.

But i will try to point you into few things that might/mightnot help :

1- make sure that global non maskable interrupts are enabled , inaddition to USB OTG gloabl interrupt. in the configuration window , NVIC tab in cubemx project.

2- make sure you are using the correct mode , (using RTOS or standalone project , becuase the code generator may change things in RTOS mode or using DMA because DMA usually consider the interrupt as a request event). your problem might be somewhere else which is preventing write to this register, something like the lock sequence used for mapping I/O and peripherals.

3- There is 2 things called GINTMSK , a bit in OTG_FS_GAHBCFG register

and a a register called : OTG_FS_GINTMSK

4- The correct programming sequence is used :

5- Search in smt32cube directory / projects / stm32xx discovery / applications/ in this folder you will find multiple projects on USB applications depending on your deivce , use these codes as starter and compare the initalization to your code.

• I am familiar with this page of the manual, but the Cube code does not follow it, really at all. – Daniel Mar 30 '16 at 16:06
• For example, I added debug messages to (one of the two) functions that turns on the USB VBUS line, and it is called three different times. – Daniel Mar 30 '16 at 16:07
• Credit for making an attempt. Still a lot of work left to do to figure this out unfortunately. Tomorrow I start mapping every bit of every register being touched in the USB subsystem... :( – Daniel Apr 1 '16 at 5:56
• You were right in the comments to my question. The external clock was not oscillating. That creates a new mystery of how the code was executing when it should have been running from that clock (and I don't have clock protection turned on). I just needed someone to force me to question everything. That's worth 1,000,000 internet points as far as I'm concerned. – Daniel Apr 4 '16 at 21:02
• i have been their before , facing problem that could drive one crazy and very difficult to trace , (sometimes wrong footprint , sometimes datasheet mistakes , eratta , you name it) , The thing is that maybe the debugger (st-link) was providing the clock ?? – ElectronS Apr 5 '16 at 7:37

So, here is the resolution.

@ElectronS was correct, sometimes you have to assume you don't know anything for sure. For example, I knew for sure that my 24MHz external oscillator was working fine because the whole core was running from it, according to the code generation configurator.

Well, apparently the STM32 will not allow you to select the external oscillator if it is not running. Or something. I don't have a good explanation.

Here is the core of the core of the problem: the Abracon ASDMB datasheet.

When it says

What it means is

Which might more accurately be written as $\overline{Standby}$...

tl;dr the oscillator Enable pin was pulled low.

Thanks for all the feedback and pushing me to challenge my established thinking that had me stuck.

• good work as they say the devil is in the details , finally we can sleep now:) – ElectronS Apr 5 '16 at 7:31

I think what was happing is that , even though your oscillator is not providing clock , the micocontroller was running at power on from its internal RC oscillator . Heres a qoute from Things to remember when coding stm32

"Don't forget to enable the external or internal oscillator that you need to use for SYSCLK. At power-on for default is enabled the internal RC oscillator HSI."

There should be also a startup timer that forces the micro into reset until the oscillator is stable and from the PLL to lock ( i used that in dspic processors ) , if clock is not stable switchover from internal RC to external doesnot happen and program gets stuck.