407 vs 427 DFU, auto detect HSE clock speed

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
User avatar
russian
Posts: 364
Joined: Mon Oct 29, 2012 3:17 am
Location: Jersey City, USA
Has thanked: 16 times
Been thanked: 14 times

407 vs 427 DFU, auto detect HSE clock speed

Postby russian » Mon Jul 12, 2021 10:20 pm

TL,DR: just wanted to share https://github.com/rusefi/rusefi/pull/2952

We had an interesting DFU drama when we have fabricated a batch of our boards with 407 instead of 427: it looks like (older?) bootloader has a shorter timeout on external oscillator start up, our PCB design/BOM did not survive that change in behavior and as a consequence we are now looking at changing 8MHz osc for something starting faster, i.e. higher frequency oscillator.

With different batches fabricated differently it seemed like a cool idea to auto-detect HSE clock speed

https://github.com/rusefi/hellen-NB2-issues/issues/5
https://github.com/andreika-git/hellen-one/issues/79
http://rusefi.com/ - electronic fuel injection

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Tue Jul 13, 2021 12:32 am

I'm the one who made that PR, so I can shed a little light on how it works.

The STM32s we support (in fact all F4, F7, etc) have a 1% tolerance 16MHz internal RC oscillator (HSI = high speed internal). They also have a low speed internal oscillator, nominally 32khz, but with a wide tolerance (something like +- 50%, LSI = low speed internal). We have some external crystal of unknown frequency, HSE.

First, we measure how many counts of HSI fit in one period of LSI (calibrate poor LSI against good HSI). The STM32 includes a special register, TIM5_OR, that lets you remap TIM5's 4th input capture channel to connect to the LSI clock, instead of the external pin, so we simply measure a few periods of the clock with TIM5, which runs at sysclk frequency. This gives us the number of HSI clocks per LSI clock.

Then, the system clock is switched to use the unknown HSE directly (no divider or PLL), and the same measurement taken. Since the drift of LSI will be essentially zero over the short period of time required to make the measurement (~40 cycles of LSE total, a few ms max), we can then compare the ratio of HSE:HSI based on the ratio of measured cycles of each in one LSE period. With the known 16Mhz frequency of the HSI oscillator, we can then easily calculate HSE's frequency, and reconfigure the PLL to get the CPU speed we want!

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Tue Jul 13, 2021 12:34 am

Oh, and this process happens in __late_init(), which runs just after things like bss/zero initialization, and just before static constructors and the call to main().

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby Giovanni » Tue Jul 13, 2021 7:51 am

Hi,

On the F4 clocks are calculated at compile time, how is this compatible with that?

Giovanni

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Tue Jul 13, 2021 8:42 am

Giovanni wrote:On the F4 clocks are calculated at compile time, how is this compatible with that?


We cheat. The clock settings in the headers are set such that:

  • The input to the PLL is expected to be 1MHz (which we will match later once PLL is reconfigured)
  • The default pre-PLL divider (PLLM) is set to 25, the maximum crystal we might expect, so we don't accidentally overclock the CPU during init.
  • STM32_HSECLK is set to 25MHz, so that all the math works out correctly in the headers (bus/core clocks are calculated correctly)

If the crystal is slower than 25MHz, we're underclocked for bss/zero init, but then in __late_init, but after measuring HSE we turn PLLM down so that the input to the PLL speeds up to match the 1MHz as configured in the headers. It's not too bad though, since an 8MHz crystal will still have us running at 8/25*336/2 = 53.7 MHz.

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Tue Jul 13, 2021 8:43 am

Thinking about it now, we could prevent the brief underclock by selecting HSI as the default PLL input, with PLLM=16, so we get full CPU speed during bss/zero init. Then after measurement switch PLLM and the PLL input, then switch back to the PLL.

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Tue Jul 13, 2021 9:15 am

