cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750 and USB3300-EZK Startup Issue

synclavierdigital
Associate II

My design uses a STM32H750VBT6 MCU with the USB3300-EZK PHY for high-speed USB. The hardware and software implementations are complete and in general everything works extremely will.

The only issue I am seeing is that there are occasional startup problems with the host computer (both Mac and Linux) reading the device descriptor. This occurs about 10% of the time. The Linux error log is:

<6>[19177.992026] usb 1-1.1.4: new full-speed USB device number 75 using xhci-hcd
<3>[19178.072046] usb 1-1.1.4: device descriptor read/64, error -32
<3>[19178.260043] usb 1-1.1.4: device descriptor read/64, error -32
<6>[19178.448021] usb 1-1.1.4: new full-speed USB device number 76 using xhci-hcd
<3>[19178.528074] usb 1-1.1.4: device descriptor read/64, error -32
<3>[19178.716051] usb 1-1.1.4: device descriptor read/64, error -32

A normal connection log as follows:

<6>[19166.984026] usb 1-1.1.4: new high-speed USB device number 74 using xhci-hcd
<6>[19167.084645] usb 1-1.1.4: New USB device found, idVendor=0483, idProduct=5730, bcdDevice= 0.04
<6>[19167.084664] usb 1-1.1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3

I don't believe there are any hardware issues. I am using an Epson CMOS Standard Clock Oscillator for the 3300 clock source. I could not find any documentation on any different setup needed for the 3300 to use a CMOS Clock Oscillator instead of a crystal directly.

In response to the descriptor error, I both reset and the 3300 and the MCU via software and do a full reboot. In about 90% of the cases the chip comes up correctly after the reboot. But in about 10% of the cases the chip continues to negotiate a full-speed connection with the host and the only solution is to fully power cycle the entire device.

I gather for some reason the "USB Chirp" negotiation is failing, but I am not set up to diagnose those kind of USB problems.

Simple questions: The STM32CubeH7 code base (which is excellent by the way!) does not provide a mechanism to access the external ULPI registers directly (yes I have look quite deeply; the earlier GRXFSP register does not seem to exist in the H7 series). So is there any setup of the 3300 required to use an external standard oscillator instead of a physical crystal?

In response to the failed speed negotiation, I am sometimes able to get the system to recover by using the USB3300 RESET line (active high), and doing a full MCU soft reset and reboot. But about 10% the time the USB3300 gets into a state where it will  never connect to the host computer; the only solution in that case is to power cycle the entire device.

So second simple question, is there a way to fully reset the USB3300 from the MCU? I have tried using the USB3300 RESET pin (which documents that it does not reset the registers), as well as the Cube's PSV_PCD_Init, PSV_PCD_DeInit, USBD_Init and USBD_DeInit functions. 90% of the time those reset functions do allow me to reset the chip and the connection will succeed the second time. But about 10% of the time the 3300 will never connect with the host until the complete device is power-cycled.

Any hints?

1 ACCEPTED SOLUTION

Accepted Solutions
synclavierdigital
Associate II

Aha I believe I have solved the issue. The reference manual for STM32H750 (publication RM0433) describes the XCVRDLY bit in the OTG_DCFG register. That bit is not defined in the stm32cubeh7 library. The documentation describes it as follows:

Bit 14 XCVRDLY: Transceiver delay
  Enables or disables delay in ULPI timing during device chirp.
  0: Disable delay (use default timing)
  1: Enable delay to default timing, necessary for some ULPI PHYs

Apparently the USB3300 ULPI PHY is one of the devices that requires that setting. By setting bit 14 in the OTG_DCFG register it appears I am able to establish HS USB communication reliably using the USB 3300.

That bit definition could be added to STM32 Cube and if someone would guide me through the process I will contribute that source line.

View solution in original post

3 REPLIES 3
synclavierdigital
Associate II

Aha I believe I have solved the issue. The reference manual for STM32H750 (publication RM0433) describes the XCVRDLY bit in the OTG_DCFG register. That bit is not defined in the stm32cubeh7 library. The documentation describes it as follows:

Bit 14 XCVRDLY: Transceiver delay
  Enables or disables delay in ULPI timing during device chirp.
  0: Disable delay (use default timing)
  1: Enable delay to default timing, necessary for some ULPI PHYs

Apparently the USB3300 ULPI PHY is one of the devices that requires that setting. By setting bit 14 in the OTG_DCFG register it appears I am able to establish HS USB communication reliably using the USB 3300.

That bit definition could be added to STM32 Cube and if someone would guide me through the process I will contribute that source line.

FBL
ST Employee

Hi @synclavierdigital 

Thank you for your feedback.

Bit 14 was not documented in the previous version of RM. This is an old issue discussed also here.

An internal ticket CDM0061111 is submitted to dedicated team to add this feature, when using some external PHY.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.




Best regards,
FBL
synclavierdigital
Associate II

To get my design to work fully I need a more specific delay in USB_CoreReset(). Version  1.11.6 of the stm32h7xx-hal-driver has an attempted fix as follows:

 /* Wait for AHB master IDLE state. */
  do
  {
    count++;

    if (count > HAL_USB_TIMEOUT)
    {
      return HAL_TIMEOUT;
    }
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);

  count = 10U;

  /* few cycles before setting core reset */
  while (count > 0U)
  {
    count--;
  }

  /* Core Soft Reset */
  USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;

  do
  {
    count++;

    if (count > HAL_USB_TIMEOUT)
    {
      return HAL_TIMEOUT;
    }
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);

But, aha, a simple loop as above can get optimized out at -O3. So I just used a brute force delay and now USB3300 starts up OK every time. Phew!

Here is what I ended up with:

/* Wait for AHB master IDLE state. */
  do
  {
    count++;

    if (count > HAL_USB_TIMEOUT)
    {
      return HAL_TIMEOUT;
    }
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);

  /* few cycles before setting core reset */
  HAL_Delay(1);

  /* Core Soft Reset */
  USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;

  do
  {
    count++;

    if (count > HAL_USB_TIMEOUT)
    {
      return HAL_TIMEOUT;
    }
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);

  HAL_Delay(1);

 Short and effective and to the point.