stm32/rcc: extract and combine ahb/apb prescalers
This commit is contained in:
parent
fcbfd224a7
commit
2f18770e27
@ -1,5 +1,6 @@
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::flash::vals::Latency;
|
||||
use crate::pac::rcc::vals::{Hpre, Hsidiv, Ppre, Sw};
|
||||
use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
@ -45,58 +46,6 @@ impl Into<Hsidiv> for HSIPrescaler {
|
||||
}
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Into<Ppre> for APBPrescaler {
|
||||
fn into(self) -> Ppre {
|
||||
match self {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Hpre> for AHBPrescaler {
|
||||
fn into(self) -> Hpre {
|
||||
match self {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clocks configutation
|
||||
pub struct Config {
|
||||
pub mux: ClockSrc,
|
||||
|
174
embassy-stm32/src/rcc/common.rs
Normal file
174
embassy-stm32/src/rcc/common.rs
Normal file
@ -0,0 +1,174 @@
|
||||
use core::ops::Div;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use crate::pac::rcc;
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// Voltage Scale
|
||||
///
|
||||
/// Represents the voltage range feeding the CPU core. The maximum core
|
||||
/// clock frequency depends on this value.
|
||||
///
|
||||
/// Scale0 represents the highest voltage range
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VoltageScale {
|
||||
Scale0,
|
||||
Scale1,
|
||||
#[cfg(not(any(rcc_wl5, rcc_wle)))]
|
||||
Scale2,
|
||||
#[cfg(not(any(rcc_wl5, rcc_wle)))]
|
||||
Scale3,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
Div3,
|
||||
Div4,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
Div5,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
Div6,
|
||||
Div8,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
Div10,
|
||||
Div16,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
Div32,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
impl Div<AHBPrescaler> for Hertz {
|
||||
type Output = Hertz;
|
||||
|
||||
fn div(self, rhs: AHBPrescaler) -> Self::Output {
|
||||
let divisor = match rhs {
|
||||
AHBPrescaler::NotDivided => 1,
|
||||
AHBPrescaler::Div2 => 2,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
AHBPrescaler::Div3 => 3,
|
||||
AHBPrescaler::Div4 => 4,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
AHBPrescaler::Div5 => 5,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
AHBPrescaler::Div6 => 6,
|
||||
AHBPrescaler::Div8 => 8,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
AHBPrescaler::Div10 => 10,
|
||||
AHBPrescaler::Div16 => 16,
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
AHBPrescaler::Div32 => 32,
|
||||
AHBPrescaler::Div64 => 64,
|
||||
AHBPrescaler::Div128 => 128,
|
||||
AHBPrescaler::Div256 => 256,
|
||||
AHBPrescaler::Div512 => 512,
|
||||
};
|
||||
Hertz(self.0 / divisor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(rcc_g4, rcc_wb, rcc_wl5, rcc_wle)))]
|
||||
impl From<AHBPrescaler> for rcc::vals::Hpre {
|
||||
fn from(val: AHBPrescaler) -> rcc::vals::Hpre {
|
||||
use rcc::vals::Hpre;
|
||||
|
||||
match val {
|
||||
#[cfg(not(rcc_u5))]
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
#[cfg(rcc_u5)]
|
||||
AHBPrescaler::NotDivided => Hpre::NONE,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
impl From<AHBPrescaler> for u8 {
|
||||
fn from(val: AHBPrescaler) -> u8 {
|
||||
match val {
|
||||
AHBPrescaler::NotDivided => 0x0,
|
||||
AHBPrescaler::Div2 => 0x08,
|
||||
AHBPrescaler::Div3 => 0x01,
|
||||
AHBPrescaler::Div4 => 0x09,
|
||||
AHBPrescaler::Div5 => 0x02,
|
||||
AHBPrescaler::Div6 => 0x05,
|
||||
AHBPrescaler::Div8 => 0x0a,
|
||||
AHBPrescaler::Div10 => 0x06,
|
||||
AHBPrescaler::Div16 => 0x0b,
|
||||
AHBPrescaler::Div32 => 0x07,
|
||||
AHBPrescaler::Div64 => 0x0c,
|
||||
AHBPrescaler::Div128 => 0x0d,
|
||||
AHBPrescaler::Div256 => 0x0e,
|
||||
AHBPrescaler::Div512 => 0x0f,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Div<APBPrescaler> for Hertz {
|
||||
type Output = Hertz;
|
||||
|
||||
fn div(self, rhs: APBPrescaler) -> Self::Output {
|
||||
let divisor = match rhs {
|
||||
APBPrescaler::NotDivided => 1,
|
||||
APBPrescaler::Div2 => 2,
|
||||
APBPrescaler::Div4 => 4,
|
||||
APBPrescaler::Div8 => 8,
|
||||
APBPrescaler::Div16 => 16,
|
||||
};
|
||||
Hertz(self.0 / divisor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(rcc_f1, rcc_g4, rcc_h7, rcc_wb, rcc_wl5, rcc_wle)))]
|
||||
impl From<APBPrescaler> for rcc::vals::Ppre {
|
||||
fn from(val: APBPrescaler) -> rcc::vals::Ppre {
|
||||
use rcc::vals::Ppre;
|
||||
|
||||
match val {
|
||||
#[cfg(not(rcc_u5))]
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
#[cfg(rcc_u5)]
|
||||
APBPrescaler::NotDivided => Ppre::NONE,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
|
||||
impl From<APBPrescaler> for u8 {
|
||||
fn from(val: APBPrescaler) -> u8 {
|
||||
match val {
|
||||
APBPrescaler::NotDivided => 1,
|
||||
APBPrescaler::Div2 => 0x04,
|
||||
APBPrescaler::Div4 => 0x05,
|
||||
APBPrescaler::Div8 => 0x06,
|
||||
APBPrescaler::Div16 => 0x07,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
use core::convert::TryFrom;
|
||||
use core::ops::{Div, Mul};
|
||||
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::flash::vals::Latency;
|
||||
use crate::pac::rcc::vals::{Hpre, Pllp, Pllsrc, Ppre, Sw};
|
||||
use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
@ -200,114 +201,15 @@ pub struct PLLClocks {
|
||||
pub pll48_freq: Hertz,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
pub use super::common::VoltageScale;
|
||||
|
||||
impl Div<AHBPrescaler> for Hertz {
|
||||
type Output = Hertz;
|
||||
|
||||
fn div(self, rhs: AHBPrescaler) -> Self::Output {
|
||||
let divisor = match rhs {
|
||||
AHBPrescaler::NotDivided => 1,
|
||||
AHBPrescaler::Div2 => 2,
|
||||
AHBPrescaler::Div4 => 4,
|
||||
AHBPrescaler::Div8 => 8,
|
||||
AHBPrescaler::Div16 => 16,
|
||||
AHBPrescaler::Div64 => 64,
|
||||
AHBPrescaler::Div128 => 128,
|
||||
AHBPrescaler::Div256 => 256,
|
||||
AHBPrescaler::Div512 => 512,
|
||||
};
|
||||
Hertz(self.0 / divisor)
|
||||
}
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Div<APBPrescaler> for Hertz {
|
||||
type Output = Hertz;
|
||||
|
||||
fn div(self, rhs: APBPrescaler) -> Self::Output {
|
||||
let divisor = match rhs {
|
||||
APBPrescaler::NotDivided => 1,
|
||||
APBPrescaler::Div2 => 2,
|
||||
APBPrescaler::Div4 => 4,
|
||||
APBPrescaler::Div8 => 8,
|
||||
APBPrescaler::Div16 => 16,
|
||||
};
|
||||
Hertz(self.0 / divisor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Ppre> for APBPrescaler {
|
||||
fn into(self) -> Ppre {
|
||||
match self {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Hpre> for AHBPrescaler {
|
||||
fn into(self) -> Hpre {
|
||||
match self {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Voltage Range
|
||||
///
|
||||
/// Represents the system supply voltage range
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VoltageRange {
|
||||
/// 1.8 to 3.6 V
|
||||
Min1V8,
|
||||
/// 2.1 to 3.6 V
|
||||
Min2V1,
|
||||
/// 2.4 to 3.6 V
|
||||
Min2V4,
|
||||
/// 2.7 to 3.6 V
|
||||
Min2V7,
|
||||
}
|
||||
|
||||
impl VoltageRange {
|
||||
impl VoltageScale {
|
||||
const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> {
|
||||
let ahb_freq = ahb_freq.0;
|
||||
// Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock
|
||||
// frequency
|
||||
match self {
|
||||
VoltageRange::Min1V8 => {
|
||||
VoltageScale::Scale3 => {
|
||||
if ahb_freq <= 16_000_000 {
|
||||
Some(Latency::WS0)
|
||||
} else if ahb_freq <= 32_000_000 {
|
||||
@ -328,7 +230,7 @@ impl VoltageRange {
|
||||
None
|
||||
}
|
||||
}
|
||||
VoltageRange::Min2V1 => {
|
||||
VoltageScale::Scale2 => {
|
||||
if ahb_freq <= 18_000_000 {
|
||||
Some(Latency::WS0)
|
||||
} else if ahb_freq <= 36_000_000 {
|
||||
@ -347,7 +249,7 @@ impl VoltageRange {
|
||||
None
|
||||
}
|
||||
}
|
||||
VoltageRange::Min2V4 => {
|
||||
VoltageScale::Scale1 => {
|
||||
if ahb_freq <= 24_000_000 {
|
||||
Some(Latency::WS0)
|
||||
} else if ahb_freq <= 48_000_000 {
|
||||
@ -362,7 +264,7 @@ impl VoltageRange {
|
||||
None
|
||||
}
|
||||
}
|
||||
VoltageRange::Min2V7 => {
|
||||
VoltageScale::Scale0 => {
|
||||
if ahb_freq <= 30_000_000 {
|
||||
Some(Latency::WS0)
|
||||
} else if ahb_freq <= 60_000_000 {
|
||||
@ -386,7 +288,7 @@ pub struct Config {
|
||||
pub pll_mux: PLLSrc,
|
||||
pub pll: PLLConfig,
|
||||
pub mux: ClockSrc,
|
||||
pub voltage: VoltageRange,
|
||||
pub voltage: VoltageScale,
|
||||
pub ahb_pre: AHBPrescaler,
|
||||
pub apb1_pre: APBPrescaler,
|
||||
pub apb2_pre: APBPrescaler,
|
||||
@ -400,7 +302,7 @@ impl Default for Config {
|
||||
hsi: true,
|
||||
pll_mux: PLLSrc::HSI,
|
||||
pll: PLLConfig::default(),
|
||||
voltage: VoltageRange::Min1V8,
|
||||
voltage: VoltageScale::Scale3,
|
||||
mux: ClockSrc::HSI,
|
||||
ahb_pre: AHBPrescaler::NotDivided,
|
||||
apb1_pre: APBPrescaler::NotDivided,
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::flash::vals::Latency;
|
||||
use crate::pac::rcc::vals::{self, Hpre, Hsidiv, Ppre, Sw};
|
||||
use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw};
|
||||
use crate::pac::{FLASH, PWR, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
@ -172,58 +173,6 @@ impl From<Pllr> for u32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Into<Ppre> for APBPrescaler {
|
||||
fn into(self) -> Ppre {
|
||||
match self {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Hpre> for AHBPrescaler {
|
||||
fn into(self) -> Hpre {
|
||||
match self {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clocks configutation
|
||||
pub struct Config {
|
||||
pub mux: ClockSrc,
|
||||
@ -425,25 +374,14 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
FLASH.acr().modify(|w| w.set_latency(target_flash_latency));
|
||||
}
|
||||
|
||||
let ahb_div = match config.ahb_pre {
|
||||
AHBPrescaler::NotDivided => 1,
|
||||
AHBPrescaler::Div2 => 2,
|
||||
AHBPrescaler::Div4 => 4,
|
||||
AHBPrescaler::Div8 => 8,
|
||||
AHBPrescaler::Div16 => 16,
|
||||
AHBPrescaler::Div64 => 64,
|
||||
AHBPrescaler::Div128 => 128,
|
||||
AHBPrescaler::Div256 => 256,
|
||||
AHBPrescaler::Div512 => 512,
|
||||
};
|
||||
let ahb_freq = sys_clk / ahb_div;
|
||||
let ahb_freq = Hertz(sys_clk) / config.ahb_pre;
|
||||
|
||||
let (apb_freq, apb_tim_freq) = match config.apb_pre {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
APBPrescaler::NotDivided => (ahb_freq.0, ahb_freq.0),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let freq = ahb_freq.0 / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
};
|
||||
@ -455,7 +393,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: Hertz(sys_clk),
|
||||
ahb1: Hertz(ahb_freq),
|
||||
ahb1: ahb_freq,
|
||||
apb1: Hertz(apb_freq),
|
||||
apb1_tim: Hertz(apb_tim_freq),
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ use stm32_metapac::flash::vals::Latency;
|
||||
use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw};
|
||||
use stm32_metapac::FLASH;
|
||||
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::{PWR, RCC};
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
@ -21,39 +22,8 @@ pub enum ClockSrc {
|
||||
PLL,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
/// PLL clock input source
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum PllSrc {
|
||||
HSI16,
|
||||
HSE(Hertz),
|
||||
}
|
||||
|
||||
impl Into<Pllsrc> for PllSrc {
|
||||
fn into(self) -> Pllsrc {
|
||||
impl Into<u8> for APBPrescaler {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
PllSrc::HSE(..) => Pllsrc::HSE,
|
||||
PllSrc::HSI16 => Pllsrc::HSI16,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use stm32_metapac::rcc::vals::{Hpre, Ppre, Timpre};
|
||||
use stm32_metapac::rcc::vals::Timpre;
|
||||
|
||||
use crate::pac::pwr::vals::Vos;
|
||||
use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw};
|
||||
@ -26,21 +26,7 @@ const VCO_MAX: u32 = 420_000_000;
|
||||
const VCO_WIDE_MIN: u32 = 128_000_000;
|
||||
const VCO_WIDE_MAX: u32 = 560_000_000;
|
||||
|
||||
/// Voltage Scale
|
||||
///
|
||||
/// Represents the voltage range feeding the CPU core. The maximum core
|
||||
/// clock frequency depends on this value.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VoltageScale {
|
||||
/// VOS 0 range VCORE 1.30V - 1.40V
|
||||
Scale0,
|
||||
/// VOS 1 range VCORE 1.15V - 1.26V
|
||||
Scale1,
|
||||
/// VOS 2 range VCORE 1.05V - 1.15V
|
||||
Scale2,
|
||||
/// VOS 3 range VCORE 0.95V - 1.05V
|
||||
Scale3,
|
||||
}
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale};
|
||||
|
||||
pub enum HseMode {
|
||||
/// crystal/ceramic oscillator (HSEBYP=0)
|
||||
@ -105,57 +91,7 @@ pub struct Pll {
|
||||
pub divr: Option<u16>,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
impl AHBPrescaler {
|
||||
fn div(&self, clk: Hertz) -> Hertz {
|
||||
match self {
|
||||
Self::NotDivided => clk,
|
||||
Self::Div2 => clk / 2u32,
|
||||
Self::Div4 => clk / 4u32,
|
||||
Self::Div8 => clk / 8u32,
|
||||
Self::Div16 => clk / 16u32,
|
||||
Self::Div64 => clk / 64u32,
|
||||
Self::Div128 => clk / 128u32,
|
||||
Self::Div256 => clk / 256u32,
|
||||
Self::Div512 => clk / 512u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl APBPrescaler {
|
||||
fn div(&self, clk: Hertz) -> Hertz {
|
||||
match self {
|
||||
Self::NotDivided => clk,
|
||||
Self::Div2 => clk / 2u32,
|
||||
Self::Div4 => clk / 4u32,
|
||||
Self::Div8 => clk / 8u32,
|
||||
Self::Div16 => clk / 16u32,
|
||||
}
|
||||
}
|
||||
|
||||
fn div_tim(&self, clk: Hertz, tim: TimerPrescaler) -> Hertz {
|
||||
match (tim, self) {
|
||||
// The timers kernel clock is equal to rcc_hclk1 if PPRE1 or PPRE2 corresponds to a
|
||||
@ -193,34 +129,6 @@ impl From<TimerPrescaler> for Timpre {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<APBPrescaler> for Ppre {
|
||||
fn from(val: APBPrescaler) -> Ppre {
|
||||
match val {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AHBPrescaler> for Hpre {
|
||||
fn from(val: AHBPrescaler) -> Hpre {
|
||||
match val {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration of the core clocks
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
@ -406,13 +314,13 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
};
|
||||
assert!(sys <= max_clk);
|
||||
|
||||
let hclk = config.ahb_pre.div(sys);
|
||||
let hclk = sys / config.ahb_pre;
|
||||
|
||||
let apb1 = config.apb1_pre.div(hclk);
|
||||
let apb1 = hclk / config.apb1_pre;
|
||||
let apb1_tim = config.apb1_pre.div_tim(hclk, config.timer_prescaler);
|
||||
let apb2 = config.apb2_pre.div(hclk);
|
||||
let apb2 = hclk / config.apb2_pre;
|
||||
let apb2_tim = config.apb2_pre.div_tim(hclk, config.timer_prescaler);
|
||||
let apb3 = config.apb3_pre.div(hclk);
|
||||
let apb3 = hclk / config.apb3_pre;
|
||||
|
||||
flash_setup(hclk, config.voltage_scale);
|
||||
|
||||
|
@ -24,21 +24,7 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
|
||||
/// LSI speed
|
||||
pub const LSI_FREQ: Hertz = Hertz(32_000);
|
||||
|
||||
/// Voltage Scale
|
||||
///
|
||||
/// Represents the voltage range feeding the CPU core. The maximum core
|
||||
/// clock frequency depends on this value.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VoltageScale {
|
||||
/// VOS 0 range VCORE 1.26V - 1.40V
|
||||
Scale0,
|
||||
/// VOS 1 range VCORE 1.15V - 1.26V
|
||||
Scale1,
|
||||
/// VOS 2 range VCORE 1.05V - 1.15V
|
||||
Scale2,
|
||||
/// VOS 3 range VCORE 0.95V - 1.05V
|
||||
Scale3,
|
||||
}
|
||||
pub use super::common::VoltageScale;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum AdcClockSource {
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw};
|
||||
use crate::pac::RCC;
|
||||
#[cfg(crs)]
|
||||
@ -70,30 +71,6 @@ pub enum PLLMul {
|
||||
Mul48,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
/// PLL clock input source
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PLLSource {
|
||||
@ -136,34 +113,6 @@ impl From<PLLSource> for Pllsrc {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<APBPrescaler> for Ppre {
|
||||
fn from(val: APBPrescaler) -> Ppre {
|
||||
match val {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AHBPrescaler> for Hpre {
|
||||
fn from(val: AHBPrescaler) -> Hpre {
|
||||
match val {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MSIRange> for Msirange {
|
||||
fn from(val: MSIRange) -> Msirange {
|
||||
match val {
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
@ -68,30 +69,6 @@ pub enum PLLMul {
|
||||
Mul48,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
/// PLL clock input source
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PLLSource {
|
||||
@ -134,34 +111,6 @@ impl From<PLLSource> for Pllsrc {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<APBPrescaler> for Ppre {
|
||||
fn from(val: APBPrescaler) -> Ppre {
|
||||
match val {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AHBPrescaler> for Hpre {
|
||||
fn from(val: AHBPrescaler) -> Hpre {
|
||||
match val {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MSIRange> for Msirange {
|
||||
fn from(val: MSIRange) -> Msirange {
|
||||
match val {
|
||||
|
@ -4,6 +4,7 @@ use embassy_hal_internal::into_ref;
|
||||
use stm32_metapac::rcc::regs::Cfgr;
|
||||
use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel};
|
||||
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::gpio::Speed;
|
||||
use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw};
|
||||
@ -78,30 +79,6 @@ pub enum PLLDiv {
|
||||
Div4,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
/// PLL clock input source
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PLLSource {
|
||||
@ -209,34 +186,6 @@ impl From<PLLSource> for Pllsrc {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<APBPrescaler> for Ppre {
|
||||
fn from(val: APBPrescaler) -> Ppre {
|
||||
match val {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AHBPrescaler> for Hpre {
|
||||
fn from(val: AHBPrescaler) -> Hpre {
|
||||
match val {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MSIRange> for Msirange {
|
||||
fn from(val: MSIRange) -> Msirange {
|
||||
match val {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use stm32_metapac::PWR;
|
||||
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
@ -71,30 +72,6 @@ pub enum PLLDiv {
|
||||
Div4,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
/// PLL clock input source
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PLLSource {
|
||||
@ -202,34 +179,6 @@ impl From<PLLSource> for Pllsrc {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<APBPrescaler> for Ppre {
|
||||
fn from(val: APBPrescaler) -> Ppre {
|
||||
match val {
|
||||
APBPrescaler::NotDivided => Ppre::DIV1,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AHBPrescaler> for Hpre {
|
||||
fn from(val: AHBPrescaler) -> Hpre {
|
||||
match val {
|
||||
AHBPrescaler::NotDivided => Hpre::DIV1,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MSIRange> for Msirange {
|
||||
fn from(val: MSIRange) -> Msirange {
|
||||
match val {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#![macro_use]
|
||||
|
||||
pub mod common;
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use crate::time::Hertz;
|
||||
|
@ -1,5 +1,6 @@
|
||||
use stm32_metapac::rcc::vals::{Hpre, Msirange, Msirgsel, Pllm, Pllsrc, Ppre, Sw};
|
||||
use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw};
|
||||
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
@ -10,19 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000);
|
||||
/// LSI speed
|
||||
pub const LSI_FREQ: Hertz = Hertz(32_000);
|
||||
|
||||
/// Voltage Scale
|
||||
///
|
||||
/// Represents the voltage range feeding the CPU core. The maximum core
|
||||
/// clock frequency depends on this value.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VoltageScale {
|
||||
// Highest frequency
|
||||
Range1,
|
||||
Range2,
|
||||
Range3,
|
||||
// Lowest power
|
||||
Range4,
|
||||
}
|
||||
pub use super::common::VoltageScale;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ClockSrc {
|
||||
@ -130,36 +119,6 @@ impl Into<Pllm> for PllM {
|
||||
}
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
impl Into<Hpre> for AHBPrescaler {
|
||||
fn into(self) -> Hpre {
|
||||
match self {
|
||||
AHBPrescaler::NotDivided => Hpre::NONE,
|
||||
AHBPrescaler::Div2 => Hpre::DIV2,
|
||||
AHBPrescaler::Div4 => Hpre::DIV4,
|
||||
AHBPrescaler::Div8 => Hpre::DIV8,
|
||||
AHBPrescaler::Div16 => Hpre::DIV16,
|
||||
AHBPrescaler::Div64 => Hpre::DIV64,
|
||||
AHBPrescaler::Div128 => Hpre::DIV128,
|
||||
AHBPrescaler::Div256 => Hpre::DIV256,
|
||||
AHBPrescaler::Div512 => Hpre::DIV512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u8> for AHBPrescaler {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
@ -182,28 +141,6 @@ impl Default for AHBPrescaler {
|
||||
}
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Into<Ppre> for APBPrescaler {
|
||||
fn into(self) -> Ppre {
|
||||
match self {
|
||||
APBPrescaler::NotDivided => Ppre::NONE,
|
||||
APBPrescaler::Div2 => Ppre::DIV2,
|
||||
APBPrescaler::Div4 => Ppre::DIV4,
|
||||
APBPrescaler::Div8 => Ppre::DIV8,
|
||||
APBPrescaler::Div16 => Ppre::DIV16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for APBPrescaler {
|
||||
fn default() -> Self {
|
||||
APBPrescaler::NotDivided
|
||||
@ -389,12 +326,12 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
|
||||
// TODO make configurable
|
||||
let power_vos = VoltageScale::Range4;
|
||||
let power_vos = VoltageScale::Scale3;
|
||||
|
||||
// states and programming delay
|
||||
let wait_states = match power_vos {
|
||||
// VOS 0 range VCORE 1.26V - 1.40V
|
||||
VoltageScale::Range1 => {
|
||||
VoltageScale::Scale0 => {
|
||||
if sys_clk < 32_000_000 {
|
||||
0
|
||||
} else if sys_clk < 64_000_000 {
|
||||
@ -408,7 +345,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
}
|
||||
// VOS 1 range VCORE 1.15V - 1.26V
|
||||
VoltageScale::Range2 => {
|
||||
VoltageScale::Scale1 => {
|
||||
if sys_clk < 30_000_000 {
|
||||
0
|
||||
} else if sys_clk < 60_000_000 {
|
||||
@ -420,7 +357,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
}
|
||||
// VOS 2 range VCORE 1.05V - 1.15V
|
||||
VoltageScale::Range3 => {
|
||||
VoltageScale::Scale2 => {
|
||||
if sys_clk < 24_000_000 {
|
||||
0
|
||||
} else if sys_clk < 48_000_000 {
|
||||
@ -430,7 +367,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
}
|
||||
// VOS 3 range VCORE 0.95V - 1.05V
|
||||
VoltageScale::Range4 => {
|
||||
VoltageScale::Scale3 => {
|
||||
if sys_clk < 12_000_000 {
|
||||
0
|
||||
} else {
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::rcc::Clocks;
|
||||
use crate::time::{khz, mhz, Hertz};
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler};
|
||||
use crate::pac::RCC;
|
||||
use crate::rcc::{set_freqs, Clocks, Clocks};
|
||||
use crate::time::{khz, mhz, Hertz, Hertz};
|
||||
|
||||
/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
|
||||
/// and with the addition of the init function to configure a system clock.
|
||||
@ -102,68 +104,6 @@ pub struct Pll {
|
||||
pub divr: Option<u16>,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div3,
|
||||
Div4,
|
||||
Div5,
|
||||
Div6,
|
||||
Div8,
|
||||
Div10,
|
||||
Div16,
|
||||
Div32,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Into<u8> for APBPrescaler {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
APBPrescaler::NotDivided => 1,
|
||||
APBPrescaler::Div2 => 0x04,
|
||||
APBPrescaler::Div4 => 0x05,
|
||||
APBPrescaler::Div8 => 0x06,
|
||||
APBPrescaler::Div16 => 0x07,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u8> for AHBPrescaler {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
AHBPrescaler::NotDivided => 0x0,
|
||||
AHBPrescaler::Div2 => 0x08,
|
||||
AHBPrescaler::Div3 => 0x01,
|
||||
AHBPrescaler::Div4 => 0x09,
|
||||
AHBPrescaler::Div5 => 0x02,
|
||||
AHBPrescaler::Div6 => 0x05,
|
||||
AHBPrescaler::Div8 => 0x0a,
|
||||
AHBPrescaler::Div10 => 0x06,
|
||||
AHBPrescaler::Div16 => 0x0b,
|
||||
AHBPrescaler::Div32 => 0x07,
|
||||
AHBPrescaler::Div64 => 0x0c,
|
||||
AHBPrescaler::Div128 => 0x0d,
|
||||
AHBPrescaler::Div256 => 0x0e,
|
||||
AHBPrescaler::Div512 => 0x0f,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clocks configutation
|
||||
pub struct Config {
|
||||
pub hse: Option<Hse>,
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale};
|
||||
use crate::pac::pwr::vals::Dbp;
|
||||
use crate::pac::{FLASH, PWR, RCC};
|
||||
use crate::pac::{FLASH, FLASH, PWR, RCC, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
@ -73,9 +74,9 @@ impl MSIRange {
|
||||
|
||||
fn vos(&self) -> VoltageScale {
|
||||
if self > &MSIRange::Range8 {
|
||||
VoltageScale::Range1
|
||||
VoltageScale::Scale0
|
||||
} else {
|
||||
VoltageScale::Range2
|
||||
VoltageScale::Scale1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,78 +106,6 @@ impl Into<u8> for MSIRange {
|
||||
}
|
||||
}
|
||||
|
||||
/// Voltage Scale
|
||||
///
|
||||
/// Represents the voltage range feeding the CPU core. The maximum core
|
||||
/// clock frequency depends on this value.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VoltageScale {
|
||||
Range1,
|
||||
Range2,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AHBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div3,
|
||||
Div4,
|
||||
Div5,
|
||||
Div6,
|
||||
Div8,
|
||||
Div10,
|
||||
Div16,
|
||||
Div32,
|
||||
Div64,
|
||||
Div128,
|
||||
Div256,
|
||||
Div512,
|
||||
}
|
||||
|
||||
/// APB prescaler
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum APBPrescaler {
|
||||
NotDivided,
|
||||
Div2,
|
||||
Div4,
|
||||
Div8,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl Into<u8> for APBPrescaler {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
APBPrescaler::NotDivided => 1,
|
||||
APBPrescaler::Div2 => 0x04,
|
||||
APBPrescaler::Div4 => 0x05,
|
||||
APBPrescaler::Div8 => 0x06,
|
||||
APBPrescaler::Div16 => 0x07,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u8> for AHBPrescaler {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
AHBPrescaler::NotDivided => 0x0,
|
||||
AHBPrescaler::Div2 => 0x08,
|
||||
AHBPrescaler::Div3 => 0x01,
|
||||
AHBPrescaler::Div4 => 0x09,
|
||||
AHBPrescaler::Div5 => 0x02,
|
||||
AHBPrescaler::Div6 => 0x05,
|
||||
AHBPrescaler::Div8 => 0x0a,
|
||||
AHBPrescaler::Div10 => 0x06,
|
||||
AHBPrescaler::Div16 => 0x0b,
|
||||
AHBPrescaler::Div32 => 0x07,
|
||||
AHBPrescaler::Div64 => 0x0c,
|
||||
AHBPrescaler::Div128 => 0x0d,
|
||||
AHBPrescaler::Div256 => 0x0e,
|
||||
AHBPrescaler::Div512 => 0x0f,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clocks configutation
|
||||
pub struct Config {
|
||||
pub mux: ClockSrc,
|
||||
@ -220,8 +149,8 @@ pub enum Lsedrv {
|
||||
|
||||
pub(crate) unsafe fn init(config: Config) {
|
||||
let (sys_clk, sw, vos) = match config.mux {
|
||||
ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Range2),
|
||||
ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Range1),
|
||||
ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Scale1),
|
||||
ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Scale0),
|
||||
ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()),
|
||||
};
|
||||
|
||||
@ -266,12 +195,12 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
// Adjust flash latency
|
||||
let flash_clk_src_freq: u32 = shd_ahb_freq;
|
||||
let ws = match vos {
|
||||
VoltageScale::Range1 => match flash_clk_src_freq {
|
||||
VoltageScale::Scale0 => match flash_clk_src_freq {
|
||||
0..=18_000_000 => 0b000,
|
||||
18_000_001..=36_000_000 => 0b001,
|
||||
_ => 0b010,
|
||||
},
|
||||
VoltageScale::Range2 => match flash_clk_src_freq {
|
||||
VoltageScale::Scale1 => match flash_clk_src_freq {
|
||||
0..=6_000_000 => 0b000,
|
||||
6_000_001..=12_000_000 => 0b001,
|
||||
_ => 0b010,
|
||||
|
Loading…
Reference in New Issue
Block a user