stm32/rcc: add HSISYS support for g0

adds support to divide HSI clock, which allows running in low power mode on HSI
This commit is contained in:
Markus Kasten 2025-01-17 12:07:43 +01:00
parent 4fbe1beefe
commit 5d26bca2e7

View File

@ -1,8 +1,8 @@
use crate::pac::flash::vals::Latency; use crate::pac::flash::vals::Latency;
pub use crate::pac::pwr::vals::Vos as VoltageRange; pub use crate::pac::pwr::vals::Vos as VoltageRange;
pub use crate::pac::rcc::vals::{ pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Hpre as AHBPrescaler, Hsidiv as HsiSysDiv, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk,
}; };
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::time::Hertz; use crate::time::Hertz;
@ -28,6 +28,12 @@ pub struct Hse {
pub mode: HseMode, pub mode: HseMode,
} }
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Hsi {
/// Division factor for HSISYS clock. Default is 1.
pub sys_div: HsiSysDiv,
}
/// PLL Configuration /// PLL Configuration
/// ///
/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output /// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
@ -58,8 +64,8 @@ pub struct Pll {
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Config { pub struct Config {
/// HSI Enable /// HSI Configuration
pub hsi: bool, pub hsi: Option<Hsi>,
/// HSE Configuration /// HSE Configuration
pub hse: Option<Hse>, pub hse: Option<Hse>,
@ -94,7 +100,9 @@ impl Default for Config {
#[inline] #[inline]
fn default() -> Config { fn default() -> Config {
Config { Config {
hsi: true, hsi: Some(Hsi {
sys_div: HsiSysDiv::DIV1,
}),
hse: None, hse: None,
sys: Sysclk::HSI, sys: Sysclk::HSI,
#[cfg(crs)] #[cfg(crs)]
@ -119,7 +127,12 @@ pub struct PllFreq {
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
// Turn on the HSI // Turn on the HSI
RCC.cr().modify(|w| w.set_hsion(true)); RCC.cr().modify(|w| {
w.set_hsion(true);
if let Some(hsi) = config.hsi {
w.set_hsidiv(hsi.sys_div);
}
});
while !RCC.cr().read().hsirdy() {} while !RCC.cr().read().hsirdy() {}
// Use the HSI clock as system clock during the actual clock setup // Use the HSI clock as system clock during the actual clock setup
@ -127,9 +140,9 @@ pub(crate) unsafe fn init(config: Config) {
while RCC.cfgr().read().sws() != Sysclk::HSI {} while RCC.cfgr().read().sws() != Sysclk::HSI {}
// Configure HSI // Configure HSI
let hsi = match config.hsi { let (hsi, hsisys) = match config.hsi {
false => None, None => (None, None),
true => Some(HSI_FREQ), Some(hsi) => (Some(HSI_FREQ), Some(HSI_FREQ / hsi.sys_div)),
}; };
// Configure HSE // Configure HSE
@ -222,7 +235,7 @@ pub(crate) unsafe fn init(config: Config) {
.unwrap_or_default(); .unwrap_or_default();
let sys = match config.sys { let sys = match config.sys {
Sysclk::HSI => unwrap!(hsi), Sysclk::HSI => unwrap!(hsisys),
Sysclk::HSE => unwrap!(hse), Sysclk::HSE => unwrap!(hse),
Sysclk::PLL1_R => unwrap!(pll.pll_r), Sysclk::PLL1_R => unwrap!(pll.pll_r),
_ => unreachable!(), _ => unreachable!(),
@ -264,7 +277,7 @@ pub(crate) unsafe fn init(config: Config) {
while RCC.cfgr().read().sws() != config.sys {} while RCC.cfgr().read().sws() != config.sys {}
// Disable HSI if not used // Disable HSI if not used
if !config.hsi { if config.hsi.is_none() {
RCC.cr().modify(|w| w.set_hsion(false)); RCC.cr().modify(|w| w.set_hsion(false));
} }