Use new stm32-data registers and fix AHB clock calculation

The original code for calculating the AHB clock did not account for the gap in
prescaler values (32 is not an available value.) The bit shifting and math has
been replaced by a `match`.
This commit is contained in:
Matthew W. Samsonoff 2022-03-02 18:35:53 -05:00 committed by Dario Nieuwenhuis
parent 35636953b2
commit 047ff9a2f2

View File

@ -1,4 +1,5 @@
use crate::pac::{PWR, RCC}; use crate::pac::{PWR, RCC};
use crate::pac::rcc::vals::{Hsidiv, Hpre, Ppre, Sw};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
use crate::time::U32Ext; use crate::time::U32Ext;
@ -29,17 +30,17 @@ pub enum HSI16Prescaler {
Div128, Div128,
} }
impl Into<u8> for HSI16Prescaler { impl Into<Hsidiv> for HSI16Prescaler {
fn into(self) -> u8 { fn into(self) -> Hsidiv {
match self { match self {
HSI16Prescaler::NotDivided => 0x00, HSI16Prescaler::NotDivided => Hsidiv::DIV1,
HSI16Prescaler::Div2 => 0x01, HSI16Prescaler::Div2 => Hsidiv::DIV2,
HSI16Prescaler::Div4 => 0x02, HSI16Prescaler::Div4 => Hsidiv::DIV4,
HSI16Prescaler::Div8 => 0x03, HSI16Prescaler::Div8 => Hsidiv::DIV8,
HSI16Prescaler::Div16 => 0x04, HSI16Prescaler::Div16 => Hsidiv::DIV16,
HSI16Prescaler::Div32 => 0x05, HSI16Prescaler::Div32 => Hsidiv::DIV32,
HSI16Prescaler::Div64 => 0x06, HSI16Prescaler::Div64 => Hsidiv::DIV64,
HSI16Prescaler::Div128 => 0x07, HSI16Prescaler::Div128 => Hsidiv::DIV128,
} }
} }
} }
@ -68,30 +69,30 @@ pub enum APBPrescaler {
Div16, Div16,
} }
impl Into<u8> for APBPrescaler { impl Into<Ppre> for APBPrescaler {
fn into(self) -> u8 { fn into(self) -> Ppre {
match self { match self {
APBPrescaler::NotDivided => 1, APBPrescaler::NotDivided => Ppre::DIV1,
APBPrescaler::Div2 => 0x04, APBPrescaler::Div2 => Ppre::DIV2,
APBPrescaler::Div4 => 0x05, APBPrescaler::Div4 => Ppre::DIV4,
APBPrescaler::Div8 => 0x06, APBPrescaler::Div8 => Ppre::DIV8,
APBPrescaler::Div16 => 0x07, APBPrescaler::Div16 => Ppre::DIV16,
} }
} }
} }
impl Into<u8> for AHBPrescaler { impl Into<Hpre> for AHBPrescaler {
fn into(self) -> u8 { fn into(self) -> Hpre {
match self { match self {
AHBPrescaler::NotDivided => 1, AHBPrescaler::NotDivided => Hpre::DIV1,
AHBPrescaler::Div2 => 0x08, AHBPrescaler::Div2 => Hpre::DIV2,
AHBPrescaler::Div4 => 0x09, AHBPrescaler::Div4 => Hpre::DIV4,
AHBPrescaler::Div8 => 0x0a, AHBPrescaler::Div8 => Hpre::DIV8,
AHBPrescaler::Div16 => 0x0b, AHBPrescaler::Div16 => Hpre::DIV16,
AHBPrescaler::Div64 => 0x0c, AHBPrescaler::Div64 => Hpre::DIV64,
AHBPrescaler::Div128 => 0x0d, AHBPrescaler::Div128 => Hpre::DIV128,
AHBPrescaler::Div256 => 0x0e, AHBPrescaler::Div256 => Hpre::DIV256,
AHBPrescaler::Div512 => 0x0f, AHBPrescaler::Div512 => Hpre::DIV512,
} }
} }
} }
@ -120,27 +121,27 @@ pub(crate) unsafe fn init(config: Config) {
let (sys_clk, sw) = match config.mux { let (sys_clk, sw) = match config.mux {
ClockSrc::HSI16(div) => { ClockSrc::HSI16(div) => {
// Enable HSI16 // Enable HSI16
let div: u8 = div.into(); let div: Hsidiv = div.into();
RCC.cr().write(|w| { RCC.cr().write(|w| {
w.set_hsidiv(div); w.set_hsidiv(div);
w.set_hsion(true) w.set_hsion(true)
}); });
while !RCC.cr().read().hsirdy() {} while !RCC.cr().read().hsirdy() {}
(HSI_FREQ >> div, 0x00) (HSI_FREQ >> div.0, Sw::HSI)
} }
ClockSrc::HSE(freq) => { ClockSrc::HSE(freq) => {
// Enable HSE // Enable HSE
RCC.cr().write(|w| w.set_hseon(true)); RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {} while !RCC.cr().read().hserdy() {}
(freq.0, 0x01) (freq.0, Sw::HSE)
} }
ClockSrc::LSI => { ClockSrc::LSI => {
// Enable LSI // Enable LSI
RCC.csr().write(|w| w.set_lsion(true)); RCC.csr().write(|w| w.set_lsion(true));
while !RCC.csr().read().lsirdy() {} while !RCC.csr().read().lsirdy() {}
(LSI_FREQ, 0x03) (LSI_FREQ, Sw::LSI)
} }
}; };
@ -150,20 +151,24 @@ pub(crate) unsafe fn init(config: Config) {
w.set_ppre(config.apb_pre.into()); w.set_ppre(config.apb_pre.into());
}); });
let ahb_freq: u32 = match config.ahb_pre { let ahb_div = match config.ahb_pre {
AHBPrescaler::NotDivided => sys_clk, AHBPrescaler::NotDivided => 1,
pre => { AHBPrescaler::Div2 => 2,
let pre: u8 = pre.into(); AHBPrescaler::Div4 => 4,
let pre = 1 << (pre as u32 - 7); AHBPrescaler::Div8 => 8,
sys_clk / pre AHBPrescaler::Div16 => 16,
} AHBPrescaler::Div64 => 64,
AHBPrescaler::Div128 => 128,
AHBPrescaler::Div256 => 256,
AHBPrescaler::Div512 => 512,
}; };
let ahb_freq = sys_clk / ahb_div;
let (apb_freq, apb_tim_freq) = match config.apb_pre { let (apb_freq, apb_tim_freq) = match config.apb_pre {
APBPrescaler::NotDivided => (ahb_freq, ahb_freq), APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
pre => { pre => {
let pre: u8 = pre.into(); let pre: Ppre = pre.into();
let pre: u8 = 1 << (pre - 3); let pre: u8 = 1 << (pre.0 - 3);
let freq = ahb_freq / pre as u32; let freq = ahb_freq / pre as u32;
(freq, freq * 2) (freq, freq * 2)
} }