Merge branch 'main' of https://github.com/embassy-rs/embassy into embassy-stm32/rcc-rtc-l4
This commit is contained in:
@ -126,7 +126,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
});
|
||||
while !RCC.cr().read().hsirdy() {}
|
||||
|
||||
(HSI_FREQ.0 >> div.0, Sw::HSI)
|
||||
(HSI_FREQ.0 >> div.to_bits(), Sw::HSI)
|
||||
}
|
||||
ClockSrc::HSE(freq) => {
|
||||
// Enable HSE
|
||||
@ -157,7 +157,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
let mut set_flash_latency_after = false;
|
||||
FLASH.acr().modify(|w| {
|
||||
// Is the current flash latency less than what we need at the new SYSCLK?
|
||||
if w.latency().0 <= target_flash_latency.0 {
|
||||
if w.latency().to_bits() <= target_flash_latency.to_bits() {
|
||||
// We must increase the number of wait states now
|
||||
w.set_latency(target_flash_latency)
|
||||
} else {
|
||||
@ -171,12 +171,12 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
// > Flash memory.
|
||||
//
|
||||
// Enable flash prefetching if we have at least one wait state, and disable it otherwise.
|
||||
w.set_prften(target_flash_latency.0 > 0);
|
||||
w.set_prften(target_flash_latency.to_bits() > 0);
|
||||
});
|
||||
|
||||
if !set_flash_latency_after {
|
||||
// Spin until the effective flash latency is compatible with the clock change
|
||||
while FLASH.acr().read().latency().0 < target_flash_latency.0 {}
|
||||
while FLASH.acr().read().latency().to_bits() < target_flash_latency.to_bits() {}
|
||||
}
|
||||
|
||||
// Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once
|
||||
@ -218,7 +218,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use stm32_metapac::flash::vals::Latency;
|
||||
|
||||
use super::{set_freqs, Clocks};
|
||||
use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Sw, Usbsw};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
@ -85,14 +87,11 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
let timer_mul = if ppre == 1 { 1 } else { 2 };
|
||||
|
||||
FLASH.acr().write(|w| {
|
||||
let latency = if real_sysclk <= 24_000_000 {
|
||||
0
|
||||
} else if real_sysclk <= 48_000_000 {
|
||||
1
|
||||
w.set_latency(if real_sysclk <= 24_000_000 {
|
||||
Latency::WS0
|
||||
} else {
|
||||
2
|
||||
};
|
||||
w.latency().0 = latency;
|
||||
Latency::WS1
|
||||
});
|
||||
});
|
||||
|
||||
match (config.hse.is_some(), use_hsi48) {
|
||||
@ -134,20 +133,20 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
// TODO: Option to use CRS (Clock Recovery)
|
||||
|
||||
if let Some(pllmul_bits) = pllmul_bits {
|
||||
RCC.cfgr().modify(|w| w.set_pllmul(Pllmul(pllmul_bits)));
|
||||
RCC.cfgr().modify(|w| w.set_pllmul(Pllmul::from_bits(pllmul_bits)));
|
||||
|
||||
RCC.cr().modify(|w| w.set_pllon(true));
|
||||
while !RCC.cr().read().pllrdy() {}
|
||||
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_ppre(Ppre(ppre_bits));
|
||||
w.set_hpre(Hpre(hpre_bits));
|
||||
w.set_ppre(Ppre::from_bits(ppre_bits));
|
||||
w.set_hpre(Hpre::from_bits(hpre_bits));
|
||||
w.set_sw(Sw::PLL)
|
||||
});
|
||||
} else {
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_ppre(Ppre(ppre_bits));
|
||||
w.set_hpre(Hpre(hpre_bits));
|
||||
w.set_ppre(Ppre::from_bits(ppre_bits));
|
||||
w.set_hpre(Hpre::from_bits(hpre_bits));
|
||||
|
||||
if config.hse.is_some() {
|
||||
w.set_sw(Sw::HSE);
|
||||
|
@ -106,11 +106,11 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
// Only needed for stm32f103?
|
||||
FLASH.acr().write(|w| {
|
||||
w.set_latency(if real_sysclk <= 24_000_000 {
|
||||
Latency(0b000)
|
||||
Latency::WS0
|
||||
} else if real_sysclk <= 48_000_000 {
|
||||
Latency(0b001)
|
||||
Latency::WS1
|
||||
} else {
|
||||
Latency(0b010)
|
||||
Latency::WS2
|
||||
});
|
||||
});
|
||||
|
||||
@ -147,12 +147,13 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
if let Some(pllmul_bits) = pllmul_bits {
|
||||
let pllctpre_flag: u8 = if config.pllxtpre { 1 } else { 0 };
|
||||
RCC.cfgr().modify(|w| w.set_pllxtpre(Pllxtpre(pllctpre_flag)));
|
||||
RCC.cfgr()
|
||||
.modify(|w| w.set_pllxtpre(Pllxtpre::from_bits(pllctpre_flag)));
|
||||
|
||||
// enable PLL and wait for it to be ready
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_pllmul(Pllmul(pllmul_bits));
|
||||
w.set_pllsrc(Pllsrc(config.hse.is_some() as u8));
|
||||
w.set_pllmul(Pllmul::from_bits(pllmul_bits));
|
||||
w.set_pllsrc(Pllsrc::from_bits(config.hse.is_some() as u8));
|
||||
});
|
||||
|
||||
RCC.cr().modify(|w| w.set_pllon(true));
|
||||
@ -161,22 +162,19 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
// Only needed for stm32f103?
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_adcpre(Adcpre(apre_bits));
|
||||
w.set_ppre2(Ppre1(ppre2_bits));
|
||||
w.set_ppre1(Ppre1(ppre1_bits));
|
||||
w.set_hpre(Hpre(hpre_bits));
|
||||
w.set_adcpre(Adcpre::from_bits(apre_bits));
|
||||
w.set_ppre2(Ppre1::from_bits(ppre2_bits));
|
||||
w.set_ppre1(Ppre1::from_bits(ppre1_bits));
|
||||
w.set_hpre(Hpre::from_bits(hpre_bits));
|
||||
#[cfg(not(rcc_f100))]
|
||||
w.set_usbpre(Usbpre(usbpre as u8));
|
||||
w.set_sw(Sw(if pllmul_bits.is_some() {
|
||||
// PLL
|
||||
0b10
|
||||
w.set_usbpre(Usbpre::from_bits(usbpre as u8));
|
||||
w.set_sw(if pllmul_bits.is_some() {
|
||||
Sw::PLL
|
||||
} else if config.hse.is_some() {
|
||||
// HSE
|
||||
0b1
|
||||
Sw::HSE
|
||||
} else {
|
||||
// HSI
|
||||
0b0
|
||||
}));
|
||||
Sw::HSI
|
||||
});
|
||||
});
|
||||
|
||||
set_freqs(Clocks {
|
||||
|
@ -485,7 +485,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
w.set_ppre1(config.apb1_pre.into());
|
||||
w.set_ppre2(config.apb2_pre.into());
|
||||
});
|
||||
while RCC.cfgr().read().sws() != sw.0 {}
|
||||
while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {}
|
||||
|
||||
// Turn off HSI to save power if we don't need it
|
||||
if !config.hsi {
|
||||
|
@ -36,18 +36,18 @@ pub struct Config {
|
||||
}
|
||||
|
||||
#[cfg(stm32f410)]
|
||||
unsafe fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> {
|
||||
fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> {
|
||||
None
|
||||
}
|
||||
|
||||
// Not currently implemented, but will be in the future
|
||||
#[cfg(any(stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))]
|
||||
unsafe fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> {
|
||||
fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))]
|
||||
unsafe fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> {
|
||||
fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> {
|
||||
let min_div = 2;
|
||||
let max_div = 7;
|
||||
let target = match plli2s {
|
||||
@ -82,18 +82,12 @@ unsafe fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> {
|
||||
Some(output)
|
||||
}
|
||||
|
||||
unsafe fn setup_pll(
|
||||
pllsrcclk: u32,
|
||||
use_hse: bool,
|
||||
pllsysclk: Option<u32>,
|
||||
plli2s: Option<u32>,
|
||||
pll48clk: bool,
|
||||
) -> PllResults {
|
||||
fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, plli2s: Option<u32>, pll48clk: bool) -> PllResults {
|
||||
use crate::pac::rcc::vals::{Pllp, Pllsrc};
|
||||
|
||||
let sysclk = pllsysclk.unwrap_or(pllsrcclk);
|
||||
if pllsysclk.is_none() && !pll48clk {
|
||||
RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc(use_hse as u8)));
|
||||
RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)));
|
||||
|
||||
return PllResults {
|
||||
use_pll: false,
|
||||
@ -147,9 +141,9 @@ unsafe fn setup_pll(
|
||||
RCC.pllcfgr().modify(|w| {
|
||||
w.set_pllm(pllm as u8);
|
||||
w.set_plln(plln as u16);
|
||||
w.set_pllp(Pllp(pllp as u8));
|
||||
w.set_pllp(Pllp::from_bits(pllp as u8));
|
||||
w.set_pllq(pllq as u8);
|
||||
w.set_pllsrc(Pllsrc(use_hse as u8));
|
||||
w.set_pllsrc(Pllsrc::from_bits(use_hse as u8));
|
||||
});
|
||||
|
||||
let real_pllsysclk = vco_in * plln / sysclk_div;
|
||||
@ -320,7 +314,7 @@ impl<'d, T: McoInstance> Mco<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn flash_setup(sysclk: u32) {
|
||||
fn flash_setup(sysclk: u32) {
|
||||
use crate::pac::flash::vals::Latency;
|
||||
|
||||
// Be conservative with voltage ranges
|
||||
@ -329,7 +323,7 @@ unsafe fn flash_setup(sysclk: u32) {
|
||||
critical_section::with(|_| {
|
||||
FLASH
|
||||
.acr()
|
||||
.modify(|w| w.set_latency(Latency(((sysclk - 1) / FLASH_LATENCY_STEP) as u8)));
|
||||
.modify(|w| w.set_latency(Latency::from_bits(((sysclk - 1) / FLASH_LATENCY_STEP) as u8)));
|
||||
});
|
||||
}
|
||||
|
||||
@ -446,8 +440,8 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_ppre2(Ppre(ppre2_bits));
|
||||
w.set_ppre1(Ppre(ppre1_bits));
|
||||
w.set_ppre2(Ppre::from_bits(ppre2_bits));
|
||||
w.set_ppre1(Ppre::from_bits(ppre1_bits));
|
||||
w.set_hpre(hpre_bits);
|
||||
});
|
||||
|
||||
|
@ -25,12 +25,12 @@ pub struct Config {
|
||||
pub pll48: bool,
|
||||
}
|
||||
|
||||
unsafe fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults {
|
||||
fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults {
|
||||
use crate::pac::rcc::vals::{Pllp, Pllsrc};
|
||||
|
||||
let sysclk = pllsysclk.unwrap_or(pllsrcclk);
|
||||
if pllsysclk.is_none() && !pll48clk {
|
||||
RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc(use_hse as u8)));
|
||||
RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)));
|
||||
|
||||
return PllResults {
|
||||
use_pll: false,
|
||||
@ -83,9 +83,9 @@ unsafe fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48
|
||||
RCC.pllcfgr().modify(|w| {
|
||||
w.set_pllm(pllm as u8);
|
||||
w.set_plln(plln as u16);
|
||||
w.set_pllp(Pllp(pllp as u8));
|
||||
w.set_pllp(Pllp::from_bits(pllp as u8));
|
||||
w.set_pllq(pllq as u8);
|
||||
w.set_pllsrc(Pllsrc(use_hse as u8));
|
||||
w.set_pllsrc(Pllsrc::from_bits(use_hse as u8));
|
||||
});
|
||||
|
||||
let real_pllsysclk = vco_in * plln / sysclk_div;
|
||||
@ -97,7 +97,7 @@ unsafe fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn flash_setup(sysclk: u32) {
|
||||
fn flash_setup(sysclk: u32) {
|
||||
use crate::pac::flash::vals::Latency;
|
||||
|
||||
// Be conservative with voltage ranges
|
||||
@ -106,7 +106,7 @@ unsafe fn flash_setup(sysclk: u32) {
|
||||
critical_section::with(|_| {
|
||||
FLASH
|
||||
.acr()
|
||||
.modify(|w| w.set_latency(Latency(((sysclk - 1) / FLASH_LATENCY_STEP) as u8)));
|
||||
.modify(|w| w.set_latency(Latency::from_bits(((sysclk - 1) / FLASH_LATENCY_STEP) as u8)));
|
||||
});
|
||||
}
|
||||
|
||||
@ -246,8 +246,8 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_ppre2(Ppre(ppre2_bits));
|
||||
w.set_ppre1(Ppre(ppre1_bits));
|
||||
w.set_ppre2(Ppre::from_bits(ppre2_bits));
|
||||
w.set_ppre1(Ppre::from_bits(ppre1_bits));
|
||||
w.set_hpre(hpre_bits);
|
||||
});
|
||||
|
||||
|
@ -245,7 +245,7 @@ impl Default for Config {
|
||||
}
|
||||
|
||||
impl PllConfig {
|
||||
pub(crate) unsafe fn init(self) -> u32 {
|
||||
pub(crate) fn init(self) -> u32 {
|
||||
assert!(self.n >= 8 && self.n <= 86);
|
||||
let (src, input_freq) = match self.source {
|
||||
PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ.0),
|
||||
@ -344,7 +344,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
});
|
||||
while !RCC.cr().read().hsirdy() {}
|
||||
|
||||
(HSI_FREQ.0 >> div.0, Sw::HSI)
|
||||
(HSI_FREQ.0 >> div.to_bits(), Sw::HSI)
|
||||
}
|
||||
ClockSrc::HSE(freq) => {
|
||||
// Enable HSE
|
||||
@ -381,7 +381,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
let mut set_flash_latency_after = false;
|
||||
FLASH.acr().modify(|w| {
|
||||
// Is the current flash latency less than what we need at the new SYSCLK?
|
||||
if w.latency().0 <= target_flash_latency.0 {
|
||||
if w.latency().to_bits() <= target_flash_latency.to_bits() {
|
||||
// We must increase the number of wait states now
|
||||
w.set_latency(target_flash_latency)
|
||||
} else {
|
||||
@ -395,12 +395,12 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
// > Flash memory.
|
||||
//
|
||||
// Enable flash prefetching if we have at least one wait state, and disable it otherwise.
|
||||
w.set_prften(target_flash_latency.0 > 0);
|
||||
w.set_prften(target_flash_latency.to_bits() > 0);
|
||||
});
|
||||
|
||||
if !set_flash_latency_after {
|
||||
// Spin until the effective flash latency is compatible with the clock change
|
||||
while FLASH.acr().read().latency().0 < target_flash_latency.0 {}
|
||||
while FLASH.acr().read().latency().to_bits() < target_flash_latency.to_bits() {}
|
||||
}
|
||||
|
||||
// Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once
|
||||
@ -442,7 +442,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
use stm32_metapac::rcc::vals::{Hpre, Ppre, Sw};
|
||||
use stm32_metapac::flash::vals::Latency;
|
||||
use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw};
|
||||
use stm32_metapac::FLASH;
|
||||
|
||||
use crate::pac::{PWR, RCC};
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
@ -15,6 +18,7 @@ pub const LSI_FREQ: Hertz = Hertz(32_000);
|
||||
pub enum ClockSrc {
|
||||
HSE(Hertz),
|
||||
HSI16,
|
||||
PLL,
|
||||
}
|
||||
|
||||
/// AHB prescaler
|
||||
@ -41,6 +45,222 @@ pub enum APBPrescaler {
|
||||
Div16,
|
||||
}
|
||||
|
||||
/// PLL clock input source
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum PllSrc {
|
||||
HSI16,
|
||||
HSE(Hertz),
|
||||
}
|
||||
|
||||
impl Into<Pllsrc> for PllSrc {
|
||||
fn into(self) -> Pllsrc {
|
||||
match self {
|
||||
PllSrc::HSE(..) => Pllsrc::HSE,
|
||||
PllSrc::HSI16 => Pllsrc::HSI16,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
seq_macro::seq!(P in 2..=31 {
|
||||
/// Output divider for the PLL P output.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PllP {
|
||||
// Note: If PLL P is set to 0 the PLLP bit controls the output division. There does not seem to
|
||||
// a good reason to do this so the API does not support it.
|
||||
// Div1 is invalid
|
||||
#(
|
||||
Div~P,
|
||||
)*
|
||||
}
|
||||
|
||||
impl From<PllP> for u8 {
|
||||
/// Returns the register value for the P output divider.
|
||||
fn from(val: PllP) -> u8 {
|
||||
match val {
|
||||
#(
|
||||
PllP::Div~P => P,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
impl PllP {
|
||||
/// Returns the numeric value of the P output divider.
|
||||
pub fn to_div(self) -> u32 {
|
||||
let val: u8 = self.into();
|
||||
val as u32
|
||||
}
|
||||
}
|
||||
|
||||
/// Output divider for the PLL Q output.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PllQ {
|
||||
Div2,
|
||||
Div4,
|
||||
Div6,
|
||||
Div8,
|
||||
}
|
||||
|
||||
impl PllQ {
|
||||
/// Returns the numeric value of the Q output divider.
|
||||
pub fn to_div(self) -> u32 {
|
||||
let val: u8 = self.into();
|
||||
(val as u32 + 1) * 2
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PllQ> for u8 {
|
||||
/// Returns the register value for the Q output divider.
|
||||
fn from(val: PllQ) -> u8 {
|
||||
match val {
|
||||
PllQ::Div2 => 0b00,
|
||||
PllQ::Div4 => 0b01,
|
||||
PllQ::Div6 => 0b10,
|
||||
PllQ::Div8 => 0b11,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Output divider for the PLL R output.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PllR {
|
||||
Div2,
|
||||
Div4,
|
||||
Div6,
|
||||
Div8,
|
||||
}
|
||||
|
||||
impl PllR {
|
||||
/// Returns the numeric value of the R output divider.
|
||||
pub fn to_div(self) -> u32 {
|
||||
let val: u8 = self.into();
|
||||
(val as u32 + 1) * 2
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PllR> for u8 {
|
||||
/// Returns the register value for the R output divider.
|
||||
fn from(val: PllR) -> u8 {
|
||||
match val {
|
||||
PllR::Div2 => 0b00,
|
||||
PllR::Div4 => 0b01,
|
||||
PllR::Div6 => 0b10,
|
||||
PllR::Div8 => 0b11,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
seq_macro::seq!(N in 8..=127 {
|
||||
/// Multiplication factor for the PLL VCO input clock.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PllN {
|
||||
#(
|
||||
Mul~N,
|
||||
)*
|
||||
}
|
||||
|
||||
impl From<PllN> for u8 {
|
||||
/// Returns the register value for the N multiplication factor.
|
||||
fn from(val: PllN) -> u8 {
|
||||
match val {
|
||||
#(
|
||||
PllN::Mul~N => N,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PllN {
|
||||
/// Returns the numeric value of the N multiplication factor.
|
||||
pub fn to_mul(self) -> u32 {
|
||||
match self {
|
||||
#(
|
||||
PllN::Mul~N => N,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/// PLL Pre-division. This must be set such that the PLL input is between 2.66 MHz and 16 MHz.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum PllM {
|
||||
Div1,
|
||||
Div2,
|
||||
Div3,
|
||||
Div4,
|
||||
Div5,
|
||||
Div6,
|
||||
Div7,
|
||||
Div8,
|
||||
Div9,
|
||||
Div10,
|
||||
Div11,
|
||||
Div12,
|
||||
Div13,
|
||||
Div14,
|
||||
Div15,
|
||||
Div16,
|
||||
}
|
||||
|
||||
impl PllM {
|
||||
/// Returns the numeric value of the M pre-division.
|
||||
pub fn to_div(self) -> u32 {
|
||||
let val: u8 = self.into();
|
||||
val as u32 + 1
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PllM> for u8 {
|
||||
/// Returns the register value for the M pre-division.
|
||||
fn from(val: PllM) -> u8 {
|
||||
match val {
|
||||
PllM::Div1 => 0b0000,
|
||||
PllM::Div2 => 0b0001,
|
||||
PllM::Div3 => 0b0010,
|
||||
PllM::Div4 => 0b0011,
|
||||
PllM::Div5 => 0b0100,
|
||||
PllM::Div6 => 0b0101,
|
||||
PllM::Div7 => 0b0110,
|
||||
PllM::Div8 => 0b0111,
|
||||
PllM::Div9 => 0b1000,
|
||||
PllM::Div10 => 0b1001,
|
||||
PllM::Div11 => 0b1010,
|
||||
PllM::Div12 => 0b1011,
|
||||
PllM::Div13 => 0b1100,
|
||||
PllM::Div14 => 0b1101,
|
||||
PllM::Div15 => 0b1110,
|
||||
PllM::Div16 => 0b1111,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PLL Configuration
|
||||
///
|
||||
/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
|
||||
/// dividers. Be sure to keep check the datasheet for your specific part for the appropriate
|
||||
/// frequency ranges for each of these settings.
|
||||
pub struct Pll {
|
||||
/// PLL Source clock selection.
|
||||
pub source: PllSrc,
|
||||
|
||||
/// PLL pre-divider
|
||||
pub prediv_m: PllM,
|
||||
|
||||
/// PLL multiplication factor for VCO
|
||||
pub mul_n: PllN,
|
||||
|
||||
/// PLL division factor for P clock (ADC Clock)
|
||||
pub div_p: Option<PllP>,
|
||||
|
||||
/// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI)
|
||||
pub div_q: Option<PllQ>,
|
||||
|
||||
/// PLL division factor for R clock (SYSCLK)
|
||||
pub div_r: Option<PllR>,
|
||||
}
|
||||
|
||||
impl AHBPrescaler {
|
||||
const fn div(self) -> u32 {
|
||||
match self {
|
||||
@ -97,6 +317,27 @@ impl Into<Hpre> for AHBPrescaler {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the source for the 48MHz clock to the USB and RNG peripherals.
|
||||
pub enum Clock48MhzSrc {
|
||||
/// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the
|
||||
/// oscillator to comply with the USB specification for oscillator tolerance.
|
||||
Hsi48(Option<CrsConfig>),
|
||||
/// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. For USB usage the
|
||||
/// PLL needs to be using the HSE source to comply with the USB specification for oscillator
|
||||
/// tolerance.
|
||||
PllQ,
|
||||
}
|
||||
|
||||
/// Sets the sync source for the Clock Recovery System (CRS).
|
||||
pub enum CrsSyncSource {
|
||||
/// Use an external GPIO to sync the CRS.
|
||||
Gpio,
|
||||
/// Use the Low Speed External oscillator to sync the CRS.
|
||||
Lse,
|
||||
/// Use the USB SOF to sync the CRS.
|
||||
Usb,
|
||||
}
|
||||
|
||||
/// Clocks configutation
|
||||
pub struct Config {
|
||||
pub mux: ClockSrc,
|
||||
@ -104,6 +345,17 @@ pub struct Config {
|
||||
pub apb1_pre: APBPrescaler,
|
||||
pub apb2_pre: APBPrescaler,
|
||||
pub low_power_run: bool,
|
||||
/// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration
|
||||
/// MUST turn on the PLLR output.
|
||||
pub pll: Option<Pll>,
|
||||
/// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
|
||||
pub clock_48mhz_src: Option<Clock48MhzSrc>,
|
||||
}
|
||||
|
||||
/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator.
|
||||
pub struct CrsConfig {
|
||||
/// Sync source for the CRS.
|
||||
pub sync_src: CrsSyncSource,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@ -115,11 +367,81 @@ impl Default for Config {
|
||||
apb1_pre: APBPrescaler::NotDivided,
|
||||
apb2_pre: APBPrescaler::NotDivided,
|
||||
low_power_run: false,
|
||||
pll: None,
|
||||
clock_48mhz_src: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PllFreq {
|
||||
pub pll_p: Option<Hertz>,
|
||||
pub pll_q: Option<Hertz>,
|
||||
pub pll_r: Option<Hertz>,
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn init(config: Config) {
|
||||
let pll_freq = config.pll.map(|pll_config| {
|
||||
let src_freq = match pll_config.source {
|
||||
PllSrc::HSI16 => {
|
||||
RCC.cr().write(|w| w.set_hsion(true));
|
||||
while !RCC.cr().read().hsirdy() {}
|
||||
|
||||
HSI_FREQ.0
|
||||
}
|
||||
PllSrc::HSE(freq) => {
|
||||
RCC.cr().write(|w| w.set_hseon(true));
|
||||
while !RCC.cr().read().hserdy() {}
|
||||
freq.0
|
||||
}
|
||||
};
|
||||
|
||||
// Disable PLL before configuration
|
||||
RCC.cr().modify(|w| w.set_pllon(false));
|
||||
while RCC.cr().read().pllrdy() {}
|
||||
|
||||
let internal_freq = src_freq / pll_config.prediv_m.to_div() * pll_config.mul_n.to_mul();
|
||||
|
||||
RCC.pllcfgr().write(|w| {
|
||||
w.set_plln(pll_config.mul_n.into());
|
||||
w.set_pllm(pll_config.prediv_m.into());
|
||||
w.set_pllsrc(pll_config.source.into());
|
||||
});
|
||||
|
||||
let pll_p_freq = pll_config.div_p.map(|div_p| {
|
||||
RCC.pllcfgr().modify(|w| {
|
||||
w.set_pllpdiv(div_p.into());
|
||||
w.set_pllpen(true);
|
||||
});
|
||||
Hertz(internal_freq / div_p.to_div())
|
||||
});
|
||||
|
||||
let pll_q_freq = pll_config.div_q.map(|div_q| {
|
||||
RCC.pllcfgr().modify(|w| {
|
||||
w.set_pllq(div_q.into());
|
||||
w.set_pllqen(true);
|
||||
});
|
||||
Hertz(internal_freq / div_q.to_div())
|
||||
});
|
||||
|
||||
let pll_r_freq = pll_config.div_r.map(|div_r| {
|
||||
RCC.pllcfgr().modify(|w| {
|
||||
w.set_pllr(div_r.into());
|
||||
w.set_pllren(true);
|
||||
});
|
||||
Hertz(internal_freq / div_r.to_div())
|
||||
});
|
||||
|
||||
// Enable the PLL
|
||||
RCC.cr().modify(|w| w.set_pllon(true));
|
||||
while !RCC.cr().read().pllrdy() {}
|
||||
|
||||
PllFreq {
|
||||
pll_p: pll_p_freq,
|
||||
pll_q: pll_q_freq,
|
||||
pll_r: pll_r_freq,
|
||||
}
|
||||
});
|
||||
|
||||
let (sys_clk, sw) = match config.mux {
|
||||
ClockSrc::HSI16 => {
|
||||
// Enable HSI16
|
||||
@ -135,6 +457,47 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
(freq.0, Sw::HSE)
|
||||
}
|
||||
ClockSrc::PLL => {
|
||||
assert!(pll_freq.is_some());
|
||||
assert!(pll_freq.as_ref().unwrap().pll_r.is_some());
|
||||
|
||||
let freq = pll_freq.as_ref().unwrap().pll_r.unwrap().0;
|
||||
|
||||
assert!(freq <= 170_000_000);
|
||||
|
||||
if freq >= 150_000_000 {
|
||||
// Enable Core Boost mode on freq >= 150Mhz ([RM0440] p234)
|
||||
PWR.cr5().modify(|w| w.set_r1mode(false));
|
||||
// Set flash wait state in boost mode based on frequency ([RM0440] p191)
|
||||
if freq <= 36_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
|
||||
} else if freq <= 68_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS1));
|
||||
} else if freq <= 102_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS2));
|
||||
} else if freq <= 136_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS3));
|
||||
} else {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
|
||||
}
|
||||
} else {
|
||||
PWR.cr5().modify(|w| w.set_r1mode(true));
|
||||
// Set flash wait state in normal mode based on frequency ([RM0440] p191)
|
||||
if freq <= 30_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
|
||||
} else if freq <= 60_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS1));
|
||||
} else if freq <= 80_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS2));
|
||||
} else if freq <= 120_000_000 {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS3));
|
||||
} else {
|
||||
FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
|
||||
}
|
||||
}
|
||||
|
||||
(freq, Sw::PLLRCLK)
|
||||
}
|
||||
};
|
||||
|
||||
RCC.cfgr().modify(|w| {
|
||||
@ -165,6 +528,50 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
};
|
||||
|
||||
// Setup the 48 MHz clock if needed
|
||||
if let Some(clock_48mhz_src) = config.clock_48mhz_src {
|
||||
let source = match clock_48mhz_src {
|
||||
Clock48MhzSrc::PllQ => {
|
||||
// Make sure the PLLQ is enabled and running at 48Mhz
|
||||
let pllq_freq = pll_freq.as_ref().and_then(|f| f.pll_q);
|
||||
assert!(pllq_freq.is_some() && pllq_freq.unwrap().0 == 48_000_000);
|
||||
|
||||
crate::pac::rcc::vals::Clk48sel::PLLQCLK
|
||||
}
|
||||
Clock48MhzSrc::Hsi48(crs_config) => {
|
||||
// Enable HSI48
|
||||
RCC.crrcr().modify(|w| w.set_hsi48on(true));
|
||||
// Wait for HSI48 to turn on
|
||||
while RCC.crrcr().read().hsi48rdy() == false {}
|
||||
|
||||
// Enable and setup CRS if needed
|
||||
if let Some(crs_config) = crs_config {
|
||||
crate::peripherals::CRS::enable();
|
||||
|
||||
let sync_src = match crs_config.sync_src {
|
||||
CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO,
|
||||
CrsSyncSource::Lse => crate::pac::crs::vals::Syncsrc::LSE,
|
||||
CrsSyncSource::Usb => crate::pac::crs::vals::Syncsrc::USB,
|
||||
};
|
||||
|
||||
crate::pac::CRS.cfgr().modify(|w| {
|
||||
w.set_syncsrc(sync_src);
|
||||
});
|
||||
|
||||
// These are the correct settings for standard USB operation. If other settings
|
||||
// are needed there will need to be additional config options for the CRS.
|
||||
crate::pac::CRS.cr().modify(|w| {
|
||||
w.set_autotrimen(true);
|
||||
w.set_cen(true);
|
||||
});
|
||||
}
|
||||
crate::pac::rcc::vals::Clk48sel::HSI48
|
||||
}
|
||||
};
|
||||
|
||||
RCC.ccipr().modify(|w| w.set_clk48sel(source));
|
||||
}
|
||||
|
||||
if config.low_power_run {
|
||||
assert!(sys_clk <= 2_000_000);
|
||||
PWR.cr1().modify(|w| w.set_lpr(true));
|
||||
|
@ -462,7 +462,7 @@ struct PllOutput {
|
||||
r: Option<Hertz>,
|
||||
}
|
||||
|
||||
unsafe fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
|
||||
fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
|
||||
let Some(config) = config else {
|
||||
// Stop PLL
|
||||
RCC.cr().modify(|w| w.set_pllon(num, false));
|
||||
@ -595,12 +595,9 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) {
|
||||
|
||||
defmt::debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq);
|
||||
|
||||
// NOTE(unsafe) Atomic write
|
||||
unsafe {
|
||||
FLASH.acr().write(|w| {
|
||||
w.set_wrhighfreq(wrhighfreq);
|
||||
w.set_latency(latency);
|
||||
});
|
||||
while FLASH.acr().read().latency() != latency {}
|
||||
}
|
||||
FLASH.acr().write(|w| {
|
||||
w.set_wrhighfreq(wrhighfreq);
|
||||
w.set_latency(latency);
|
||||
});
|
||||
while FLASH.acr().read().latency() != latency {}
|
||||
}
|
||||
|
@ -253,14 +253,11 @@ fn flash_setup(rcc_aclk: u32, vos: VoltageScale) {
|
||||
},
|
||||
};
|
||||
|
||||
// NOTE(unsafe) Atomic write
|
||||
unsafe {
|
||||
FLASH.acr().write(|w| {
|
||||
w.set_wrhighfreq(progr_delay);
|
||||
w.set_latency(wait_states)
|
||||
});
|
||||
while FLASH.acr().read().latency() != wait_states {}
|
||||
}
|
||||
FLASH.acr().write(|w| {
|
||||
w.set_wrhighfreq(progr_delay);
|
||||
w.set_latency(wait_states)
|
||||
});
|
||||
while FLASH.acr().read().latency() != wait_states {}
|
||||
}
|
||||
|
||||
pub enum McoClock {
|
||||
@ -474,7 +471,6 @@ pub(crate) unsafe fn init(mut config: Config) {
|
||||
// Configure traceclk from PLL if needed
|
||||
traceclk_setup(&mut config, sys_use_pll1_p);
|
||||
|
||||
// NOTE(unsafe) We have exclusive access to the RCC
|
||||
let (pll1_p_ck, pll1_q_ck, pll1_r_ck) = pll::pll_setup(srcclk.0, &config.pll1, 0);
|
||||
let (pll2_p_ck, pll2_q_ck, pll2_r_ck) = pll::pll_setup(srcclk.0, &config.pll2, 1);
|
||||
let (pll3_p_ck, pll3_q_ck, pll3_r_ck) = pll::pll_setup(srcclk.0, &config.pll3, 2);
|
||||
@ -605,22 +601,22 @@ pub(crate) unsafe fn init(mut config: Config) {
|
||||
|
||||
// Core Prescaler / AHB Prescaler / APB3 Prescaler
|
||||
RCC.d1cfgr().modify(|w| {
|
||||
w.set_d1cpre(Hpre(d1cpre_bits));
|
||||
w.set_d1ppre(Dppre(ppre3_bits));
|
||||
w.set_d1cpre(Hpre::from_bits(d1cpre_bits));
|
||||
w.set_d1ppre(Dppre::from_bits(ppre3_bits));
|
||||
w.set_hpre(hpre_bits)
|
||||
});
|
||||
// Ensure core prescaler value is valid before future lower
|
||||
// core voltage
|
||||
while RCC.d1cfgr().read().d1cpre().0 != d1cpre_bits {}
|
||||
while RCC.d1cfgr().read().d1cpre().to_bits() != d1cpre_bits {}
|
||||
|
||||
// APB1 / APB2 Prescaler
|
||||
RCC.d2cfgr().modify(|w| {
|
||||
w.set_d2ppre1(Dppre(ppre1_bits));
|
||||
w.set_d2ppre2(Dppre(ppre2_bits));
|
||||
w.set_d2ppre1(Dppre::from_bits(ppre1_bits));
|
||||
w.set_d2ppre2(Dppre::from_bits(ppre2_bits));
|
||||
});
|
||||
|
||||
// APB4 Prescaler
|
||||
RCC.d3cfgr().modify(|w| w.set_d3ppre(Dppre(ppre4_bits)));
|
||||
RCC.d3cfgr().modify(|w| w.set_d3ppre(Dppre::from_bits(ppre4_bits)));
|
||||
|
||||
// Peripheral Clock (per_ck)
|
||||
RCC.d1ccipr().modify(|w| w.set_ckpersel(ckpersel));
|
||||
@ -644,7 +640,7 @@ pub(crate) unsafe fn init(mut config: Config) {
|
||||
_ => Sw::HSI,
|
||||
};
|
||||
RCC.cfgr().modify(|w| w.set_sw(sw));
|
||||
while RCC.cfgr().read().sws() != sw.0 {}
|
||||
while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {}
|
||||
|
||||
// IO compensation cell - Requires CSI clock and SYSCFG
|
||||
assert!(RCC.cr().read().csirdy());
|
||||
@ -756,7 +752,7 @@ mod pll {
|
||||
/// # Safety
|
||||
///
|
||||
/// Must have exclusive access to the RCC register block
|
||||
unsafe fn vco_setup(pll_src: u32, requested_output: u32, plln: usize) -> PllConfigResults {
|
||||
fn vco_setup(pll_src: u32, requested_output: u32, plln: usize) -> PllConfigResults {
|
||||
use crate::pac::rcc::vals::{Pllrge, Pllvcosel};
|
||||
|
||||
let (vco_ck_target, pll_x_p) = vco_output_divider_setup(requested_output, plln);
|
||||
@ -785,11 +781,7 @@ mod pll {
|
||||
/// # Safety
|
||||
///
|
||||
/// Must have exclusive access to the RCC register block
|
||||
pub(super) unsafe fn pll_setup(
|
||||
pll_src: u32,
|
||||
config: &PllConfig,
|
||||
plln: usize,
|
||||
) -> (Option<u32>, Option<u32>, Option<u32>) {
|
||||
pub(super) fn pll_setup(pll_src: u32, config: &PllConfig, plln: usize) -> (Option<u32>, Option<u32>, Option<u32>) {
|
||||
use crate::pac::rcc::vals::Divp;
|
||||
|
||||
match config.p_ck {
|
||||
@ -814,7 +806,8 @@ mod pll {
|
||||
RCC.pllcfgr().modify(|w| w.set_pllfracen(plln, false));
|
||||
let vco_ck = ref_x_ck * pll_x_n;
|
||||
|
||||
RCC.plldivr(plln).modify(|w| w.set_divp1(Divp((pll_x_p - 1) as u8)));
|
||||
RCC.plldivr(plln)
|
||||
.modify(|w| w.set_divp1(Divp::from_bits((pll_x_p - 1) as u8)));
|
||||
RCC.pllcfgr().modify(|w| w.set_divpen(plln, true));
|
||||
|
||||
// Calulate additional output dividers
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw};
|
||||
use crate::pac::RCC;
|
||||
#[cfg(crs)]
|
||||
use crate::pac::{CRS, SYSCFG};
|
||||
use crate::pac::{crs, CRS, SYSCFG};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
@ -293,7 +293,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
AHBPrescaler::NotDivided => sys_clk,
|
||||
pre => {
|
||||
let pre: Hpre = pre.into();
|
||||
let pre = 1 << (pre.0 as u32 - 7);
|
||||
let pre = 1 << (pre.to_bits() as u32 - 7);
|
||||
sys_clk / pre
|
||||
}
|
||||
};
|
||||
@ -302,7 +302,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
@ -312,7 +312,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
@ -338,7 +338,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
CRS.cfgr().write(|w|
|
||||
|
||||
// Select LSE as synchronization source
|
||||
w.set_syncsrc(0b01));
|
||||
w.set_syncsrc(crs::vals::Syncsrc::LSE));
|
||||
CRS.cr().modify(|w| {
|
||||
w.set_autotrimen(true);
|
||||
w.set_cen(true);
|
||||
|
@ -294,7 +294,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
AHBPrescaler::NotDivided => sys_clk,
|
||||
pre => {
|
||||
let pre: Hpre = pre.into();
|
||||
let pre = 1 << (pre.0 as u32 - 7);
|
||||
let pre = 1 << (pre.to_bits() as u32 - 7);
|
||||
sys_clk / pre
|
||||
}
|
||||
};
|
||||
@ -303,7 +303,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
@ -313,7 +313,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
|
@ -656,7 +656,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
AHBPrescaler::NotDivided => sys_clk,
|
||||
pre => {
|
||||
let pre: Hpre = pre.into();
|
||||
let pre = 1 << (pre.0 as u32 - 7);
|
||||
let pre = 1 << (pre.to_bits() as u32 - 7);
|
||||
sys_clk / pre
|
||||
}
|
||||
};
|
||||
@ -665,7 +665,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
@ -675,7 +675,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
AHBPrescaler::NotDivided => sys_clk,
|
||||
pre => {
|
||||
let pre: Hpre = pre.into();
|
||||
let pre = 1 << (pre.0 as u32 - 7);
|
||||
let pre = 1 << (pre.to_bits() as u32 - 7);
|
||||
sys_clk / pre
|
||||
}
|
||||
};
|
||||
@ -470,7 +470,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
@ -480,7 +480,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
||||
pre => {
|
||||
let pre: Ppre = pre.into();
|
||||
let pre: u8 = 1 << (pre.0 - 3);
|
||||
let pre: u8 = 1 << (pre.to_bits() - 3);
|
||||
let freq = ahb_freq / pre as u32;
|
||||
(freq, freq * 2)
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ pub enum PllM {
|
||||
|
||||
impl Into<Pllm> for PllM {
|
||||
fn into(self) -> Pllm {
|
||||
Pllm(self as u8)
|
||||
Pllm::from_bits(self as u8)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user