diff --git a/embassy-imxrt/Cargo.toml b/embassy-imxrt/Cargo.toml index d58de6353..f16002a8d 100644 --- a/embassy-imxrt/Cargo.toml +++ b/embassy-imxrt/Cargo.toml @@ -12,7 +12,7 @@ documentation = "https://docs.embassy.dev/embassy-imxrt" [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-imxrt-v$VERSION/embassy-imxrt/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-imxrt/src/" -features = ["defmt", "unstable-pac", "time", "time-driver"] +features = ["defmt", "unstable-pac", "time", "time-driver-os-timer"] flavors = [ { regex_feature = "mimxrt6.*", target = "thumbv8m.main-none-eabihf" } ] @@ -37,9 +37,12 @@ defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt", "mimxr time = ["dep:embassy-time", "embassy-embedded-hal/time"] ## Enable custom embassy time-driver implementation, using 32KHz RTC -time-driver-rtc = ["_time-driver"] +time-driver-rtc = ["_time-driver", "embassy-time-driver?/tick-hz-1_000"] -_time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-1_000", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] +## Enable custom embassy time-driver implementation, using 1MHz OS Timer +time-driver-os-timer = ["_time-driver", "embassy-time-driver?/tick-hz-1_000_000"] + +_time-driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] ## Reexport the PAC for the currently enabled chip at `embassy_imxrt::pac` (unstable) unstable-pac = [] diff --git a/embassy-imxrt/src/clocks.rs b/embassy-imxrt/src/clocks.rs index 1d36fb142..39c3e6238 100644 --- a/embassy-imxrt/src/clocks.rs +++ b/embassy-imxrt/src/clocks.rs @@ -1,8 +1,6 @@ //! Clock configuration for the `RT6xx` use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; -#[cfg(feature = "defmt")] -use defmt; use paste::paste; use crate::pac; @@ -503,7 +501,6 @@ impl ConfigurableClock for LposcConfig { } } } else { - error!("failed to convert desired clock rate, {:#}, to LPOSC Freq", freq); Err(ClockError::InvalidFrequency) } } @@ -549,7 +546,6 @@ impl ConfigurableClock for FfroConfig { Ok(()) } fn get_clock_rate(&self) -> Result { - trace!("getting ffro clock rate"); Ok(self.freq.load(Ordering::Relaxed)) } fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { @@ -616,7 +612,6 @@ impl ConfigurableClock for SfroConfig { fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { if self.state == State::Enabled { if freq == SFRO_FREQ { - trace!("Sfro frequency is already set at 16MHz"); Ok(()) } else { Err(ClockError::InvalidFrequency) @@ -677,7 +672,6 @@ impl MultiSourceClock for MainPllClkConfig { } MainPllClkSrc::SFRO => { if !clock_src_config.is_enabled() { - error!("Can't set SFRO as source for MainPll as it's not enabled"); return Err(ClockError::ClockNotEnabled); } // check if desired frequency is a valid multiple of 16m SFRO clock @@ -703,7 +697,6 @@ impl ConfigurableClock for MainPllClkConfig { } fn disable(&self) -> Result<(), ClockError> { if self.is_enabled() { - error!("Attempting to reset the Main Pll Clock, should be resetting its source"); Err(ClockError::ClockNotSupported) } else { Err(ClockError::ClockNotEnabled) @@ -719,7 +712,6 @@ impl ConfigurableClock for MainPllClkConfig { } fn set_clock_rate(&mut self, div: u8, mult: u8, freq: u32) -> Result<(), ClockError> { if self.is_enabled() { - trace!("attempting to set main pll clock rate"); // SAFETY: unsafe needed to take pointers to Sysctl0 and Clkctl0 let clkctl0 = unsafe { crate::pac::Clkctl0::steal() }; let sysctl0 = unsafe { crate::pac::Sysctl0::steal() }; @@ -741,15 +733,12 @@ impl ConfigurableClock for MainPllClkConfig { base_rate = r; } MainPllClkSrc::FFRO => { - trace!("found FFRO as source, wait a bit"); delay_loop_clocks(1000, desired_freq); match clkctl0.ffroctl0().read().trim_range().is_ffro_48mhz() { true => base_rate = Into::into(FfroFreq::Ffro48m), false => base_rate = Into::into(FfroFreq::Ffro60m), } - trace!("found ffro rate to be: {:#}", base_rate); if div == 2 { - trace!("dividing FFRO rate by 2"); clkctl0.syspll0clksel().write(|w| w.sel().ffro_div_2()); delay_loop_clocks(150, desired_freq); base_rate /= 2; @@ -763,10 +752,8 @@ impl ConfigurableClock for MainPllClkConfig { } }; base_rate *= u32::from(mult); - trace!("calculated base rate at: {:#}", base_rate); if base_rate != freq { // make sure to power syspll back up before returning the error - error!("invalid frequency found, powering syspll back up before returning error. Check div and mult"); // Clear System PLL reset clkctl0.syspll0ctl0().write(|w| w.reset().normal()); // Power up SYSPLL @@ -775,13 +762,11 @@ impl ConfigurableClock for MainPllClkConfig { .write(|w| w.syspllana_pd().clr_pdruncfg0().syspllldo_pd().clr_pdruncfg0()); return Err(ClockError::InvalidFrequency); } - trace!("setting default num and denom"); // SAFETY: unsafe needed to write the bits for the num and demon fields clkctl0.syspll0num().write(|w| unsafe { w.num().bits(0b0) }); clkctl0.syspll0denom().write(|w| unsafe { w.denom().bits(0b1) }); delay_loop_clocks(30, desired_freq); self.mult.store(mult, Ordering::Relaxed); - trace!("setting self.mult as: {:#}", mult); match mult { 16 => { clkctl0.syspll0ctl0().modify(|_r, w| w.mult().div_16()); @@ -803,7 +788,6 @@ impl ConfigurableClock for MainPllClkConfig { } _ => return Err(ClockError::InvalidMult), } - trace!("clear syspll reset"); // Clear System PLL reset clkctl0.syspll0ctl0().modify(|_r, w| w.reset().normal()); // Power up SYSPLL @@ -819,7 +803,6 @@ impl ConfigurableClock for MainPllClkConfig { clkctl0.syspll0ctl0().modify(|_, w| w.holdringoff_ena().dsiable()); delay_loop_clocks(15, desired_freq); - trace!("setting new PFD0 bits"); // gate the output and clear bits. // SAFETY: unsafe needed to write the bits for pfd0 clkctl0 @@ -833,7 +816,6 @@ impl ConfigurableClock for MainPllClkConfig { .modify(|_r, w| unsafe { w.pfd0_clkgate().not_gated().pfd0().bits(0x12) }); // wait for ready bit to be set delay_loop_clocks(50, desired_freq); - trace!("waiting for mainpll clock to be ready"); while clkctl0.syspll0pfd().read().pfd0_clkrdy().bit_is_clear() {} // clear by writing a 1 clkctl0.syspll0pfd().modify(|_, w| w.pfd0_clkrdy().set_bit()); @@ -854,11 +836,9 @@ impl ConfigurableClock for MainPllClkConfig { impl MainPllClkConfig { /// Calculate the mult value of a desired frequency, return error if invalid pub(self) fn calc_mult(rate: u32, base_freq: u32) -> Result { - trace!("calculating mult for {:#} / {:#}", rate, base_freq); const VALIDMULTS: [u8; 6] = [16, 17, 20, 22, 27, 33]; if rate > base_freq && rate % base_freq == 0 { let mult = (rate / base_freq) as u8; - trace!("verifying that calculated mult {:#} is a valid one", mult); if VALIDMULTS.into_iter().any(|i| i == mult) { Ok(mult) } else { @@ -1112,7 +1092,6 @@ impl ConfigurableClock for MainClkConfig { Ok(()) } fn disable(&self) -> Result<(), ClockError> { - error!("Attempting to reset the main clock, should NOT happen during runtime"); Err(ClockError::ClockNotSupported) } fn get_clock_rate(&self) -> Result { @@ -1120,7 +1099,6 @@ impl ConfigurableClock for MainClkConfig { Ok(rate) } fn set_clock_rate(&mut self, _div: u8, _mult: u8, _freq: u32) -> Result<(), ClockError> { - error!("The multi-source set_clock_rate_and_source method should be used instead of set_clock_rate"); Err(ClockError::ClockNotSupported) } fn is_enabled(&self) -> bool { @@ -1145,7 +1123,6 @@ impl ConfigurableClock for ClkInConfig { } } fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { - trace!("Setting value of clk in config, this won't change the clock itself"); self.freq.as_ref().unwrap().store(freq, Ordering::Relaxed); Ok(()) } @@ -1188,7 +1165,6 @@ impl ConfigurableClock for RtcClkConfig { Ok(()) } fn disable(&self) -> Result<(), ClockError> { - error!("Resetting the RTC clock, this should NOT happen during runtime"); Err(ClockError::ClockNotSupported) } fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { @@ -1199,7 +1175,6 @@ impl ConfigurableClock for RtcClkConfig { match r { RtcFreq::Default1Hz => { if rtc.ctrl().read().rtc_en().is_enable() { - trace!("Attempting to enable an already enabled clock, RTC 1Hz"); } else { rtc.ctrl().modify(|_r, w| w.rtc_en().enable()); } @@ -1207,7 +1182,6 @@ impl ConfigurableClock for RtcClkConfig { } RtcFreq::HighResolution1khz => { if rtc.ctrl().read().rtc1khz_en().is_enable() { - trace!("Attempting to enable an already enabled clock, RTC 1Hz"); } else { rtc.ctrl().modify(|_r, w| w.rtc1khz_en().enable()); } @@ -1215,7 +1189,6 @@ impl ConfigurableClock for RtcClkConfig { } RtcFreq::SubSecond32kHz => { if rtc.ctrl().read().rtc_subsec_ena().is_enable() { - trace!("Attempting to enable an already enabled clock, RTC 1Hz"); } else { rtc.ctrl().modify(|_r, w| w.rtc_subsec_ena().enable()); } @@ -1245,18 +1218,12 @@ impl ConfigurableClock for RtcClkConfig { impl SysClkConfig { /// Updates the system core clock frequency, SW concept used for systick - fn update_sys_core_clock(&self) { - trace!( - "System core clock has been updated to {:?}, this involves no HW reg writes", - self.sysclkfreq.load(Ordering::Relaxed) - ); - } + fn update_sys_core_clock(&self) {} } impl ConfigurableClock for SysOscConfig { fn enable_and_reset(&self) -> Result<(), ClockError> { if self.state == State::Enabled { - trace!("SysOsc was already enabled"); return Ok(()); } @@ -1498,32 +1465,26 @@ impl ClockOutConfig { /// Using the config, enables all desired clocks to desired clock rates fn init_clock_hw(config: ClockConfig) -> Result<(), ClockError> { if let Err(e) = config.rtc.enable_and_reset() { - error!("couldn't Power on OSC for RTC, result: {:?}", e); return Err(e); } if let Err(e) = config.lposc.enable_and_reset() { - error!("couldn't Power on LPOSC, result: {:?}", e); return Err(e); } if let Err(e) = config.ffro.enable_and_reset() { - error!("couldn't Power on FFRO, result: {:?}", e); return Err(e); } if let Err(e) = config.sfro.enable_and_reset() { - error!("couldn't Power on SFRO, result: {:?}", e); return Err(e); } if let Err(e) = config.sys_osc.enable_and_reset() { - error!("Couldn't enable sys oscillator {:?}", e); return Err(e); } if let Err(e) = config.main_pll_clk.enable_and_reset() { - error!("Couldn't enable main pll clock {:?}", e); return Err(e); } @@ -1542,7 +1503,6 @@ fn init_clock_hw(config: ClockConfig) -> Result<(), ClockError> { init_syscpuahb_clk(); if let Err(e) = config.main_clk.enable_and_reset() { - error!("Couldn't enable main clock {:?}", e); return Err(e); } @@ -1561,7 +1521,8 @@ pub(crate) unsafe fn init(config: ClockConfig) -> Result<(), ClockError> { ///Trait to expose perph clocks trait SealedSysconPeripheral { - fn enable_and_reset_perph_clock(); + fn enable_perph_clock(); + fn reset_perph(); fn disable_perph_clock(); } @@ -1574,7 +1535,18 @@ pub trait SysconPeripheral: SealedSysconPeripheral + 'static {} /// /// Peripheral must not be in use. pub fn enable_and_reset() { - T::enable_and_reset_perph_clock(); + T::enable_perph_clock(); + T::reset_perph(); +} + +/// Enables peripheral `T`. +pub fn enable() { + T::enable_perph_clock(); +} + +/// Reset peripheral `T`. +pub fn reset() { + T::reset_perph(); } /// Disables peripheral `T`. @@ -1588,15 +1560,21 @@ pub fn disable() { macro_rules! impl_perph_clk { ($peripheral:ident, $clkctl:ident, $clkreg:ident, $rstctl:ident, $rstreg:ident, $bit:expr) => { impl SealedSysconPeripheral for crate::peripherals::$peripheral { - fn enable_and_reset_perph_clock() { + fn enable_perph_clock() { // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 let cc1 = unsafe { pac::$clkctl::steal() }; - let rc1 = unsafe { pac::$rstctl::steal() }; paste! { // SAFETY: unsafe due to the use of bits() cc1.[<$clkreg _set>]().write(|w| unsafe { w.bits(1 << $bit) }); + } + } + fn reset_perph() { + // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 + let rc1 = unsafe { pac::$rstctl::steal() }; + + paste! { // SAFETY: unsafe due to the use of bits() rc1.[<$rstreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); } @@ -1605,12 +1583,8 @@ macro_rules! impl_perph_clk { fn disable_perph_clock() { // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 let cc1 = unsafe { pac::$clkctl::steal() }; - let rc1 = unsafe { pac::$rstctl::steal() }; paste! { - // SAFETY: unsafe due to the use of bits() - rc1.[<$rstreg _set>]().write(|w| unsafe { w.bits(1 << $bit) }); - // SAFETY: unsafe due to the use of bits() cc1.[<$clkreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); } diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs index 5fbf3244b..ad9f81e88 100644 --- a/embassy-imxrt/src/lib.rs +++ b/embassy-imxrt/src/lib.rs @@ -22,7 +22,7 @@ pub mod gpio; pub mod iopctl; #[cfg(feature = "_time-driver")] -pub mod rtc; +pub mod time_driver; // This mod MUST go last, so that it sees all the `impl_foo!' macros #[cfg_attr(feature = "mimxrt633s", path = "chips/mimxrt633s.rs")] @@ -132,12 +132,10 @@ pub fn init(config: config::Config) -> Peripherals { error!("unable to initialize Clocks for reason: {:?}", e); // Panic here? } - gpio::init(); } - - // init RTC time driver #[cfg(feature = "_time-driver")] - rtc::init(config.time_interrupt_priority); + time_driver::init(config.time_interrupt_priority); + gpio::init(); peripherals } diff --git a/embassy-imxrt/src/rtc.rs b/embassy-imxrt/src/time_driver.rs similarity index 68% rename from embassy-imxrt/src/rtc.rs rename to embassy-imxrt/src/time_driver.rs index 56a8f7397..c68679d3e 100644 --- a/embassy-imxrt/src/rtc.rs +++ b/embassy-imxrt/src/time_driver.rs @@ -1,5 +1,6 @@ -//! RTC Time Driver. +//! Time Driver. use core::cell::{Cell, RefCell}; +#[cfg(feature = "time-driver-rtc")] use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; use critical_section::CriticalSection; @@ -8,27 +9,11 @@ use embassy_sync::blocking_mutex::Mutex; use embassy_time_driver::Driver; use embassy_time_queue_utils::Queue; +#[cfg(feature = "time-driver-os-timer")] +use crate::clocks::enable; use crate::interrupt::InterruptExt; use crate::{interrupt, pac}; -fn rtc() -> &'static pac::rtc::RegisterBlock { - unsafe { &*pac::Rtc::ptr() } -} - -/// Calculate the timestamp from the period count and the tick count. -/// -/// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches -/// the expected range for the `period` parity, we're done. If it doesn't, this means that -/// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value -/// corresponds to the next period. -/// -/// the 1kHz RTC counter is 16 bits and RTC doesn't have separate compare channels, -/// so using a 32 bit GPREG0-2 as counter, compare, and int_en -/// `period` is a 32bit integer, gpreg 'counter' is 31 bits plus the parity bit for overflow detection -fn calc_now(period: u32, counter: u32) -> u64 { - ((period as u64) << 31) + ((counter ^ ((period & 1) << 31)) as u64) -} - struct AlarmState { timestamp: Cell, } @@ -43,6 +28,34 @@ impl AlarmState { } } +#[cfg(feature = "time-driver-rtc")] +fn rtc() -> &'static pac::rtc::RegisterBlock { + unsafe { &*pac::Rtc::ptr() } +} + +/// Calculate the timestamp from the period count and the tick count. +/// +/// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches +/// the expected range for the `period` parity, we're done. If it doesn't, this means that +/// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value +/// corresponds to the next period. +/// +/// the 1kHz RTC counter is 16 bits and RTC doesn't have separate compare channels, +/// so using a 32 bit GPREG0-2 as counter, compare, and int_en +/// `period` is a 32bit integer, gpreg 'counter' is 31 bits plus the parity bit for overflow detection +#[cfg(feature = "time-driver-rtc")] +fn calc_now(period: u32, counter: u32) -> u64 { + ((period as u64) << 31) + ((counter ^ ((period & 1) << 31)) as u64) +} + +#[cfg(feature = "time-driver-rtc")] +embassy_time_driver::time_driver_impl!(static DRIVER: Rtc = Rtc { + period: AtomicU32::new(0), + alarms: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), + queue: Mutex::new(RefCell::new(Queue::new())), +}); + +#[cfg(feature = "time-driver-rtc")] struct Rtc { /// Number of 2^31 periods elapsed since boot. period: AtomicU32, @@ -51,12 +64,7 @@ struct Rtc { queue: Mutex>, } -embassy_time_driver::time_driver_impl!(static DRIVER: Rtc = Rtc { - period: AtomicU32::new(0), - alarms: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), - queue: Mutex::new(RefCell::new(Queue::new())), -}); - +#[cfg(feature = "time-driver-rtc")] impl Rtc { /// Access the GPREG0 register to use it as a 31-bit counter. #[inline] @@ -219,6 +227,7 @@ impl Rtc { } } +#[cfg(feature = "time-driver-rtc")] impl Driver for Rtc { fn now(&self) -> u64 { // `period` MUST be read before `counter`, see comment at the top for details. @@ -242,13 +251,158 @@ impl Driver for Rtc { } } -#[cfg(feature = "rt")] +#[cfg(all(feature = "rt", feature = "time-driver-rtc"))] #[allow(non_snake_case)] #[interrupt] fn RTC() { DRIVER.on_interrupt() } +#[cfg(feature = "time-driver-os-timer")] +fn os() -> &'static pac::ostimer0::RegisterBlock { + unsafe { &*pac::Ostimer0::ptr() } +} + +/// Convert gray to decimal +/// +/// Os Event provides a 64-bit timestamp gray-encoded. All we have to +/// do here is read both 32-bit halves of the register and convert +/// from gray to regular binary. +#[cfg(feature = "time-driver-os-timer")] +fn gray_to_dec(gray: u64) -> u64 { + let mut dec = gray; + + dec ^= dec >> 1; + dec ^= dec >> 2; + dec ^= dec >> 4; + dec ^= dec >> 8; + dec ^= dec >> 16; + dec ^= dec >> 32; + + dec +} + +/// Convert decimal to gray +/// +/// Before writing match value to the target register, we must convert +/// it back into gray code. +#[cfg(feature = "time-driver-os-timer")] +fn dec_to_gray(dec: u64) -> u64 { + let gray = dec; + gray ^ (gray >> 1) +} + +#[cfg(feature = "time-driver-os-timer")] +embassy_time_driver::time_driver_impl!(static DRIVER: OsTimer = OsTimer { + alarms: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), + queue: Mutex::new(RefCell::new(Queue::new())), +}); + +#[cfg(feature = "time-driver-os-timer")] +struct OsTimer { + /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. + alarms: Mutex, + queue: Mutex>, +} + +#[cfg(feature = "time-driver-os-timer")] +impl OsTimer { + fn init(&'static self, irq_prio: crate::interrupt::Priority) { + // init alarms + critical_section::with(|cs| { + let alarm = DRIVER.alarms.borrow(cs); + alarm.timestamp.set(u64::MAX); + }); + + // Enable clocks. Documentation advises AGAINST resetting this + // peripheral. + enable::(); + + interrupt::OS_EVENT.disable(); + + // Make sure interrupt is masked + os().osevent_ctrl().modify(|_, w| w.ostimer_intena().clear_bit()); + + // Default to the end of time + os().match_l().write(|w| unsafe { w.bits(0xffff_ffff) }); + os().match_h().write(|w| unsafe { w.bits(0xffff_ffff) }); + + interrupt::OS_EVENT.unpend(); + interrupt::OS_EVENT.set_priority(irq_prio); + unsafe { interrupt::OS_EVENT.enable() }; + } + + fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { + let alarm = self.alarms.borrow(cs); + alarm.timestamp.set(timestamp); + + let t = self.now(); + if timestamp <= t { + os().osevent_ctrl().modify(|_, w| w.ostimer_intena().clear_bit()); + alarm.timestamp.set(u64::MAX); + return false; + } + + let gray_timestamp = dec_to_gray(timestamp); + + os().match_l() + .write(|w| unsafe { w.bits(gray_timestamp as u32 & 0xffff_ffff) }); + os().match_h() + .write(|w| unsafe { w.bits((gray_timestamp >> 32) as u32) }); + os().osevent_ctrl().modify(|_, w| w.ostimer_intena().set_bit()); + + true + } + + #[cfg(feature = "rt")] + fn trigger_alarm(&self, cs: CriticalSection) { + let mut next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now()); + while !self.set_alarm(cs, next) { + next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now()); + } + } + + #[cfg(feature = "rt")] + fn on_interrupt(&self) { + critical_section::with(|cs| { + if os().osevent_ctrl().read().ostimer_intrflag().bit_is_set() { + os().osevent_ctrl().modify(|_, w| w.ostimer_intena().clear_bit()); + self.trigger_alarm(cs); + } + }); + } +} + +#[cfg(feature = "time-driver-os-timer")] +impl Driver for OsTimer { + fn now(&self) -> u64 { + let mut t = os().evtimerh().read().bits() as u64; + t <<= 32; + t |= os().evtimerl().read().bits() as u64; + gray_to_dec(t) + } + + fn schedule_wake(&self, at: u64, waker: &core::task::Waker) { + critical_section::with(|cs| { + let mut queue = self.queue.borrow(cs).borrow_mut(); + + if queue.schedule_wake(at, waker) { + let mut next = queue.next_expiration(self.now()); + while !self.set_alarm(cs, next) { + next = queue.next_expiration(self.now()); + } + } + }) + } +} + +#[cfg(all(feature = "rt", feature = "time-driver-os-timer"))] +#[allow(non_snake_case)] +#[interrupt] +fn OS_EVENT() { + DRIVER.on_interrupt() +} + pub(crate) fn init(irq_prio: crate::interrupt::Priority) { DRIVER.init(irq_prio) } diff --git a/examples/mimxrt6/Cargo.toml b/examples/mimxrt6/Cargo.toml index 8fc510c47..b0c56f003 100644 --- a/examples/mimxrt6/Cargo.toml +++ b/examples/mimxrt6/Cargo.toml @@ -12,8 +12,8 @@ defmt-rtt = "1.0" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } embassy-futures = { version = "0.1.1", path = "../../embassy-futures" } -embassy-imxrt = { version = "0.1.0", path = "../../embassy-imxrt", features = ["defmt", "mimxrt685s", "unstable-pac", "time", "time-driver-rtc"] } -embassy-time = { version = "0.4", path = "../../embassy-time" } +embassy-imxrt = { version = "0.1.0", path = "../../embassy-imxrt", features = ["defmt", "mimxrt685s", "unstable-pac", "time", "time-driver-os-timer"] } +embassy-time = { version = "0.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = "1.0.0"