The HSE comes from Master Clock Output of another STM32F446 where it is set to repeat it's 8 MHz HSE.

So I defined it as 8 MHz in BYPASS mode.

There are too many multipliers and various buses to keep in mind, for me is the main reason to use the Cube. The GUI factor. C code puts my h/w engineer in high-impedance state. Only when he sees the GUI, he is contactable.

Please don't confuse Cube (the "library") with CubeMX. CubeMX (the GUI) can still be used for clicking, without using the "library" or generated code. We do exactly this with my colleague who does the HW.

I prefer to print out the clock tree from the RM or the pin list from DS (or my own) and use colored pens and highlighters.

The setting for HSE_VALUE is typically in stm32f7xx_hal_conf.h (or whatever family you use) and is a project localized file.

There have been a number of situations where ST writes the wrong value as many of the EVAL boards use 25 MHz, where as most of the DISCO/NUCLEO boards use 8 MHz. This rule however is not universal as the STM32F769I-DISCO for example has a 25 MHz HSE.

Bottom line if the USART timings look off it is most likely that the HSE_VALUE doesn't match the hardware on the board (yours or ST's), as this is use to back-compute the CPU speed vs the PLL/RCC settings.

Yes I've defined HSE_VALUE = 8000000 in my stm32f4xx_hal_conf.h, and this used to work for a while.

But some time ago, added LL drivers for UARTs. This pulled in a bunch of LL includes from the Cube repository.

HSE_VALUE is defined there as well, in stm32f4xx_ll_rcc.h !

And this is because in the main.h and main.c generated by Cube, #includes for all the LL drivers go first, before inclusion of stm32f4xx_hal.h. So stm32f4xx_ll_rcc.h from the library gets included before my local stm32f4xx_hal_conf.h and overrides my HSE_VALUE.

So the resolution... HSE_VALUE must be defined at the topmost project level (in IDE compiler defines, makefile, etc).

For extra security, added ASSERT(HSE_VALUE == 800000); early in main().

It's interesting that neither UARTs or USB were affected by wrong HSE_VALUE.