commit
e1880a19df
11 changed files with 428 additions and 113 deletions
|
@ -45,6 +45,79 @@ net = ["embassy-net", "vcell"]
|
|||
|
||||
# BEGIN GENERATED FEATURES
|
||||
# Generated by gen_features.py. DO NOT EDIT.
|
||||
stm32f030c6 = [ "stm32-metapac/stm32f030c6",]
|
||||
stm32f030c8 = [ "stm32-metapac/stm32f030c8",]
|
||||
stm32f030cc = [ "stm32-metapac/stm32f030cc",]
|
||||
stm32f030f4 = [ "stm32-metapac/stm32f030f4",]
|
||||
stm32f030k6 = [ "stm32-metapac/stm32f030k6",]
|
||||
stm32f030r8 = [ "stm32-metapac/stm32f030r8",]
|
||||
stm32f030rc = [ "stm32-metapac/stm32f030rc",]
|
||||
stm32f031c4 = [ "stm32-metapac/stm32f031c4",]
|
||||
stm32f031c6 = [ "stm32-metapac/stm32f031c6",]
|
||||
stm32f031e6 = [ "stm32-metapac/stm32f031e6",]
|
||||
stm32f031f4 = [ "stm32-metapac/stm32f031f4",]
|
||||
stm32f031f6 = [ "stm32-metapac/stm32f031f6",]
|
||||
stm32f031g4 = [ "stm32-metapac/stm32f031g4",]
|
||||
stm32f031g6 = [ "stm32-metapac/stm32f031g6",]
|
||||
stm32f031k4 = [ "stm32-metapac/stm32f031k4",]
|
||||
stm32f031k6 = [ "stm32-metapac/stm32f031k6",]
|
||||
stm32f038c6 = [ "stm32-metapac/stm32f038c6",]
|
||||
stm32f038e6 = [ "stm32-metapac/stm32f038e6",]
|
||||
stm32f038f6 = [ "stm32-metapac/stm32f038f6",]
|
||||
stm32f038g6 = [ "stm32-metapac/stm32f038g6",]
|
||||
stm32f038k6 = [ "stm32-metapac/stm32f038k6",]
|
||||
stm32f042c4 = [ "stm32-metapac/stm32f042c4",]
|
||||
stm32f042c6 = [ "stm32-metapac/stm32f042c6",]
|
||||
stm32f042f4 = [ "stm32-metapac/stm32f042f4",]
|
||||
stm32f042f6 = [ "stm32-metapac/stm32f042f6",]
|
||||
stm32f042g4 = [ "stm32-metapac/stm32f042g4",]
|
||||
stm32f042g6 = [ "stm32-metapac/stm32f042g6",]
|
||||
stm32f042k4 = [ "stm32-metapac/stm32f042k4",]
|
||||
stm32f042k6 = [ "stm32-metapac/stm32f042k6",]
|
||||
stm32f042t6 = [ "stm32-metapac/stm32f042t6",]
|
||||
stm32f048c6 = [ "stm32-metapac/stm32f048c6",]
|
||||
stm32f048g6 = [ "stm32-metapac/stm32f048g6",]
|
||||
stm32f048t6 = [ "stm32-metapac/stm32f048t6",]
|
||||
stm32f051c4 = [ "stm32-metapac/stm32f051c4",]
|
||||
stm32f051c6 = [ "stm32-metapac/stm32f051c6",]
|
||||
stm32f051c8 = [ "stm32-metapac/stm32f051c8",]
|
||||
stm32f051k4 = [ "stm32-metapac/stm32f051k4",]
|
||||
stm32f051k6 = [ "stm32-metapac/stm32f051k6",]
|
||||
stm32f051k8 = [ "stm32-metapac/stm32f051k8",]
|
||||
stm32f051r4 = [ "stm32-metapac/stm32f051r4",]
|
||||
stm32f051r6 = [ "stm32-metapac/stm32f051r6",]
|
||||
stm32f051r8 = [ "stm32-metapac/stm32f051r8",]
|
||||
stm32f051t8 = [ "stm32-metapac/stm32f051t8",]
|
||||
stm32f058c8 = [ "stm32-metapac/stm32f058c8",]
|
||||
stm32f058r8 = [ "stm32-metapac/stm32f058r8",]
|
||||
stm32f058t8 = [ "stm32-metapac/stm32f058t8",]
|
||||
stm32f070c6 = [ "stm32-metapac/stm32f070c6",]
|
||||
stm32f070cb = [ "stm32-metapac/stm32f070cb",]
|
||||
stm32f070f6 = [ "stm32-metapac/stm32f070f6",]
|
||||
stm32f070rb = [ "stm32-metapac/stm32f070rb",]
|
||||
stm32f071c8 = [ "stm32-metapac/stm32f071c8",]
|
||||
stm32f071cb = [ "stm32-metapac/stm32f071cb",]
|
||||
stm32f071rb = [ "stm32-metapac/stm32f071rb",]
|
||||
stm32f071v8 = [ "stm32-metapac/stm32f071v8",]
|
||||
stm32f071vb = [ "stm32-metapac/stm32f071vb",]
|
||||
stm32f072c8 = [ "stm32-metapac/stm32f072c8",]
|
||||
stm32f072cb = [ "stm32-metapac/stm32f072cb",]
|
||||
stm32f072r8 = [ "stm32-metapac/stm32f072r8",]
|
||||
stm32f072rb = [ "stm32-metapac/stm32f072rb",]
|
||||
stm32f072v8 = [ "stm32-metapac/stm32f072v8",]
|
||||
stm32f072vb = [ "stm32-metapac/stm32f072vb",]
|
||||
stm32f078cb = [ "stm32-metapac/stm32f078cb",]
|
||||
stm32f078rb = [ "stm32-metapac/stm32f078rb",]
|
||||
stm32f078vb = [ "stm32-metapac/stm32f078vb",]
|
||||
stm32f091cb = [ "stm32-metapac/stm32f091cb",]
|
||||
stm32f091cc = [ "stm32-metapac/stm32f091cc",]
|
||||
stm32f091rb = [ "stm32-metapac/stm32f091rb",]
|
||||
stm32f091rc = [ "stm32-metapac/stm32f091rc",]
|
||||
stm32f091vb = [ "stm32-metapac/stm32f091vb",]
|
||||
stm32f091vc = [ "stm32-metapac/stm32f091vc",]
|
||||
stm32f098cc = [ "stm32-metapac/stm32f098cc",]
|
||||
stm32f098rc = [ "stm32-metapac/stm32f098rc",]
|
||||
stm32f098vc = [ "stm32-metapac/stm32f098vc",]
|
||||
stm32f401cb = [ "stm32-metapac/stm32f401cb",]
|
||||
stm32f401cc = [ "stm32-metapac/stm32f401cc",]
|
||||
stm32f401cd = [ "stm32-metapac/stm32f401cd",]
|
||||
|
|
|
@ -33,10 +33,6 @@ if len(c) > 1:
|
|||
with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f:
|
||||
chip = yaml.load(f, Loader=SafeLoader)
|
||||
|
||||
# ======= load GPIO AF
|
||||
with open(f'{data_path}/gpio_af/{chip["gpio_af"]}.yaml', 'r') as f:
|
||||
af = yaml.load(f, Loader=SafeLoader)
|
||||
|
||||
# ======= Generate!
|
||||
with open(output_file, 'w') as f:
|
||||
singletons = [] # USART1, PA5, EXTI8
|
||||
|
|
|
@ -13,6 +13,7 @@ dname = os.path.dirname(abspath)
|
|||
os.chdir(dname)
|
||||
|
||||
supported_families = [
|
||||
"STM32F0",
|
||||
'STM32F4',
|
||||
'STM32L0',
|
||||
'STM32L4',
|
||||
|
|
111
embassy-stm32/src/exti/mod.rs
Normal file
111
embassy-stm32/src/exti/mod.rs
Normal file
|
@ -0,0 +1,111 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! foreach_exti_irq {
|
||||
($action:ident) => {
|
||||
crate::pac::interrupts!(
|
||||
(EXTI0) => { $action!(EXTI0); };
|
||||
(EXTI1) => { $action!(EXTI1); };
|
||||
(EXTI2) => { $action!(EXTI2); };
|
||||
(EXTI3) => { $action!(EXTI3); };
|
||||
(EXTI4) => { $action!(EXTI4); };
|
||||
(EXTI5) => { $action!(EXTI5); };
|
||||
(EXTI6) => { $action!(EXTI6); };
|
||||
(EXTI7) => { $action!(EXTI7); };
|
||||
(EXTI8) => { $action!(EXTI8); };
|
||||
(EXTI9) => { $action!(EXTI9); };
|
||||
(EXTI10) => { $action!(EXTI10); };
|
||||
(EXTI11) => { $action!(EXTI11); };
|
||||
(EXTI12) => { $action!(EXTI12); };
|
||||
(EXTI13) => { $action!(EXTI13); };
|
||||
(EXTI14) => { $action!(EXTI14); };
|
||||
(EXTI15) => { $action!(EXTI15); };
|
||||
|
||||
// plus the weird ones
|
||||
(EXTI0_1) => { $action!( EXTI0_1 ); };
|
||||
(EXTI15_10) => { $action!(EXTI15_10); };
|
||||
(EXTI15_4) => { $action!(EXTI15_4); };
|
||||
(EXTI1_0) => { $action!(EXTI1_0); };
|
||||
(EXTI2_3) => { $action!(EXTI2_3); };
|
||||
(EXTI2_TSC) => { $action!(EXTI2_TSC); };
|
||||
(EXTI3_2) => { $action!(EXTI3_2); };
|
||||
(EXTI4_15) => { $action!(EXTI4_15); };
|
||||
(EXTI9_5) => { $action!(EXTI9_5); };
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg_attr(exti_v1, path = "v1.rs")]
|
||||
#[cfg_attr(exti_wb55, path = "v2.rs")]
|
||||
mod _version;
|
||||
|
||||
#[allow(unused)]
|
||||
pub use _version::*;
|
||||
|
||||
use crate::peripherals;
|
||||
use embassy_extras::unsafe_impl_unborrow;
|
||||
|
||||
pub(crate) mod sealed {
|
||||
pub trait Channel {}
|
||||
}
|
||||
|
||||
pub trait Channel: sealed::Channel + Sized {
|
||||
fn number(&self) -> usize;
|
||||
fn degrade(self) -> AnyChannel {
|
||||
AnyChannel {
|
||||
number: self.number() as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyChannel {
|
||||
number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyChannel);
|
||||
impl sealed::Channel for AnyChannel {}
|
||||
impl Channel for AnyChannel {
|
||||
fn number(&self) -> usize {
|
||||
self.number as usize
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_exti {
|
||||
($type:ident, $number:expr) => {
|
||||
impl sealed::Channel for peripherals::$type {}
|
||||
impl Channel for peripherals::$type {
|
||||
fn number(&self) -> usize {
|
||||
$number as usize
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_exti!(EXTI0, 0);
|
||||
impl_exti!(EXTI1, 1);
|
||||
impl_exti!(EXTI2, 2);
|
||||
impl_exti!(EXTI3, 3);
|
||||
impl_exti!(EXTI4, 4);
|
||||
impl_exti!(EXTI5, 5);
|
||||
impl_exti!(EXTI6, 6);
|
||||
impl_exti!(EXTI7, 7);
|
||||
impl_exti!(EXTI8, 8);
|
||||
impl_exti!(EXTI9, 9);
|
||||
impl_exti!(EXTI10, 10);
|
||||
impl_exti!(EXTI11, 11);
|
||||
impl_exti!(EXTI12, 12);
|
||||
impl_exti!(EXTI13, 13);
|
||||
impl_exti!(EXTI14, 14);
|
||||
impl_exti!(EXTI15, 15);
|
||||
|
||||
macro_rules! enable_irq {
|
||||
($e:ident) => {
|
||||
crate::interrupt::$e::steal().enable();
|
||||
};
|
||||
}
|
||||
|
||||
/// safety: must be called only once
|
||||
pub(crate) unsafe fn init() {
|
||||
use embassy::interrupt::Interrupt;
|
||||
use embassy::interrupt::InterruptExt;
|
||||
|
||||
foreach_exti_irq!(enable_irq);
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
#![macro_use]
|
||||
use core::convert::Infallible;
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
|
@ -6,14 +5,12 @@ use core::pin::Pin;
|
|||
use core::task::{Context, Poll};
|
||||
use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
|
||||
use embassy::util::{AtomicWaker, Unborrow};
|
||||
use embassy_extras::unsafe_impl_unborrow;
|
||||
use embedded_hal::digital::v2::InputPin;
|
||||
use pac::exti::{regs, vals};
|
||||
|
||||
use crate::gpio::{AnyPin, Input, Pin as GpioPin};
|
||||
use crate::pac;
|
||||
use crate::pac::{EXTI, SYSCFG};
|
||||
use crate::peripherals;
|
||||
|
||||
const EXTI_COUNT: usize = 16;
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
|
@ -160,106 +157,6 @@ impl<'a> Future for ExtiInputFuture<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
pub trait Channel {}
|
||||
}
|
||||
|
||||
pub trait Channel: sealed::Channel + Sized {
|
||||
fn number(&self) -> usize;
|
||||
fn degrade(self) -> AnyChannel {
|
||||
AnyChannel {
|
||||
number: self.number() as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyChannel {
|
||||
number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyChannel);
|
||||
impl sealed::Channel for AnyChannel {}
|
||||
impl Channel for AnyChannel {
|
||||
fn number(&self) -> usize {
|
||||
self.number as usize
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_exti {
|
||||
($type:ident, $number:expr) => {
|
||||
impl sealed::Channel for peripherals::$type {}
|
||||
impl Channel for peripherals::$type {
|
||||
fn number(&self) -> usize {
|
||||
$number as usize
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_exti!(EXTI0, 0);
|
||||
impl_exti!(EXTI1, 1);
|
||||
impl_exti!(EXTI2, 2);
|
||||
impl_exti!(EXTI3, 3);
|
||||
impl_exti!(EXTI4, 4);
|
||||
impl_exti!(EXTI5, 5);
|
||||
impl_exti!(EXTI6, 6);
|
||||
impl_exti!(EXTI7, 7);
|
||||
impl_exti!(EXTI8, 8);
|
||||
impl_exti!(EXTI9, 9);
|
||||
impl_exti!(EXTI10, 10);
|
||||
impl_exti!(EXTI11, 11);
|
||||
impl_exti!(EXTI12, 12);
|
||||
impl_exti!(EXTI13, 13);
|
||||
impl_exti!(EXTI14, 14);
|
||||
impl_exti!(EXTI15, 15);
|
||||
|
||||
macro_rules! foreach_exti_irq {
|
||||
($action:ident) => {
|
||||
crate::pac::interrupts!(
|
||||
(EXTI0) => { $action!(EXTI0); };
|
||||
(EXTI1) => { $action!(EXTI1); };
|
||||
(EXTI2) => { $action!(EXTI2); };
|
||||
(EXTI3) => { $action!(EXTI3); };
|
||||
(EXTI4) => { $action!(EXTI4); };
|
||||
(EXTI5) => { $action!(EXTI5); };
|
||||
(EXTI6) => { $action!(EXTI6); };
|
||||
(EXTI7) => { $action!(EXTI7); };
|
||||
(EXTI8) => { $action!(EXTI8); };
|
||||
(EXTI9) => { $action!(EXTI9); };
|
||||
(EXTI10) => { $action!(EXTI10); };
|
||||
(EXTI11) => { $action!(EXTI11); };
|
||||
(EXTI12) => { $action!(EXTI12); };
|
||||
(EXTI13) => { $action!(EXTI13); };
|
||||
(EXTI14) => { $action!(EXTI14); };
|
||||
(EXTI15) => { $action!(EXTI15); };
|
||||
|
||||
// plus the weird ones
|
||||
(EXTI0_1) => { $action!( EXTI0_1 ); };
|
||||
(EXTI15_10) => { $action!(EXTI15_10); };
|
||||
(EXTI15_4) => { $action!(EXTI15_4); };
|
||||
(EXTI1_0) => { $action!(EXTI1_0); };
|
||||
(EXTI2_3) => { $action!(EXTI2_3); };
|
||||
(EXTI2_TSC) => { $action!(EXTI2_TSC); };
|
||||
(EXTI3_2) => { $action!(EXTI3_2); };
|
||||
(EXTI4_15) => { $action!(EXTI4_15); };
|
||||
(EXTI9_5) => { $action!(EXTI9_5); };
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! enable_irq {
|
||||
($e:ident) => {
|
||||
crate::interrupt::$e::steal().enable();
|
||||
};
|
||||
}
|
||||
|
||||
/// safety: must be called only once
|
||||
pub(crate) unsafe fn init() {
|
||||
use embassy::interrupt::Interrupt;
|
||||
use embassy::interrupt::InterruptExt;
|
||||
|
||||
foreach_exti_irq!(enable_irq);
|
||||
}
|
||||
|
||||
use crate::interrupt;
|
||||
|
||||
macro_rules! impl_irq {
|
1
embassy-stm32/src/exti/v2.rs
Normal file
1
embassy-stm32/src/exti/v2.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -16,7 +16,6 @@ pub mod interrupt;
|
|||
pub mod time;
|
||||
|
||||
// Always-present hardware
|
||||
pub mod exti;
|
||||
pub mod gpio;
|
||||
pub mod rcc;
|
||||
|
||||
|
@ -31,6 +30,8 @@ pub mod dac;
|
|||
pub mod dma;
|
||||
#[cfg(all(eth, feature = "net"))]
|
||||
pub mod eth;
|
||||
#[cfg(exti)]
|
||||
pub mod exti;
|
||||
#[cfg(i2c)]
|
||||
pub mod i2c;
|
||||
#[cfg(pwr)]
|
||||
|
@ -83,10 +84,9 @@ pub fn init(config: Config) -> Peripherals {
|
|||
let p = Peripherals::take();
|
||||
|
||||
unsafe {
|
||||
exti::init();
|
||||
|
||||
#[cfg(dma)]
|
||||
dma::init();
|
||||
#[cfg(exti)]
|
||||
exti::init();
|
||||
rcc::init(config.rcc);
|
||||
}
|
||||
|
|
231
embassy-stm32/src/rcc/f0/mod.rs
Normal file
231
embassy-stm32/src/rcc/f0/mod.rs
Normal file
|
@ -0,0 +1,231 @@
|
|||
use core::marker::PhantomData;
|
||||
|
||||
use embassy::util::Unborrow;
|
||||
|
||||
use crate::pac::{DBGMCU, FLASH, RCC};
|
||||
use crate::peripherals;
|
||||
use crate::time::Hertz;
|
||||
|
||||
use super::{set_freqs, Clocks};
|
||||
|
||||
const HSI: u32 = 8_000_000;
|
||||
|
||||
/// Configuration of the clocks
|
||||
///
|
||||
/// hse takes precedence over hsi48 if both are enabled
|
||||
#[non_exhaustive]
|
||||
#[derive(Default)]
|
||||
pub struct Config {
|
||||
pub hse: Option<Hertz>,
|
||||
pub bypass_hse: bool,
|
||||
pub usb_pll: bool,
|
||||
|
||||
#[cfg(rcc_f0)]
|
||||
pub hsi48: bool,
|
||||
|
||||
pub sys_ck: Option<Hertz>,
|
||||
pub hclk: Option<Hertz>,
|
||||
pub pclk: Option<Hertz>,
|
||||
pub enable_debug_wfe: bool,
|
||||
}
|
||||
|
||||
pub struct Rcc<'d> {
|
||||
inner: PhantomData<&'d ()>,
|
||||
config: Config,
|
||||
}
|
||||
|
||||
impl<'d> Rcc<'d> {
|
||||
pub fn new(_rcc: impl Unborrow<Target = peripherals::RCC> + 'd, config: Config) -> Self {
|
||||
Self {
|
||||
inner: PhantomData,
|
||||
config,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn freeze(self) -> Clocks {
|
||||
use crate::pac::rcc::vals::{Hpre, Hsebyp, Pllmul, Pllsrc, Ppre, Sw, Usbsw};
|
||||
|
||||
let sysclk = self.config.sys_ck.map(|v| v.0).unwrap_or(HSI);
|
||||
|
||||
let (src_clk, use_hsi48) = self.config.hse.map(|v| (v.0, false)).unwrap_or_else(|| {
|
||||
#[cfg(rcc_f0)]
|
||||
if self.config.hsi48 {
|
||||
return (48_000_000, true);
|
||||
}
|
||||
(HSI, false)
|
||||
});
|
||||
|
||||
let (pllmul_bits, real_sysclk) = if sysclk == src_clk {
|
||||
(None, sysclk)
|
||||
} else {
|
||||
let prediv = if self.config.hse.is_some() { 1 } else { 2 };
|
||||
let pllmul = (2 * prediv * sysclk + src_clk) / src_clk / 2;
|
||||
let pllmul = pllmul.max(2).min(16);
|
||||
|
||||
let pllmul_bits = pllmul as u8 - 2;
|
||||
let real_sysclk = pllmul * src_clk / prediv;
|
||||
(Some(pllmul_bits), real_sysclk)
|
||||
};
|
||||
|
||||
let hpre_bits = self
|
||||
.config
|
||||
.hclk
|
||||
.map(|hclk| match real_sysclk / hclk.0 {
|
||||
0 => unreachable!(),
|
||||
1 => 0b0111,
|
||||
2 => 0b1000,
|
||||
3..=5 => 0b1001,
|
||||
6..=11 => 0b1010,
|
||||
12..=39 => 0b1011,
|
||||
40..=95 => 0b1100,
|
||||
96..=191 => 0b1101,
|
||||
192..=383 => 0b1110,
|
||||
_ => 0b1111,
|
||||
})
|
||||
.unwrap_or(0b0111);
|
||||
let hclk = real_sysclk / (1 << (hpre_bits - 0b0111));
|
||||
|
||||
let ppre_bits = self
|
||||
.config
|
||||
.pclk
|
||||
.map(|pclk| match hclk / pclk.0 {
|
||||
0 => unreachable!(),
|
||||
1 => 0b011,
|
||||
2 => 0b100,
|
||||
3..=5 => 0b101,
|
||||
6..=11 => 0b110,
|
||||
_ => 0b111,
|
||||
})
|
||||
.unwrap_or(0b011);
|
||||
|
||||
let ppre: u8 = 1 << (ppre_bits - 0b011);
|
||||
let pclk = hclk / u32::from(ppre);
|
||||
|
||||
let timer_mul = if ppre == 1 { 1 } else { 2 };
|
||||
|
||||
// NOTE(safety) Atomic write
|
||||
unsafe {
|
||||
FLASH.acr().write(|w| {
|
||||
let latency = if real_sysclk <= 24_000_000 {
|
||||
0
|
||||
} else if real_sysclk <= 48_000_000 {
|
||||
1
|
||||
} else {
|
||||
2
|
||||
};
|
||||
w.latency().0 = latency;
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE(unsafe) We have exclusive access to the RCC
|
||||
unsafe {
|
||||
match (self.config.hse.is_some(), use_hsi48) {
|
||||
(true, _) => {
|
||||
RCC.cr().modify(|w| {
|
||||
w.set_csson(true);
|
||||
w.set_hseon(true);
|
||||
|
||||
if self.config.bypass_hse {
|
||||
w.set_hsebyp(Hsebyp::BYPASSED);
|
||||
}
|
||||
});
|
||||
while !RCC.cr().read().hserdy() {}
|
||||
|
||||
if pllmul_bits.is_some() {
|
||||
RCC.cfgr().modify(|w| w.set_pllsrc(Pllsrc::HSE_DIV_PREDIV))
|
||||
}
|
||||
}
|
||||
(false, true) => {
|
||||
// use_hsi48 will always be false for rcc_f0x0
|
||||
#[cfg(rcc_f0)]
|
||||
RCC.cr2().modify(|w| w.set_hsi48on(true));
|
||||
#[cfg(rcc_f0)]
|
||||
while !RCC.cr2().read().hsi48rdy() {}
|
||||
|
||||
#[cfg(rcc_f0)]
|
||||
if pllmul_bits.is_some() {
|
||||
RCC.cfgr()
|
||||
.modify(|w| w.set_pllsrc(Pllsrc::HSI48_DIV_PREDIV))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
RCC.cr().modify(|w| w.set_hsion(true));
|
||||
while !RCC.cr().read().hsirdy() {}
|
||||
|
||||
if pllmul_bits.is_some() {
|
||||
RCC.cfgr().modify(|w| w.set_pllsrc(Pllsrc::HSI_DIV2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.config.usb_pll {
|
||||
RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLLCLK));
|
||||
}
|
||||
// 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.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_sw(Sw::PLL)
|
||||
});
|
||||
} else {
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_ppre(Ppre(ppre_bits));
|
||||
w.set_hpre(Hpre(hpre_bits));
|
||||
|
||||
if self.config.hse.is_some() {
|
||||
w.set_sw(Sw::HSE);
|
||||
} else if use_hsi48 {
|
||||
#[cfg(rcc_f0)]
|
||||
w.set_sw(Sw::HSI48);
|
||||
} else {
|
||||
w.set_sw(Sw::HSI)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if self.config.enable_debug_wfe {
|
||||
RCC.ahbenr().modify(|w| w.set_dmaen(true));
|
||||
|
||||
critical_section::with(|_| {
|
||||
DBGMCU.cr().modify(|w| {
|
||||
w.set_dbg_standby(true);
|
||||
w.set_dbg_stop(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Clocks {
|
||||
sys: Hertz(real_sysclk),
|
||||
apb1: Hertz(pclk),
|
||||
apb1_tim: Hertz(pclk * timer_mul),
|
||||
apb2_tim: Hertz(0),
|
||||
ahb: Hertz(hclk),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn init(config: Config) {
|
||||
RCC.ahbenr().modify(|w| {
|
||||
w.set_iopaen(true);
|
||||
w.set_iopben(true);
|
||||
w.set_iopcen(true);
|
||||
w.set_iopden(true);
|
||||
|
||||
#[cfg(rcc_f0)]
|
||||
w.set_iopeen(true);
|
||||
|
||||
w.set_iopfen(true);
|
||||
});
|
||||
|
||||
let rcc = Rcc::new(<peripherals::RCC as embassy::util::Steal>::steal(), config);
|
||||
let clocks = rcc.freeze();
|
||||
set_freqs(clocks);
|
||||
}
|
|
@ -9,11 +9,14 @@ mod types;
|
|||
pub struct Clocks {
|
||||
pub sys: Hertz,
|
||||
pub apb1: Hertz,
|
||||
|
||||
#[cfg(not(any(rcc_f0, rcc_f0x0)))]
|
||||
pub apb2: Hertz,
|
||||
|
||||
pub apb1_tim: Hertz,
|
||||
pub apb2_tim: Hertz,
|
||||
|
||||
#[cfg(any(rcc_l0))]
|
||||
#[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))]
|
||||
pub ahb: Hertz,
|
||||
|
||||
#[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))]
|
||||
|
@ -65,6 +68,9 @@ cfg_if::cfg_if! {
|
|||
} else if #[cfg(rcc_wl5x)] {
|
||||
mod wl5x;
|
||||
pub use wl5x::*;
|
||||
} else if #[cfg(any(rcc_f0, rcc_f0x0))] {
|
||||
mod f0;
|
||||
pub use f0::*;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 18f86c83123771048f971350c99c4f810385d7d1
|
||||
Subproject commit eb76ee900ac67b51497196572250323e82666b4c
|
|
@ -19,7 +19,6 @@ pub struct Chip {
|
|||
pub cores: Vec<Core>,
|
||||
pub flash: u32,
|
||||
pub ram: u32,
|
||||
pub gpio_af: String,
|
||||
pub packages: Vec<Package>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue