cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 USB-HOST (dis)connect bouncing

Microman
Associate III

Hi all,

I have a STM32H743 running at 400MHz with simple USB 1 wiring to an USB A jack. It works fine, no issues, runs for hours with thousands of read and write operations.

But there is one little issue that drives me crazy:

If I plug in and unplug one specific USB Stick (Intenso 8GB) sometimes after removing the stick (no read/write ongoing!), I see "USB Device disconnected" in the log (which is perfectly correct when unplugging an USB stick) but just a millsecond later, I get also "USB Device Connected" again - even though there is nothing connected to the port! After this occures, there is nothing more happening in the USB subsystem. Reconnecting any other stick does not change anything - untill a reset of the STM32, there are no more reactions, no events, no USB (dis)connect anymore.

This only happens from time to time and only with some sticks. With the SanDisk 64GB "Ultra Flair" for example, I never experienced this issue. At first, to me this looked like some hardware bounce effect, but I cannot find any unual signal behaviour on the lines.

Any ideas how to solve this? Maybe by inserting some delay(sleep) after disconnet event?

Middleware is:

  • FreeRTOS V10.0.1
  • STM32Cube FW_H7 V1.6.0

Hardware:

  • ESDA6V1BC6 USB Surge protection at the USB jack
  • 90 Ohm traces, same length, symmetrical wiring
  • only 20mm trace length between STM32 an USB Jack
  • 5V 1A permanent power, filtered with 0.1uF cer and 22uF low ESR

1 ACCEPTED SOLUTION

Accepted Solutions
Microman
Associate III

"crude example" =)

ST is telling a different story at the fairs like "Faster time to market, save cost and time thanks to Cube" etc

BTW I am not here to reveal shocking news or something - I'm only pointing at things that are not working fine and try to find guys who had similiar issues.

Anyway, I fixed at least the disconnect debounce issue:

added a timer variable to HCD_HandleTypeDef;

STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hcd.h

81a82

>  __IO uint32_t           Timer;

ignored and cleared any IRQs for 200ms after disconnect

STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hcd.c

498a501,506

>  

>  if(hhcd->Timer > HAL_GetTick()) {

>    /* we have to wait, clear all events */

>    __HAL_HCD_CLEAR_FLAG(hhcd, 0xFFFFFFFF);

>    return;

>  }

547a556

>        hhcd->Timer = HAL_GetTick() + 200; /*TODO create a define in config file */

There are more issues with USB MSC - but that will be another thread.

View solution in original post

10 REPLIES 10

Debug as usually - observe the USB lines using oscilloscope/LA/protocol analyzer, instrument the code and trace it after the disconnect, possibly outputting states to pins being observed synchronously with the USB lines.

JW

Microman
Associate III

Yes thanks! Already had an eye(Scope) on the lines. I did not found something unusal. Another issue is that the STM32H7 USB subsystem sometimes does not catch the unplug/disconnect event and stays in "connected" state. Because there are no more SOF events, pHost->timer is not updated anymore and the whole USB subsystem hangs. I changed the time source in usb_msc.c to xTaskGetTickCount() which solved at least the dead lock. But I still do not know, why it sometime misses the plug/unplugs...

Pavel A.
Evangelist III

We've seen similar behavior with STM32F446 USB host and fatfs.

Had no time to debug, so just delayed mounting the USB drives for ~200 ms.

If the drive remained connected, proceed with mount.

-- pa

> Already had an eye(Scope) on the lines. I did not found something unusal.

Then it is probably a software problem.

> Another issue is that the STM32H7 USB subsystem sometimes does not catch the unplug/disconnect event and stays in "connected" state. Because there are no more SOF events,

What is "connected" state in terms of the USB registers? For "no more SOF events you observed the GINTSTS register in USB interrupt?

I don't Cube.

> delayed mounting

Well, if it avoids the problem, even if symptomatically, why not.

JW

Microman
Associate III

I did a bit of debugging and found out that the false connect detection (as any other USB connect event) deactives the DISCINT interrupt in GINTMSK (USB int.mask reg -> 0) insinde HCD_Port_IRQHandler(). However the DISCINT flag itself still works and shows that we are in a correct disconnected state (logical 1). It is just the USB HOst stack that did not get the latest disconnect state. I can get back to proper USB operation by clearing DISCINT (writing a 1 to it) and enable DISCINT in GINTMSK. After these two bit operations, I can unplug/plug the USB Stick and everything works fine again.

I don't know for what reason ST masks and unmasks the DISCINT inside the HCD_Port_IRQHandler() each time a stick is inserted - to be honest, I did not dig deeper into this machinery. It would be nice I could use the USB host code from ST without any "work arounds".

Microman
Associate III

Here is what happens when unplugging a certain USB stick (Mass Storage Class)

0690X00000DXGtZQAX.png

The first disconnect irq is poperly handled. HCD-IRQ shows the execution of the disconnect callback routine wich takes a moment.

Directly after this, a connect is detected again witch is also properly handled, but the next event 114us later shows another port connect (USB_OTG_HPRT_PCDET and USB_OTG_HPRT_PCSTS are 1) and a disconnect (USB_OTG_GINTSTS_DISCINT) at the same time.

This kills the Cube USB stack and due to this, it stays in the connected state forever. Later (dis)connects also do produce irqs but these will not bring back the USB stack back into operational mode.

OK, so the connection-detection circuit bounces. That is no news, and that it occurs only with certain devices is not anything shocking either.

And doesn't sound that impossible to tackle either, once you know what's the root cause of the problem.

> It would be nice I could use the USB host code from ST without any "work arounds".

Yes but it's not the case. Consider it as a crude example, showcasing the peripherals' capabilities, rather than production-ready code.

JW

Microman
Associate III

"crude example" =)

ST is telling a different story at the fairs like "Faster time to market, save cost and time thanks to Cube" etc

BTW I am not here to reveal shocking news or something - I'm only pointing at things that are not working fine and try to find guys who had similiar issues.

Anyway, I fixed at least the disconnect debounce issue:

added a timer variable to HCD_HandleTypeDef;

STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hcd.h

81a82

>  __IO uint32_t           Timer;

ignored and cleared any IRQs for 200ms after disconnect

STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hcd.c

498a501,506

>  

>  if(hhcd->Timer > HAL_GetTick()) {

>    /* we have to wait, clear all events */

>    __HAL_HCD_CLEAR_FLAG(hhcd, 0xFFFFFFFF);

>    return;

>  }

547a556

>        hhcd->Timer = HAL_GetTick() + 200; /*TODO create a define in config file */

There are more issues with USB MSC - but that will be another thread.

> Faster time to market, save cost and time thanks to Cube

That is probably the case if your application matches the usage model of Cube (and you don't hit an error - but that happens with any approach) - as is the case of any "library", it has an inevitably limited scope. I don't know how fast and cheap it can get, my applications never got into that matching cathegory.

> crude

In the role of examples, I mean. This again may be sufficient for the intended usage.

Can't the bouncing be problem at connect event, too (again, maybe with some particular device)? Pavel appears to hint in that direction.

Thanks for coming back with the solution. Please select your post as Best, so that the thread is marked as solved.

JW