Assume tim2 in macro and remove clock setup in chip specific rcc init

Add temporary start_tim2() fn to Clock to assist macro in starting
embassy clock
This commit is contained in:
Ulf Lilleengen 2021-05-26 21:42:07 +02:00
parent aaab7d87a5
commit bfa999a2e0
6 changed files with 48 additions and 28 deletions

View File

@ -9,10 +9,14 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream
quote!( quote!(
use #embassy_stm32_path::{interrupt, peripherals, clock::Clock, time::Hertz}; use #embassy_stm32_path::{interrupt, peripherals, clock::Clock, time::Hertz};
let (p, mut c) = #embassy_stm32_path::init(#config); let p = #embassy_stm32_path::init(#config);
let mut c = Clock::new(
unsafe { <peripherals::TIM2 as embassy::util::Steal>::steal() },
interrupt::take!(TIM2),
);
let clock = unsafe { make_static(&mut c) }; let clock = unsafe { make_static(&mut c) };
clock.start(); clock.start_tim2();
let mut alarm = clock.alarm1(); let mut alarm = clock.alarm1();
unsafe { #embassy_path::time::set_clock(clock) }; unsafe { #embassy_path::time::set_clock(clock) };

View File

@ -33,6 +33,20 @@ fn calc_now(period: u32, counter: u16) -> u64 {
((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
} }
static mut CLOCK_FREQS: Option<ClockFreqs> = None;
#[derive(Copy, Clone)]
pub struct ClockFreqs {
pub tim2: Hertz,
}
/// Sets the clock frequencies
///
/// Safety: Sets a mutable global.
pub unsafe fn set_freqs(freqs: ClockFreqs) {
CLOCK_FREQS.replace(freqs);
}
struct AlarmState { struct AlarmState {
timestamp: Cell<u64>, timestamp: Cell<u64>,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
@ -59,8 +73,6 @@ const ALARM_COUNT: usize = 3;
pub struct Clock<T: Instance> { pub struct Clock<T: Instance> {
_inner: T, _inner: T,
irq: T::Interrupt, irq: T::Interrupt,
/// Clock frequency
frequency: Hertz,
/// Number of 2^23 periods elapsed since boot. /// Number of 2^23 periods elapsed since boot.
period: AtomicU32, period: AtomicU32,
/// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled.
@ -68,23 +80,37 @@ pub struct Clock<T: Instance> {
} }
impl<T: Instance> Clock<T> { impl<T: Instance> Clock<T> {
pub fn new(peripheral: T, irq: T::Interrupt, frequency: Hertz) -> Self { pub fn new(peripheral: T, irq: T::Interrupt) -> Self {
Self { Self {
_inner: peripheral, _inner: peripheral,
irq, irq,
frequency,
period: AtomicU32::new(0), period: AtomicU32::new(0),
alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]), alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]),
} }
} }
pub fn start(&'static self) { // TODO: Temporary until clock code generation is in place
pub fn start_tim2(&'static self) {
#[cfg(feature = "_stm32l0")]
unsafe {
let rcc = crate::pac::RCC;
rcc.apb1enr()
.modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED));
rcc.apb1rstr().modify(|w| w.set_tim2rst(true));
rcc.apb1rstr().modify(|w| w.set_tim2rst(false));
}
let timer_freq = unsafe { CLOCK_FREQS.unwrap().tim2 };
self.start(timer_freq);
}
pub fn start(&'static self, timer_freq: Hertz) {
let inner = T::inner(); let inner = T::inner();
// NOTE(unsafe) Critical section to use the unsafe methods // NOTE(unsafe) Critical section to use the unsafe methods
critical_section::with(|_| { critical_section::with(|_| {
unsafe { unsafe {
inner.prepare(self.frequency); inner.prepare(timer_freq);
} }
self.irq.set_handler_context(self as *const _ as *mut _); self.irq.set_handler_context(self as *const _ as *mut _);

View File

@ -36,7 +36,6 @@ pub mod time;
pub use embassy_macros::interrupt; pub use embassy_macros::interrupt;
pub use pac::{interrupt, peripherals, Peripherals}; pub use pac::{interrupt, peripherals, Peripherals};
pub use rcc::SystemClock;
// workaround for svd2rust-generated code using `use crate::generic::*;` // workaround for svd2rust-generated code using `use crate::generic::*;`
pub(crate) use pac::regs::generic; pub(crate) use pac::regs::generic;
@ -61,12 +60,14 @@ impl Default for Config {
} }
/// Initialize embassy. /// Initialize embassy.
pub fn init(config: Config) -> (Peripherals, SystemClock) { pub fn init(config: Config) -> Peripherals {
let p = Peripherals::take(); let p = Peripherals::take();
unsafe { unsafe {
dma::init(); dma::init();
pac::init_exti(); pac::init_exti();
(p, rcc::init(config.rcc)) rcc::init(config.rcc);
} }
p
} }

View File

@ -529,5 +529,4 @@ impl<'d> Rcc<'d> {
} }
// TODO // TODO
pub type SystemClock = (); pub unsafe fn init(_config: Config) {}
pub unsafe fn init(_config: Config) -> SystemClock {}

View File

@ -1,4 +1,5 @@
use crate::clock::Clock; use crate::clock::Clock;
use crate::clock::{set_freqs, ClockFreqs};
use crate::interrupt; use crate::interrupt;
use crate::pac; use crate::pac;
use crate::pac::peripherals::{self, RCC, TIM2}; use crate::pac::peripherals::{self, RCC, TIM2};
@ -585,10 +586,7 @@ pub struct MCOEnabled(());
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct LSE(()); pub struct LSE(());
// We use TIM2 as SystemClock pub unsafe fn init(config: Config) {
pub type SystemClock = Clock<TIM2>;
pub unsafe fn init(config: Config) -> SystemClock {
let rcc = pac::RCC; let rcc = pac::RCC;
let enabled = vals::Iophen::ENABLED; let enabled = vals::Iophen::ENABLED;
rcc.iopenr().write(|w| { rcc.iopenr().write(|w| {
@ -602,14 +600,7 @@ pub unsafe fn init(config: Config) -> SystemClock {
let mut r = <peripherals::RCC as embassy::util::Steal>::steal(); let mut r = <peripherals::RCC as embassy::util::Steal>::steal();
let clocks = r.freeze(config); let clocks = r.freeze(config);
set_freqs(ClockFreqs {
rcc.apb1enr().modify(|w| w.set_tim2en(Lptimen::ENABLED)); tim2: clocks.apb1_clk(),
rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); });
rcc.apb1rstr().modify(|w| w.set_tim2rst(false));
Clock::new(
<peripherals::TIM2 as embassy::util::Steal>::steal(),
interrupt::take!(TIM2),
clocks.apb1_clk(),
)
} }

View File

@ -6,7 +6,6 @@ cfg_if::cfg_if! {
mod l0; mod l0;
pub use l0::*; pub use l0::*;
} else { } else {
pub type SystemClock = ();
#[derive(Default)] #[derive(Default)]
pub struct Config {} pub struct Config {}
pub unsafe fn init(_config: Config) -> SystemClock { pub unsafe fn init(_config: Config) -> SystemClock {