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"
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
5152static uint32_t sysclk_freq ;
5253
@@ -121,50 +122,12 @@ static uint32_t pll2p_freq;
121122const char *
122123stm32h7_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+ }
0 commit comments