Reviewing the datasheet it looks like the way we do it now is technically out of spec if you use any crystal other than 25mhz - the PLL input is supposed to be 0.95MHz <= x <= 2.1MHz, and with an 8MHz crystal you get 0.32MHz input to the PLL.

Time to try using HSI as the PLL input, then switching PLL input to HSE once measured.

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Fri Jul 16, 2021 6:49 pm

mck1117 wrote:Time to try using HSI as the PLL input, then switching PLL input to HSE once measured.


Yep, doing it this way works fine too. So that's now what we do: start with everything configured correctly running on HSI, then swap out PLLSRC and PLLM at runtime to suit HSE.

electronic_eel
Posts: 77
Joined: Sat Mar 19, 2016 8:07 pm
Been thanked: 17 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby electronic_eel » Sat Jul 17, 2021 3:43 pm

mck1117 wrote:First, we measure how many counts of HSI fit in one period of LSI (calibrate poor LSI against good HSI). The STM32 includes a special register, TIM5_OR, that lets you remap TIM5's 4th input capture channel to connect to the LSI clock, instead of the external pin, so we simply measure a few periods of the clock with TIM5, which runs at sysclk frequency. This gives us the number of HSI clocks per LSI clock.

Then, the system clock is switched to use the unknown HSE directly (no divider or PLL), and the same measurement taken. Since the drift of LSI will be essentially zero over the short period of time required to make the measurement (~40 cycles of LSE total, a few ms max), we can then compare the ratio of HSE:HSI based on the ratio of measured cycles of each in one LSE period.

This procedure seems to be overly complicated to me. I don't think you have to take the detour of using the LSI, but can directly measure the HSE against the HSI while the system is clocked by HSI. Most STM32 offer a way to do this.

For example for the F427 have a look at the Reference Manual RM0090, chapter 6.2.11, Internal/external clock measurement using TIM11 channel1. The F407 has the same mechanism, chapter 7.2.11.

mck1117
Posts: 28
Joined: Wed Nov 11, 2020 6:41 am
Has thanked: 1 time
Been thanked: 5 times

Re: 407 vs 427 DFU, auto detect HSE clock speed

Postby mck1117 » Mon Jul 19, 2021 9:16 am

electronic_eel wrote:
mck1117 wrote:First, we measure how many counts of HSI fit in one period of LSI (calibrate poor LSI against good HSI). The STM32 includes a special register, TIM5_OR, that lets you remap TIM5's 4th input capture channel to connect to the LSI clock, instead of the external pin, so we simply measure a few periods of the clock with TIM5, which runs at sysclk frequency. This gives us the number of HSI clocks per LSI clock.

Then, the system clock is switched to use the unknown HSE directly (no divider or PLL), and the same measurement taken. Since the drift of LSI will be essentially zero over the short period of time required to make the measurement (~40 cycles of LSE total, a few ms max), we can then compare the ratio of HSE:HSI based on the ratio of measured cycles of each in one LSE period.

This procedure seems to be overly complicated to me. I don't think you have to take the detour of using the LSI, but can directly measure the HSE against the HSI while the system is clocked by HSI. Most STM32 offer a way to do this.

For example for the F427 have a look at the Reference Manual RM0090, chapter 6.2.11, Internal/external clock measurement using TIM11 channel1. The F407 has the same mechanism, chapter 7.2.11.


Thanks for the hint, I saw that note in the reference manual, but figured the LSI jump would be easier as I saw it suggested somewhere else. I reverse engineered the ST F407 bootloader a bit, and they are indeed using TIM11, not TIM5 to do the HSE measurement for USB DFU.

RTCPRE is configured to /31, TIM11 is enabled, and TIM11_OR is set to remap ch1 to HSE_RTC.

Here it is in Ghidra:

snip.png


In our case, TIM11 would run at 168MHz, so the expected range of counts for 4-24MHz crystals would be 1302 counts for 4mhz, 651 counts for 8MHz, and 217 counts for 24MHz, which is plenty of resolution to correctly identify the crystal, especially if multiple capture periods are observed.


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 13 guests