168 vs 180 MHz Operation


#1

mcuconf.h

#define STM32_PLLN_VALUE                    336

The STM32F427vg is being setup to run at 168 MHz.

It's capable of running at 180 MHz.
http://www.st.com/en/microcontrollers/stm32f427-437.html

Why is that? Is it a hangover from STM32F407 development?

180/168 = 1.07 (7% performance gain)

To try it out:

#define STM32_PLLN_VALUE                    360

#2

@johannes should say but probably there is a good reason for that. if not, yayy! :slight_smile:


#3

Yes, the STM32F42x family can run at 180MHz ... however that is without USB!
It took me a while to believe it and I was disappointed when I figured this out, it is a limitation of the clock tree/PLLs inside the chip.

USB requires the PLL48CLK at 48MHz, for a 180MHz SYSCLK you can derive that
PLLP/PLLQ=3.75
That ratio can only be achieved with PLLQ=15 and PLLP=4
However that requires the PLLN output to be 720MHz while that is specified to be maximum 432MHz.


#4

Well that's a pity. It seems like an oversight on the part of ST to provide a max clock rate that can't be effectively used with USB operations.


#5

#!/usr/bin/python

MHz = 1000000.0

HSE = 8.0 * MHz

pll_m_set = range(2, 63 + 1)
pll_n_set = range(50, 432 + 1)
pll_p_set = (2,4,6,8)
pll_q_set = range(2, 15 + 1)
ahb_presc_set = (1, 2, 4, 8, 16, 64, 128, 256, 512)

def pll_vco_input(hse, pll_m):
  return float(hse) / float(pll_m)

def pll(hse, pll_m, pll_n):
  return pll_vco_input(hse, pll_m) * float(pll_n)

def pllclk(hse, pll_m, pll_n, pll_p):
  return pll(hse, pll_m, pll_n) / float(pll_p)

def pll48ck(hse, pll_m, pll_n, pll_q):
  return pll(hse, pll_m, pll_n) / float(pll_q)

def sysclk(hse, pll_m, pll_n, pll_p, ahb_presc):
  return pllclk(hse, pll_m, pll_n, pll_p) / float(ahb_presc)

def main():
  max_sysclk = 0.0
  for pll_m in pll_m_set:
    for pll_n in pll_n_set:
      for pll_p in pll_p_set:
        for pll_q in pll_q_set:
          for ahb_presc in ahb_presc_set:

            x = pll48ck(HSE, pll_m, pll_n, pll_q)
            if x != 48.0 * MHz:
              continue

            x = pll_vco_input(HSE, pll_m)
            if x < 1.0 * MHz or x > 2.0 * MHz:
              continue

            x = pll(HSE, pll_m, pll_n)
            if x < 100.0 * MHz or x > 432.0 * MHz:
              continue

            x = sysclk(HSE, pll_m, pll_n, pll_p, ahb_presc)
            if x > 180.0 * MHz:
              continue

            if x >= max_sysclk:
              print('sysclk %d pll_m %d pll_n %d pll_p %d pll_q %d ahb_presc %d' % (x, pll_m, pll_n, pll_p, pll_q, ahb_presc))
              max_sysclk = x

main()

Gives:

sysclk 72000000 pll_m 4 pll_n 72 pll_p 2 pll_q 3 ahb_presc 1
sysclk 96000000 pll_m 4 pll_n 96 pll_p 2 pll_q 4 ahb_presc 1
sysclk 120000000 pll_m 4 pll_n 120 pll_p 2 pll_q 5 ahb_presc 1
sysclk 144000000 pll_m 4 pll_n 144 pll_p 2 pll_q 6 ahb_presc 1
sysclk 168000000 pll_m 4 pll_n 168 pll_p 2 pll_q 7 ahb_presc 1
sysclk 168000000 pll_m 5 pll_n 210 pll_p 2 pll_q 7 ahb_presc 1
sysclk 168000000 pll_m 6 pll_n 252 pll_p 2 pll_q 7 ahb_presc 1
sysclk 168000000 pll_m 7 pll_n 294 pll_p 2 pll_q 7 ahb_presc 1
sysclk 168000000 pll_m 8 pll_n 336 pll_p 2 pll_q 7 ahb_presc 1

So - yeah. No solutions for 180.0 MHz :frowning_face:


#6

Five years later and thanks for this little script! I am messing around with an STM32F767 that can run at max. 216 Mhz and your script (if F7 config even works the same) gives me the following options:

sysclk 72000000 pll_m 4 pll_n 72 pll_p 2 pll_q 3 ahb_presc 1
sysclk 96000000 pll_m 4 pll_n 96 pll_p 2 pll_q 4 ahb_presc 1
sysclk 120000000 pll_m 4 pll_n 120 pll_p 2 pll_q 5 ahb_presc 1
sysclk 144000000 pll_m 4 pll_n 144 pll_p 2 pll_q 6 ahb_presc 1
sysclk 168000000 pll_m 4 pll_n 168 pll_p 2 pll_q 7 ahb_presc 1
sysclk 192000000 pll_m 4 pll_n 192 pll_p 2 pll_q 8 ahb_presc 1
sysclk 216000000 pll_m 4 pll_n 216 pll_p 2 pll_q 9 ahb_presc 1
sysclk 216000000 pll_m 5 pll_n 270 pll_p 2 pll_q 9 ahb_presc 1
sysclk 216000000 pll_m 6 pll_n 324 pll_p 2 pll_q 9 ahb_presc 1
sysclk 216000000 pll_m 8 pll_n 432 pll_p 2 pll_q 9 ahb_presc 1