Skip to content

Commit 862360b

Browse files
committed
stm32h7: Add support for any xtal (HSE) frequency
1 parent dd755d6 commit 862360b

2 files changed

Lines changed: 54 additions & 44 deletions

File tree

src/platform/stm32h7/stm32h7_clk.c

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <mios/mios.h>
22
#include <stddef.h>
3-
3+
#include <stdio.h>
44
#include "stm32h7_clk.h"
55
#include "stm32h7_pwr.h"
66
#include "stm32h7_flash.h"
@@ -14,7 +14,9 @@
1414
#define VOS_LEVEL_2 2
1515
#define VOS_LEVEL_3 1
1616

17-
#ifndef CPU_SYSTICK_RVR
17+
#ifdef CPU_SYSTICK_RVR
18+
#error Compile-time core frequency is not supported
19+
#endif
1820

1921
// Dynamic core clock frequency
2022

@@ -46,7 +48,6 @@ clock_get_irq_blocked(void)
4648
}
4749
}
4850

49-
#endif
5051

5152
static uint32_t sysclk_freq;
5253

@@ -121,50 +122,12 @@ static uint32_t pll2p_freq;
121122
const char *
122123
stm32h7_init_pll(unsigned int hse_freq, uint32_t flags)
123124
{
124-
int pll2_freq = 400 * MHZ;
125-
126125
reg_clr_bit(PWR_CR3, 2); // Disable SMPS
127126
while(reg_get_bit(PWR_CSR1, 13) == 0) {}
128127

129-
#ifdef CPU_SYSTICK_RVR
130-
// Compile-time core clock frequency
131-
const int sysclk_freq_mhz = CPU_SYSCLK_MHZ;
132-
sysclk_freq = sysclk_freq_mhz * MHZ;
133-
#else
134-
135-
// Dynamic core clock frequency
136-
137-
int sysclk_freq_mhz = 520;
138-
128+
sysclk_freq = 520 * MHZ;
139129
if(reg_get_bit(FLASH_OPTSR2_CUR, 2)) {
140-
sysclk_freq_mhz = 550; // CPUFREQ_BOOST
141-
}
142-
143-
sysclk_freq = sysclk_freq_mhz * MHZ;
144-
145-
ticks_per_us = (sysclk_freq + 999999) / 1000000;
146-
ticks_per_hz = (sysclk_freq + HZ - 1) / HZ;
147-
148-
// We also need to configure systick
149-
*SYST_RVR = ticks_per_hz;
150-
*SYST_VAL = 0;
151-
*SYST_CSR = 7;
152-
#endif
153-
154-
const int axi_freq = sysclk_freq / 2;
155-
156-
ahb_freq = sysclk_freq / 2;
157-
apb_freq = sysclk_freq / 4;
158-
159-
int vos;
160-
if(sysclk_freq_mhz > 400) {
161-
vos = VOS_LEVEL_0;
162-
} else if(sysclk_freq_mhz > 300) {
163-
vos = VOS_LEVEL_1;
164-
} else if(sysclk_freq_mhz > 170) {
165-
vos = VOS_LEVEL_2;
166-
} else {
167-
vos = VOS_LEVEL_3;
130+
sysclk_freq = 550 * MHZ; // CPUFREQ_BOOST
168131
}
169132

170133
int pllscr;
@@ -221,7 +184,10 @@ stm32h7_init_pll(unsigned int hse_freq, uint32_t flags)
221184
const uint32_t pll1p = 0;
222185
const uint32_t pll1q = 0;
223186
const uint32_t pll1r = 0;
187+
sysclk_freq = hse_freq * (pll1n + 1);
224188

189+
// Target, will be refined
190+
int pll2_freq = 400 * MHZ;
225191
pll2q_freq = 100 * MHZ;
226192
pll2p_freq = 100 * MHZ;
227193

@@ -230,6 +196,9 @@ stm32h7_init_pll(unsigned int hse_freq, uint32_t flags)
230196
const uint32_t pll2q = (pll2_freq / pll2q_freq) - 1;
231197
const uint32_t pll2r = 0;
232198

199+
pll2_freq = hse_freq * (pll2n + 1);
200+
pll2p_freq = pll2_freq / (pll2p + 1);
201+
pll2q_freq = pll2_freq / (pll2q + 1);
233202

234203
// Set prescalers for PLLx
235204
reg_wr(RCC_PLLCKSELR,
@@ -252,10 +221,36 @@ stm32h7_init_pll(unsigned int hse_freq, uint32_t flags)
252221
reg_wr(RCC_PLL1DIVR, (pll1r << 24) | (pll1q << 16) | (pll1p << 9) | pll1n);
253222
reg_wr(RCC_PLL2DIVR, (pll2r << 24) | (pll2q << 16) | (pll2p << 9) | pll2n);
254223

255-
set_flash_latency(axi_freq, vos);
256224

225+
const int axi_freq = sysclk_freq / 2;
226+
ahb_freq = sysclk_freq / 2;
227+
apb_freq = sysclk_freq / 4;
228+
229+
230+
231+
const int sysclk_freq_mhz = sysclk_freq / 1000000;
232+
int vos;
233+
if(sysclk_freq_mhz > 400) {
234+
vos = VOS_LEVEL_0;
235+
} else if(sysclk_freq_mhz > 300) {
236+
vos = VOS_LEVEL_1;
237+
} else if(sysclk_freq_mhz > 170) {
238+
vos = VOS_LEVEL_2;
239+
} else {
240+
vos = VOS_LEVEL_3;
241+
}
242+
243+
set_flash_latency(axi_freq, vos);
257244
voltage_scaling(vos);
258245

246+
ticks_per_us = (sysclk_freq + 999999) / 1000000;
247+
ticks_per_hz = (sysclk_freq + HZ - 1) / HZ;
248+
249+
// We also need to configure systick
250+
*SYST_RVR = ticks_per_hz;
251+
*SYST_VAL = 0;
252+
*SYST_CSR = 7;
253+
259254
// Start PLL1
260255
reg_set_bit(RCC_CR, 24);
261256
// Wait for PLL1
@@ -368,3 +363,15 @@ stm32h7_clk_deinit(void)
368363
reg_wr(RCC_APB2RSTR, 0);
369364
reg_wr(RCC_APB3RSTR, 0);
370365
}
366+
367+
void
368+
stm32h7_print_clocks(struct stream *st)
369+
{
370+
stprintf(st, "Clocks (kHz): SYS:%u AHB:%u APB:%u PLL2Q:%u PLL2P:%u ECC:%s\n",
371+
sysclk_freq / 1000,
372+
ahb_freq / 1000,
373+
apb_freq / 1000,
374+
pll2q_freq / 1000,
375+
pll2p_freq / 1000,
376+
reg_get_bit(FLASH_OPTSR2_CUR, 2) ? "Off" : "On");
377+
}

src/platform/stm32h7/stm32h7_clk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,6 @@ reset_peripheral(uint16_t id)
159159

160160

161161
void stm32h7_clk_deinit(void);
162+
163+
struct stream;
164+
void stm32h7_print_clocks(struct stream *st);

0 commit comments

Comments
 (0)