cancel
Showing results for 
Search instead for 
Did you mean: 

USB-HS (ULPI) on STM32H750

flyer31
Senior

Hi,

is somebody operating the STM32H750 successfully with USB-HS (ULPI Interface)?

I succeeded in running the USB device CDC example of the STM32H743 evaluation board on my STM32H743 test board (144 pin LQFP) - but when I try the same with a test board using the STM32H750 (100 pin LQFP), it does not work. I use the USB3300 chip for the interface.

I changed 3 things on this board:

  • other processor (STM32H750 100pin instead of STM32H743 144 pins)
  • "Old-style" USB-B connector (instead of USB-B micro connector, which I used with the STM32H743 board)
  • No Ground layer on the top layer (containing the USB lines to the connector, only about 2cm long) - but in both cases I use 4 layer multilayer, and full ground plane directly under the USB lines,, the USB line width and distance the same ... as typically recommended... .

I now will try to use the STM32H743 LQFP 100pin version on the 750 test board ... I will know more tomorrow I hope... .

(but if I look at all the datasheets, such a USB ULPI software running on STM32H743, it should run without changes also on the STM32H750 ... as I see it, e, g. all the peripheral memory addresses are really identical... . I have some other STM32H750 application, this is running with processor setting STM32H743 without any problems... ..

14 REPLIES 14

Hi. Do you correctly drive the reset pin of USB PHY?

flyer31
Senior

The USB3300 has automatic Power-On Reset. I just set its RESET pin to GND by Hardware - but I did this also in all previous layouts, never a problem until now.

I am now a bit concerned about this pin VDD33USB. The LQFP144 has this pin, bht the LQFP100 device is missing this pin.

If I do not set the bit "USB33DEN" in my 144pin STM32H743 device, then also the USB-HS will NOT work. (PC will give the message "Device not recognized" ... so the PC recognizes plug in- but wrong communication). If I look at the CR3 register, the bit USB33RDY and USB33DEN is both set, and the bit USBREGEN is NOT set.

I try the same in my LQFP 100 STM32H750 so far ... the PWR->CR3 register looks the same ("USB33RDY" strangely is set) ... . But anyway not working somehow.

If there needs to be a different setting without this VDD33USB pin, then somehow this seems NOT be documented in RefManual or Datasheet, or I overlook this completely... .

(the Controller is operated from 3V3 supply, all very standard, no low power stuff or anything else more complicated, no USB host operation, only USB device operation).

Can you share schematic?

flyer31
Senior

The schematics is a bit complex, as the PCB does also many other things. But the connections between USB3300 chip and STM32H7 controller are straight forward:

USB3300-Pins

6,16,25,30 (VDD33_1,_2;_3,_4) --- 3V3 (0.1uF 0603 on each pin against GND)

31 (REG_EN) ---3V3

15 (VDD18) --- 0u1 0603 against GND

26 (VDD18_2) --- 10uF 1206 against GND

29 (VDDA18) --- 10uF 1206 + 0u1 0603 against GND

4 (VBUS) --- via 1kOhm to USB-VBUS

5,27,3,10 (ID,XO,CPEN,EVBUS) --- nc / open

28(XI) --- Output of 24MHz Oscillator (standard 4 pin SMD device, operated from 3V3, Enable tied to 3V3)

1... (3 GND pins) --- GND

32 (RBIAS) --- via 12kOhm to GND

24,23,22...17(D0...D7) --- direct connect to STM32H7 ULPI_D0...D7

9 (RST) --- GND

14,12,,11,13 (CLKOUT,DIR,NXT,STP)--- direct connect to STMh32H7 ULPI_CLK,DIR,NXT,STP)

8,7 (DM,DP) --- directly to USB connector ("old style rectangular" USB-B used here, but I tried already directly soldered to USB cable)

(DM,DP wires < 2cm long, 4 layer ground plane below, 10 mil width, 20 mil center distance, no nasty lines nearby / crossing).

The 3V3 is directly derived from VUSB via LT1763-3V3 (Linear regulator).

STEM32H750 (LQFP100, Rev. Y):

11,27,75,100 (VDD) --- 3V3 (4x0u1 against GND)

