cancel
Showing results for 
Search instead for 
Did you mean: 

Does anybody have experience with changing sysclk prescalers on the fly?

Mr_M_from_G
Senior

Hello,

working with STM32H742, I need 480 MHz in some parts of my code while on the other hand I need to save energy. That's why I came to think about changing D1CPRE and HPRE between (1, 😎 and (8, 1) to (maximize , lower) sysclk while keeping the APB clks the same. Both, D1CPRE and HPRE are in the same register, RCC_D1CFGR, so I can change them in one instruction. Still I wonder what will exactly happen then, especially two questions:

  • will the system remain stable or is there a chance for a crash?
  • will timers (eg) keep running at the same input frequency or is there a chance for glitches or other disturbance?

Is there someone who has experience on this?

Thanks a lot

Martin

6 REPLIES 6
Mr_M_from_G
Senior

gently pushing this up again.

Also I would like to know what is the drawback of reducing the AHB and APB clocks.

Thanks a lot

Martin

FSeni.1
Associate

I don' see any reason why the system should crash. I'am doing pretty much the same without experiencing any issues. The current consumption is significantly lower than just using sleep mode __wfi(); alone.

If you want to change the voltage scaling as well, you will have to decrease the core clock first before going to the lower voltage, and increase the voltage scaling first before increasing the core clock.

The Systick will be affected by D1CPRE as well, but you could use its own /8 divider to keep this clock constant as well.

I cannot tell you wether there might be any glitches during the clock switch. In case you are in need of percise timers, you should take a closer look at it.

One drawback that comes into my mind is the reduced timer resolution.

>>Also I would like to know what is the drawback of reducing the AHB and APB clocks.

Beyond the obvious ones that you'd need to modify the settings on all time dependent peripherals in the system, ie SysTick, TIM, SPI, USART, CAN, etc. on the sources you opted to change.

I'd presume the PLL/VCO are the things drawing significant current in the idle state, and costs of bring up/down those, or changing the settings is not insignificant, as the PLL needs to be stopped and the core migrated to a different source.

Generally the core would idle in a __WFI loop, and that would significantly reduce the draw of the MCU, and then you'd process things quickly/promptly in interrupt before sleeping again. The thing you want to generally avoid is tight while() loops doing nothing, waiting for peripherals or timeouts.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Mr_M_from_G
Senior

Hello and thanks for your answers,

I tried it on my hardware and I get a significant current reduction, so this is a good way to go for me. Also switching from one to the other seems to cause no problems.

Still I have some problem that I can't solve on my own.

CubeMX clock configuration for STM32 H7 42 shows a devider by 1 or 8 before the CPU systick clk. As I only copy clock configuration from CubeMX to my program I am now searching where this setting is in CubeMX generated sources. Also I couldn't find it in ref manual or in ARM cortex M7 user guide. Any ideas?

It seems I have to adjust this too to keep my program on track.

Most of my other peripherals are clocked by PLL3, so their clock remains the same when changing RCC_D1CFGR. Only timers are clocked by AHB and APB clks.

Thanks a lot for any help

Martin

FSeni.1
Associate

Hello,

I think you are looking for the following:

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);

and

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

Florian

Mr_M_from_G
Senior

Hello Florian,

thanks for that hint.

I digged deep into the sources of HAL and found that it is finally the ARM Cortex M7 register SYST_CSR in systick module and there it is bit 2 = CLKSOURCE which can be 0 = sys tick clk is equivalent to processor clk = hclk in case of STM32 or 1 = syst tick = external clk which seems to be implementation specific and in case of STM32H7 is hclk / 8.

Thanks again

Martin