stm32/time_driver: use trait impls from the main timer mod.
This commit is contained in:
parent
e8ca5f9b04
commit
2a246be06e
@ -11,12 +11,12 @@ use embassy::time::TICKS_PER_SECOND;
|
||||
use stm32_metapac::timer::regs;
|
||||
|
||||
use crate::interrupt;
|
||||
use crate::interrupt::{CriticalSection, Interrupt};
|
||||
use crate::pac::timer::{vals, TimGp16};
|
||||
use crate::interrupt::CriticalSection;
|
||||
use crate::pac::timer::vals;
|
||||
use crate::peripherals;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
|
||||
use self::sealed::Instance as _;
|
||||
use crate::timer::sealed::Basic16bitInstance as BasicInstance;
|
||||
use crate::timer::sealed::GeneralPurpose16bitInstance as Instance;
|
||||
|
||||
const ALARM_COUNT: usize = 3;
|
||||
|
||||
@ -29,25 +29,35 @@ type T = peripherals::TIM4;
|
||||
#[cfg(time_driver_tim5)]
|
||||
type T = peripherals::TIM5;
|
||||
|
||||
#[cfg(time_driver_tim2)]
|
||||
#[interrupt]
|
||||
fn TIM2() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
#[cfg(time_driver_tim3)]
|
||||
#[interrupt]
|
||||
fn TIM3() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
#[cfg(time_driver_tim4)]
|
||||
#[interrupt]
|
||||
fn TIM4() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
#[cfg(time_driver_tim5)]
|
||||
#[interrupt]
|
||||
fn TIM5() {
|
||||
DRIVER.on_interrupt()
|
||||
crate::pac::interrupts! {
|
||||
(TIM2, timer, $block:ident, UP, $irq:ident) => {
|
||||
#[cfg(time_driver_tim2)]
|
||||
#[interrupt]
|
||||
fn $irq() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
};
|
||||
(TIM3, timer, $block:ident, UP, $irq:ident) => {
|
||||
#[cfg(time_driver_tim3)]
|
||||
#[interrupt]
|
||||
fn $irq() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
};
|
||||
(TIM4, timer, $block:ident, UP, $irq:ident) => {
|
||||
#[cfg(time_driver_tim4)]
|
||||
#[interrupt]
|
||||
fn $irq() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
};
|
||||
(TIM5, timer, $block:ident, UP, $irq:ident) => {
|
||||
#[cfg(time_driver_tim5)]
|
||||
#[interrupt]
|
||||
fn $irq() {
|
||||
DRIVER.on_interrupt()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Clock timekeeping works with something we call "periods", which are time intervals
|
||||
@ -93,6 +103,7 @@ impl AlarmState {
|
||||
}
|
||||
|
||||
struct RtcDriver {
|
||||
timer: T,
|
||||
/// Number of 2^15 periods elapsed since boot.
|
||||
period: AtomicU32,
|
||||
alarm_count: AtomicU8,
|
||||
@ -103,6 +114,7 @@ struct RtcDriver {
|
||||
const ALARM_STATE_NEW: AlarmState = AlarmState::new();
|
||||
|
||||
embassy::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
|
||||
timer: unsafe { core::mem::transmute(()) }, // steal is not const
|
||||
period: AtomicU32::new(0),
|
||||
alarm_count: AtomicU8::new(0),
|
||||
alarms: Mutex::const_new(CriticalSectionRawMutex::new(), [ALARM_STATE_NEW; ALARM_COUNT]),
|
||||
@ -110,10 +122,10 @@ embassy::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
|
||||
|
||||
impl RtcDriver {
|
||||
fn init(&'static self) {
|
||||
let r = T::regs();
|
||||
let r = self.timer.regs_gp16();
|
||||
|
||||
T::enable();
|
||||
T::reset();
|
||||
<T as RccPeripheral>::enable();
|
||||
<T as RccPeripheral>::reset();
|
||||
|
||||
let timer_freq = T::frequency();
|
||||
|
||||
@ -142,7 +154,7 @@ impl RtcDriver {
|
||||
// Enable CC0, disable others
|
||||
r.dier().write(|w| w.set_ccie(0, true));
|
||||
|
||||
let irq: <T as sealed::Instance>::Interrupt = core::mem::transmute(());
|
||||
let irq: <T as BasicInstance>::Interrupt = core::mem::transmute(());
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
@ -151,7 +163,7 @@ impl RtcDriver {
|
||||
}
|
||||
|
||||
fn on_interrupt(&self) {
|
||||
let r = T::regs();
|
||||
let r = self.timer.regs_gp16();
|
||||
|
||||
// NOTE(unsafe) Use critical section to access the methods
|
||||
// XXX: reduce the size of this critical section ?
|
||||
@ -182,7 +194,7 @@ impl RtcDriver {
|
||||
}
|
||||
|
||||
fn next_period(&self) {
|
||||
let r = T::regs();
|
||||
let r = self.timer.regs_gp16();
|
||||
|
||||
let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
let t = (period as u64) << 15;
|
||||
@ -224,7 +236,7 @@ impl RtcDriver {
|
||||
|
||||
impl Driver for RtcDriver {
|
||||
fn now(&self) -> u64 {
|
||||
let r = T::regs();
|
||||
let r = self.timer.regs_gp16();
|
||||
|
||||
let period = self.period.load(Ordering::Relaxed);
|
||||
compiler_fence(Ordering::Acquire);
|
||||
@ -261,7 +273,7 @@ impl Driver for RtcDriver {
|
||||
|
||||
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) {
|
||||
critical_section::with(|cs| {
|
||||
let r = T::regs();
|
||||
let r = self.timer.regs_gp16();
|
||||
|
||||
let n = alarm.id() as _;
|
||||
let alarm = self.get_alarm(cs, alarm);
|
||||
@ -291,37 +303,3 @@ impl Driver for RtcDriver {
|
||||
pub(crate) fn init() {
|
||||
DRIVER.init()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
||||
pub(crate) mod sealed {
|
||||
use super::*;
|
||||
pub trait Instance {
|
||||
type Interrupt: Interrupt;
|
||||
|
||||
fn regs() -> TimGp16;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: sealed::Instance + Sized + RccPeripheral + 'static {}
|
||||
|
||||
macro_rules! impl_timer {
|
||||
($inst:ident) => {
|
||||
impl sealed::Instance for peripherals::$inst {
|
||||
type Interrupt = crate::interrupt::$inst;
|
||||
|
||||
fn regs() -> TimGp16 {
|
||||
crate::pac::timer::TimGp16(crate::pac::$inst.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance for peripherals::$inst {}
|
||||
};
|
||||
}
|
||||
|
||||
crate::pac::peripherals!(
|
||||
(timer, TIM2) => { impl_timer!(TIM2); };
|
||||
(timer, TIM3) => { impl_timer!(TIM3); };
|
||||
(timer, TIM4) => { impl_timer!(TIM4); };
|
||||
(timer, TIM5) => { impl_timer!(TIM5); };
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user