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:
parent
aaab7d87a5
commit
bfa999a2e0
@ -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) };
|
||||||
|
@ -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 _);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 {}
|
|
||||||
|
@ -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(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user