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!(
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) };
clock.start();
clock.start_tim2();
let mut alarm = clock.alarm1();
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)
}
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 {
timestamp: Cell<u64>,
#[allow(clippy::type_complexity)]
@ -59,8 +73,6 @@ const ALARM_COUNT: usize = 3;
pub struct Clock<T: Instance> {
_inner: T,
irq: T::Interrupt,
/// Clock frequency
frequency: Hertz,
/// Number of 2^23 periods elapsed since boot.
period: AtomicU32,
/// 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> {
pub fn new(peripheral: T, irq: T::Interrupt, frequency: Hertz) -> Self {
pub fn new(peripheral: T, irq: T::Interrupt) -> Self {
Self {
_inner: peripheral,
irq,
frequency,
period: AtomicU32::new(0),
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();
// NOTE(unsafe) Critical section to use the unsafe methods
critical_section::with(|_| {
unsafe {
inner.prepare(self.frequency);
inner.prepare(timer_freq);
}
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 pac::{interrupt, peripherals, Peripherals};
pub use rcc::SystemClock;
// workaround for svd2rust-generated code using `use crate::generic::*;`
pub(crate) use pac::regs::generic;
@ -61,12 +60,14 @@ impl Default for Config {
}
/// Initialize embassy.
pub fn init(config: Config) -> (Peripherals, SystemClock) {
pub fn init(config: Config) -> Peripherals {
let p = Peripherals::take();
unsafe {
dma::init();
pac::init_exti();
(p, rcc::init(config.rcc))
rcc::init(config.rcc);
}
p
}

View File

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

View File

@ -1,4 +1,5 @@
use crate::clock::Clock;
use crate::clock::{set_freqs, ClockFreqs};
use crate::interrupt;
use crate::pac;
use crate::pac::peripherals::{self, RCC, TIM2};
@ -585,10 +586,7 @@ pub struct MCOEnabled(());
#[derive(Clone, Copy)]
pub struct LSE(());
// We use TIM2 as SystemClock
pub type SystemClock = Clock<TIM2>;
pub unsafe fn init(config: Config) -> SystemClock {
pub unsafe fn init(config: Config) {
let rcc = pac::RCC;
let enabled = vals::Iophen::ENABLED;
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 clocks = r.freeze(config);
rcc.apb1enr().modify(|w| w.set_tim2en(Lptimen::ENABLED));
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(),
)
set_freqs(ClockFreqs {
tim2: clocks.apb1_clk(),
});
}

View File

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