tinyusb icon indicating copy to clipboard operation
tinyusb copied to clipboard

dcd_dwc2.c - reset_core() halts in infinite loop

Open MarekRyn opened this issue 2 years ago • 2 comments

Operating System

Windows 10

Board

Custom STM32H747BGT6

Firmware

Custom firmware with use of TinyUSB lib. Affected file: src/portable/synopsys/dwc2/dcd_dwc2.c

What happened ?

dcd_dwc2.c - function reset_core() halts in infinite loop after restart or power up of MCU. It happens at random times.

Present code:

static void reset_core(dwc2_regs_t * dwc2)
{
  // reset core
  dwc2->grstctl |= GRSTCTL_CSRST;

  // wait for reset bit is cleared
  // TODO version 4.20a should wait for RESET DONE mask
  while (dwc2->grstctl & GRSTCTL_CSRST) { }     // <<---- Software halts here

  // wait for AHB master IDLE
  while ( !(dwc2->grstctl & GRSTCTL_AHBIDL) ) { }

  // wait for device mode ?
}

Solution: As per ST reference manual RM0399 page 2011: The software must also check that bit 31 in this register is set to 1 (AHB Master is Idle) before starting any operation.

Also in HAL original library mentioned check is carried out before reset operation (see: function USB_CoreReset in stm32h7xx_ll_usb.c)

Proposal for corrected code:

static void reset_core(dwc2_regs_t * dwc2)
{
  // wait for AHB master IDLE
  while ( !(dwc2->grstctl & GRSTCTL_AHBIDL) ) { }

  // reset core
  dwc2->grstctl |= GRSTCTL_CSRST;

  // wait for reset bit is cleared
  // TODO version 4.20a should wait for RESET DONE mask
  while (dwc2->grstctl & GRSTCTL_CSRST) { }

  // wait for device mode ?
}

How to reproduce ?

Error happens randomly during restart or powering up of uC.

Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)

N/A

Screenshots

No response

I have checked existing issues, dicussion and documentation

  • [X] I confirm I have checked existing issues, dicussion and documentation.

MarekRyn avatar May 22 '23 15:05 MarekRyn

Your post helps a lot, thanks. I have the exact same problem with STM32F723IE MCU. Custom firmeware, board and using the internal hs phy of the f723. Your solution does not work on my board, but the problem does not happen when I add a delay at the end of dwc2_phy_init().

TinyUsb Configuration

  • NO OS
  • CDC + MSC
  • USB HS
  • DMA

Personal solution in dwc2_stm32.h

static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) {
  if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) {
    // Enable on-chip FS PHY
    dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN;
      
      .
      .
      .

      // Control the tuning interface of the High Speed PHY
      // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver for F7
      USB_HS_PHYC->USB_HS_PHYC_TUNE |= 0x00000F13U;

      // Enable PLL internal PHY
      USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
      #else

      #endif
    }
     HAL_Delay(100);
  }

}

Found this in the Reference manual of STM32F72xxx and STM32F73xxx on site 1216 Image

ST also add a delay after hs_phy init, maybe it is the solution :) found in stm32f7xx_ll_usb.c Image

Zychon avatar Jan 17 '25 10:01 Zychon

Hello,

I'm trying to port to the STM32H747XIH using the STM32H747-DISCO board, using only HS host for CDC, MSC and HID, for three days, and no matter what I do, I always get stuck at: while (dwc2->grstctl & GRSTCTL_CSRST) {}

  • I have already tried an empty project, just simple porting.
  • Then, I adapted the STM32H743 example.
  • Added HAL_PWREx_EnableVddUSB during initialization.
  • Added @static void reset_core(dwc2_regs_t* dwc2):
    while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) { }

Can anybody help me, please?

Thanks!!

eng-software avatar Mar 27 '25 21:03 eng-software

Seeing a similar issue on the STM32WBA65RI.

Dolphindalt avatar Sep 05 '25 22:09 Dolphindalt

re-open since #3126 fix seperated issue on different built-in HS PHY on F723

hathach avatar Sep 10 '25 10:09 hathach

Was able to overcome the issue on the STM32WBA65RI by using a shadow register for the dwc2 version ID before resetting the device.

Dolphindalt avatar Sep 10 '25 16:09 Dolphindalt

@Dolphindalt you mean PR implementation here https://github.com/hathach/tinyusb/pull/3228/files ? If possible can you enable LOG and print out of dwc2 hwcfg register for STM32WBA65RI by check_dwc2(dwc2_regs_t* dwc2).

hathach avatar Sep 11 '25 03:09 hathach

@hathach Yes sir. Here is the log from check_dwc2:

guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
0x00006100, 0x4F54430A, 0x00000000, 0x228FE052, 0x03B882E8, 0xE2103A30

I think in this version of the synopsis dwc2 IP, you cannot read the version from the register once the GRSTCTL_CSRST is set.

Dolphindalt avatar Sep 11 '25 16:09 Dolphindalt

@hathach Yes sir. Here is the log from check_dwc2:

guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
0x00006100, 0x4F54430A, 0x00000000, 0x228FE052, 0x03B882E8, 0xE2103A30

I think in this version of the synopsis dwc2 IP, you cannot read the version from the register once the GRSTCTL_CSRST is set.

In this case it's already fixed by https://github.com/hathach/tinyusb/commit/38f41f5fa28943086cd36653e0914fd59cb7ed03

HiFiPhile avatar Sep 11 '25 16:09 HiFiPhile

I often have h743 hil failed randomly, I think wait for AHB idle is required, it is also mentioned in thee databook as well.

hathach avatar Sep 15 '25 08:09 hathach