50((VDD) --- 3V3 (10uF against GND)

6(VBAT) --- 3V3 (0u1 against GND)

48,73(VCAP1,VCAP2) --- 2x2u2 against GND

20,21(VREF,VDDA) --- 3V3 (2x2u2 against GND)

94(BOOT0) --- via 10kOhm to GND

10,26,49,74,99 (5xGND) --- GND

19 (VSSA) --- GND

12(OSC_IN) --- same 24MHz Osciallator signal as used for USB3300

25,34,35,46,47,51,52,91 (ULPI_D0...D7) --- directly to USB3300 D0...D7 (see above)

29,17,18,15(ULPI_CLK,DIR,NXT;STP) --- directly to USB3300 CLKOUT,DIR,NXT,STP (see above)

14(NRST) --- to GND (10kOhm Pullup to 3V3)

... this is all very straight forward and simple.

This STM32H750 controller part is isolated against all other IO functions of the board by Si8650 style isolation devices (resp. ADUM... from AD...).

With STM32H743 (LQFP144) the same setup works nicely (of course different pin numbers of the controller.... Pin 95(VDD33USB) connected to 3V3)

PS: I use the STM32H7 EvalBoard Application example USB-Device-CDC as base ... the controller runs at 96MHz, and all busses also at 96MHz. I checked the sys_ck and the xtal hse_ck with MCO1 and MCO2 output, and this runs perfectly with 6.4MHz (=sys_ck/15) and 3.0MHz (=hse_ck/8) - completely identical for both PCBs (the H743 LQFP144 version, and the H750 LQFP100 version).

flyer31
Senior

Just tried with 100LQFP STM32H743 .(Rev. Y) on a 2nd identical PCB. This for God sake is running.

We will now assemble PCB 3 + 4, and then one time with H743 and one time with H750 (both LQFP100) ... . If then again problem with H750 and H743 working, then we would desolder the H743 from a working PCB and replace by H750 ... just to be sure that the H750 is the problem (and not some "stupid PCB assembly accident"). I also ordered two new LQFP100 H750 from Farnell ... but I am frightened will still will get Rev. Y anyway... .

flyer31
Senior

So now with 3 new PCBs, only USB part soldered (as described above), 2x with STM32H743, and 1x with STM32H750 (always Rev. Y, always LQFP100), the STM32H743 enumerate always correctly. This newly soldered STM32H750 now sometimes always enumerates, but only about every 4th time (if I try USB cable connection to PC 4-5 times, it will give the "PC USB connect ding-****" only once (then nicely showing "STM32 Virtual ComPort in HS Mode" in device manager)). The other times it will NOT connect... .

So quite a success already, just not yet perfect. (the STM32H743 for God sake work perfectly, they connect every time nicely...).

PS: There is one nasty drawback of H750 (RevY) concerning SysTick, which I just remember - it is not possible to run the SysTick-Timer in the 8x slower mode (this is documented in the errata sheet)... possibly this is the reason ... this strange behaviour might look a bit like a timer / timeout problem... .some timers at a limit ... I will check this further... .

flyer31
Senior

Got it now.

The problem in the STM32H750 is that sometimes the Core Reset command fails / keeps hanging.

In the file stm32h7xx_ll_usb.c there is this function "USB_CoreReset". This function in the register OTG_GRSTCTL sets the bit OTG_GRSTCTL_CSRST and then waits until the controller would clear this bit again. Usually this Reset takes about 2msec. But in STM32H750 sometimes this fails. ... no idea why...

The most straight forward method to come around it, is just to skip this command (comment out the invoke of "USB_CoreReset" in the function "USB_CoreInit". Then all works. As I see it, after power up it is not necessary to invoike this function (possibly this might be needed, if somebody enables USB only after some later time, or if somebody somehow wants to re-initialize USB in the program, or if somebody wants to use low power modes... . But I do not need such things ... I just want to enable USB reliably on power on and then never switch it off again ... ).

flyer31
Senior

The problem finally was that I had no delay after power up + SystemClock_Config. Somehow maybe the H750 needs some delay here, what the H743 does NOT seem to need... .

If I inserted a 5 msec delay time there (before calling USBD_Init) (must be > 2msec definitely - 2msec is NOT sufficient - I tried 2 and 5...). then all fine. Then also this OTG_GRSTCTL_CSRST will work nicely, and USB reset waiting time is then less than 0.5 usec (NOT 2msec as written above ... 2msec would be already "STRANGE").

What is a bit bad in the example code is that the function USBD_CoreReset would return of HAL_TIMEOUT, but this error is nowhere screened in the software. To find such errors better, it would be nice to have a possibility to define "HAL_TIMEOUT" to some Assert breakpoint handling or so (as well as HAL_Error presumably ...). This unfortunately is missing a bit in this USB demo code (but otherwise this USB demo code seems to be nicely programmed, much nicer then the "old STM32F4 Discovery USB demo code" - please better do not change too much ...).

DBywa
Associate

Hi,

I have bumped into the same issue. I was able to determine the root case and come up with a fix, although finding this bug has been extremely difficult. My findings apply to FW H7 v1.4.0

As mentioned in one of above post the USB_CoreReset function waits on GRSTCTL bit to set. The problem is that the while loop has hard coded 200K iterations before yielding timeout (implicitly number of CPU instructions). My problem started occurring as soon as I cranked up my CPU to full core speed of 480MHz. The same 200K iterations take much less time than before. This is really a poor man timer, highly unreliable.

The clue of my fix is to use HAL ticks for timeout measurement, similar to what is already used in many areas throughout HAL.

My fixed version of USB_CoreReset looks like this:

/** @defgroup USB_OTG_GRSTCTL_TXFFLSH_TIMEOUT_MS Tx FIFO flush timeout
  * @{
  */
#define USB_OTG_GRSTCTL_TXFFLSH_TIMEOUT_MS  ((uint32_t)5U)
 
/**
  * @brief  Reset the USB Core (needed after USB clock settings change)
  * @param  USBx  Selected device
  * @retval HAL status
  */
static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
{
  uint32_t tickstart;
  
  /* Get tick */
  tickstart = HAL_GetTick();
 
  /* Wait for AHB master IDLE state. */
  while((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U)
  {
    if((HAL_GetTick() - tickstart) > USB_OTG_GRSTCTL_AHBIDL_TIMEOUT_MS)
    {
      return HAL_TIMEOUT;
    }
  }
 
  /* Core Soft Reset */
  USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
 
  /* Get tick */
  tickstart = HAL_GetTick();
 
  while((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST)
  {
    if((HAL_GetTick() - tickstart) > USB_OTG_GRSTCTL_CSRST_TIMEOUT_MS)
    {
      return HAL_TIMEOUT;
    }
  }
 
  return HAL_OK;
}

I hope this information helps someone.

Let ST fix this bug. I hope they read this forum.

I will be glad to share with the complete source file containing the fix.

Apart from this case, I have also reworked other instances of this same poor man 200K iterations loop pattern.