From 60a2c76005cffd62416772d15bc811b5e13675e5 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Fri, 22 Nov 2024 11:24:06 +0000 Subject: [PATCH] [1/4] Timer refactor: system timer (#2576) * system timer simplfication * Removes _all_ type params on Alarm * Systimer no longer implements peripheral ref, the peripheral ref pattern is instead intended to be used on the higher level timer drivers * Removed `Unit` as a type, in favour of an enum * Alarms are back in the main `SystemTimer` "driver" * Made all `Unit` modification methods unsafe, it's not possible to modify the `Unit`'s safely whilst timers and or the `time::now` API is in use * fix examples and tests (by removing them :D) * changelog and migration * /unit_count/unit_value/g * etm doctest * Review feedback --- esp-hal-embassy/src/lib.rs | 7 +- esp-hal/CHANGELOG.md | 10 + esp-hal/MIGRATING-0.22.md | 18 + esp-hal/src/time.rs | 8 +- esp-hal/src/timer/mod.rs | 24 +- esp-hal/src/timer/systimer.rs | 661 ++++-------------- esp-wifi/src/lib.rs | 14 +- examples/src/bin/embassy_multiprio.rs | 4 +- examples/src/bin/embassy_parl_io_rx.rs | 4 +- examples/src/bin/embassy_parl_io_tx.rs | 4 +- examples/src/bin/etm_blinky_systimer.rs | 57 -- examples/src/bin/hmac.rs | 9 +- examples/src/bin/systimer.rs | 125 ---- examples/src/bin/wifi_embassy_access_point.rs | 4 +- .../bin/wifi_embassy_access_point_with_sta.rs | 4 +- examples/src/bin/wifi_embassy_bench.rs | 4 +- examples/src/bin/wifi_embassy_ble.rs | 4 +- examples/src/bin/wifi_embassy_dhcp.rs | 4 +- examples/src/bin/wifi_embassy_esp_now.rs | 4 +- .../src/bin/wifi_embassy_esp_now_duplex.rs | 4 +- examples/src/bin/wifi_embassy_trouble.rs | 3 +- examples/src/lib.rs | 13 - hil-test/Cargo.toml | 13 - hil-test/tests/delay_async.rs | 173 ----- hil-test/tests/embassy_interrupt_executor.rs | 4 +- hil-test/tests/embassy_interrupt_spi_dma.rs | 8 +- hil-test/tests/embassy_timers_executors.rs | 294 -------- hil-test/tests/systimer.rs | 182 ----- 28 files changed, 204 insertions(+), 1459 deletions(-) delete mode 100644 examples/src/bin/etm_blinky_systimer.rs delete mode 100644 examples/src/bin/systimer.rs delete mode 100644 examples/src/lib.rs delete mode 100644 hil-test/tests/delay_async.rs delete mode 100644 hil-test/tests/embassy_timers_executors.rs delete mode 100644 hil-test/tests/systimer.rs diff --git a/esp-hal-embassy/src/lib.rs b/esp-hal-embassy/src/lib.rs index 795f4cf13..5efbd02fb 100644 --- a/esp-hal-embassy/src/lib.rs +++ b/esp-hal-embassy/src/lib.rs @@ -83,12 +83,7 @@ where } #[cfg(not(feature = "esp32"))] -impl IntoAnyTimer for Alarm<'_, T, DM, COMP, UNIT> -where - DM: esp_hal::Mode, - Self: Into, -{ -} +impl IntoAnyTimer for Alarm where Self: Into {} impl TimerCollection for T where diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 98054d720..0348757aa 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -19,6 +19,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - DMA channel objects now implement `Peripheral` (#2526) - DMA channel objects are no longer wrapped in `Channel`. The `Channel` drivers are now managed by DMA enabled peripheral drivers. (#2526) - The `Dpi` driver and `DpiTransfer` now have a `Mode` type parameter. The driver's asyncness is determined by the asyncness of the `Lcd` used to create it. (#2526) +- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403) +- `SystemTimer::set_unit_count` & `SystemTimer::configure_unit` (#2576) +- `SystemTimer::set_unit_value` & `SystemTimer::configure_unit` (#2576) + +### Changed + +- `SystemTimer` no longer uses peripheral ref (#2576) +- `SystemTimer::now` has been renamed `SystemTimer::unit_value(Unit)` (#2576) ### Fixed @@ -26,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `configure` and `configure_for_async` DMA channel functions has been removed (#2403) - The DMA channel objects no longer have `tx` and `rx` fields. (#2526) +- `SysTimerAlarms` has been removed, alarms are now part of the `SystemTimer` struct (#2576) +- `FrozenUnit`, `AnyUnit`, `SpecificUnit`, `SpecificComparator`, `AnyComparator` have been removed from `systimer` (#2576) ## [0.22.0] - 2024-11-20 diff --git a/esp-hal/MIGRATING-0.22.md b/esp-hal/MIGRATING-0.22.md index 7cb68ead4..92e53418c 100644 --- a/esp-hal/MIGRATING-0.22.md +++ b/esp-hal/MIGRATING-0.22.md @@ -26,3 +26,21 @@ -.with_dma(dma_channel.configure(false, DmaPriority::Priority1)); +.with_dma(dma_channel); ``` + +## Timer changes + +The low level timers, `SystemTimer` and `TimerGroup` are now "dumb". They contain no logic for operating modes or trait implementations (except the low level `Timer` trait). + +### SystemTimer + +```diff +let systimer = SystemTimer::new(peripherals.SYSTIMER); +- static UNIT0: StaticCell> = StaticCell::new(); +- let unit0 = UNIT0.init(systimer.unit0); +- let frozen_unit = FrozenUnit::new(unit0); +- let alarm0 = Alarm::new(systimer.comparator0, &frozen_unit); +- alarm0.set_period(1u32.secs()); ++ let alarm0 = systimer.alarm0; ++ let mut timer = PeriodicTimer::new(alarm0); ++ timer.start(1u64.secs()); +``` diff --git a/esp-hal/src/time.rs b/esp-hal/src/time.rs index 89b45ed5d..38a29de65 100644 --- a/esp-hal/src/time.rs +++ b/esp-hal/src/time.rs @@ -47,12 +47,10 @@ pub fn now() -> Instant { #[cfg(not(esp32))] let (ticks, div) = { + use crate::timer::systimer::{SystemTimer, Unit}; // otherwise use SYSTIMER - let ticks = crate::timer::systimer::SystemTimer::now(); - ( - ticks, - (crate::timer::systimer::SystemTimer::ticks_per_second() / 1_000_000), - ) + let ticks = SystemTimer::unit_value(Unit::Unit0); + (ticks, (SystemTimer::ticks_per_second() / 1_000_000)) }; Instant::from_ticks(ticks / div) diff --git a/esp-hal/src/timer/mod.rs b/esp-hal/src/timer/mod.rs index de0c4e4da..e9c02ac10 100644 --- a/esp-hal/src/timer/mod.rs +++ b/esp-hal/src/timer/mod.rs @@ -370,12 +370,9 @@ enum AnyTimerInner { /// Timer 1 of the TIMG1 peripheral in blocking mode. #[cfg(all(timg1, timg_timer1))] Timg1Timer1(timg::Timer, Blocking>), - /// Systimer Alarm in periodic mode with blocking behavior. + /// Systimer Alarm #[cfg(systimer)] - SystimerAlarmPeriodic(systimer::Alarm<'static, systimer::Periodic, Blocking>), - /// Systimer Target in periodic mode with blocking behavior. - #[cfg(systimer)] - SystimerAlarmTarget(systimer::Alarm<'static, systimer::Target, Blocking>), + SystimerAlarm(systimer::Alarm), } /// A type-erased timer @@ -413,16 +410,9 @@ impl From, Blocking>> for An } #[cfg(systimer)] -impl From> for AnyTimer { - fn from(value: systimer::Alarm<'static, systimer::Periodic, Blocking>) -> Self { - Self(AnyTimerInner::SystimerAlarmPeriodic(value)) - } -} - -#[cfg(systimer)] -impl From> for AnyTimer { - fn from(value: systimer::Alarm<'static, systimer::Target, Blocking>) -> Self { - Self(AnyTimerInner::SystimerAlarmTarget(value)) +impl From for AnyTimer { + fn from(value: systimer::Alarm) -> Self { + Self(AnyTimerInner::SystimerAlarm(value)) } } @@ -437,9 +427,7 @@ impl Timer for AnyTimer { #[cfg(all(timg1,timg_timer1))] AnyTimerInner::Timg1Timer1(inner) => inner, #[cfg(systimer)] - AnyTimerInner::SystimerAlarmPeriodic(inner) => inner, - #[cfg(systimer)] - AnyTimerInner::SystimerAlarmTarget(inner) => inner, + AnyTimerInner::SystimerAlarm(inner) => inner, } { fn start(&self); fn stop(&self); diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index d64050204..bf96d8f3e 100644 --- a/esp-hal/src/timer/systimer.rs +++ b/esp-hal/src/timer/systimer.rs @@ -9,72 +9,17 @@ //! //! ## Configuration //! -//! The timer consists of two counters, `UNIT0` and `UNIT1`. The counter values -//! can be monitored by 3 comparators, `COMP0`, `COMP1`, and `COMP2`. +//! The timer consists of two counters, `Unit0` and `Unit1`. The counter values +//! can be monitored by 3 [`Alarm`]s //! -//! [Alarm]s can be configured in two modes: [Target] (one-shot) and [Periodic]. -//! -//! ## Examples -//! -//! ### Splitting up the System Timer into three alarms -//! -//! Use the [split][SystemTimer::split] method to create three alarms from the -//! System Timer, contained in a [SysTimerAlarms] struct. -//! -//! ```rust, no_run -#![doc = crate::before_snippet!()] -//! use esp_hal::timer::systimer::{ -//! SystemTimer, -//! Periodic, -//! }; -//! -//! let systimer = SystemTimer::new( -//! peripherals.SYSTIMER, -//! ).split::(); -//! -//! // Reconfigure a periodic alarm to be a target alarm -//! let target_alarm = systimer.alarm0.into_target(); -//! # } -//! ``` -//! -//! ### General-purpose Timer -//! ```rust, no_run -#![doc = crate::before_snippet!()] -//! use esp_hal::timer::systimer::{ -//! Alarm, -//! FrozenUnit, -//! SpecificUnit, -//! SystemTimer, -//! }; -//! -//! let mut systimer = SystemTimer::new(peripherals.SYSTIMER); -//! -//! // Get the current tick count: -//! let now = SystemTimer::now(); -//! -//! let frozen_unit = FrozenUnit::new(&mut systimer.unit0); -//! let alarm0 = Alarm::new(systimer.comparator0, &frozen_unit); -//! -//! alarm0.set_target( -//! SystemTimer::now() + SystemTimer::ticks_per_second() * 2 -//! ); -//! alarm0.enable_interrupt(true); -//! -//! while !alarm0.is_interrupt_set() { -//! // Wait for the interrupt to be set -//! } -//! -//! alarm0.clear_interrupt(); -//! # } -//! ``` +//! It is recommended to pass the [`Alarm`]s into a high level driver like +//! [`OneShotTimer`](super::OneShotTimer) and +//! [`PeriodicTimer`](super::PeriodicTimer). Using the System timer directly is +//! only possible through the low level [`Timer`](crate::timer::Timer) trait. -use core::{ - fmt::{Debug, Formatter}, - marker::PhantomData, - ptr::addr_of_mut, -}; +use core::fmt::Debug; -use fugit::{Instant, MicrosDurationU32, MicrosDurationU64}; +use fugit::{Instant, MicrosDurationU64}; use super::{Error, Timer as _}; use crate::{ @@ -83,33 +28,35 @@ use crate::{ peripherals::{Interrupt, SYSTIMER}, sync::{lock, Lock}, system::{Peripheral as PeripheralEnable, PeripheralClockControl}, - Async, - Blocking, Cpu, - InterruptConfigurable, - Mode, }; -/// System Timer driver. -pub struct SystemTimer<'d> { - /// Unit 0 - pub unit0: SpecificUnit<'d, 0>, +/// The configuration of a unit. +#[derive(Copy, Clone)] +pub enum UnitConfig { + /// Unit is not counting. + Disabled, - #[cfg(not(esp32s2))] - /// Unit 1 - pub unit1: SpecificUnit<'d, 1>, + /// Unit is counting unless the Cpu is stalled. + DisabledIfCpuIsStalled(Cpu), - /// Comparator 0. - pub comparator0: SpecificComparator<'d, 0>, - - /// Comparator 1. - pub comparator1: SpecificComparator<'d, 1>, - - /// Comparator 2. - pub comparator2: SpecificComparator<'d, 2>, + /// Unit is counting. + Enabled, } -impl<'d> SystemTimer<'d> { +/// System Timer driver. +pub struct SystemTimer { + /// Alarm 0. + pub alarm0: Alarm, + + /// Alarm 1. + pub alarm1: Alarm, + + /// Alarm 2. + pub alarm2: Alarm, +} + +impl SystemTimer { cfg_if::cfg_if! { if #[cfg(esp32s2)] { /// Bitmask to be applied to the raw register value. @@ -146,7 +93,7 @@ impl<'d> SystemTimer<'d> { } /// Create a new instance. - pub fn new(_systimer: impl Peripheral

+ 'd) -> Self { + pub fn new(_systimer: SYSTIMER) -> Self { // Don't reset Systimer as it will break `time::now`, only enable it PeripheralClockControl::enable(PeripheralEnable::Systimer); @@ -154,67 +101,49 @@ impl<'d> SystemTimer<'d> { etm::enable_etm(); Self { - unit0: SpecificUnit::new(), - #[cfg(not(esp32s2))] - unit1: SpecificUnit::new(), - comparator0: SpecificComparator::new(), - comparator1: SpecificComparator::new(), - comparator2: SpecificComparator::new(), + alarm0: Alarm::new(0), + alarm1: Alarm::new(1), + alarm2: Alarm::new(2), } } - /// Get the current count of Unit 0 in the System Timer. - pub fn now() -> u64 { + /// Get the current count of the given unit in the System Timer. + pub fn unit_value(unit: Unit) -> u64 { // This should be safe to access from multiple contexts // worst case scenario the second accessor ends up reading // an older time stamp - let unit = unsafe { SpecificUnit::<'_, 0>::conjure() }; unit.read_count() } -} -impl SystemTimer<'static> { - /// Split the System Timer into three alarms. + #[cfg(not(esp32s2))] + /// Configures when this counter can run. + /// It can be configured to stall or continue running when CPU stalls + /// or enters on-chip-debugging mode. /// - /// This is a convenience method to create `'static` alarms of the same - /// type. You are encouraged to use [Alarm::new] over this very specific - /// helper. - pub fn split(self) -> SysTimerAlarms { - static mut UNIT0: Option> = None; - let unit0 = unsafe { &mut *addr_of_mut!(UNIT0) }; - - let unit0 = unit0.insert(self.unit0.into()); - let unit = FrozenUnit::new(unit0); - - SysTimerAlarms { - alarm0: Alarm::new(self.comparator0.into(), &unit), - alarm1: Alarm::new(self.comparator1.into(), &unit), - alarm2: Alarm::new(self.comparator2.into(), &unit), - #[cfg(not(esp32s2))] - unit1: self.unit1, - } + /// # Safety + /// + /// - Disabling a `Unit` whilst [`Alarm`]s are using it will affect the + /// [`Alarm`]s operation. + /// - Disabling Unit0 will affect [`now`](crate::time::now). + pub unsafe fn configure_unit(unit: Unit, config: UnitConfig) { + unit.configure(config) } - /// Split the System Timer into three alarms. + /// Set the value of the counter immediately. If the unit is at work, + /// the counter will continue to count up from the new reloaded value. /// - /// This is a convenience method to create `'static` alarms of the same - /// type. You are encouraged to use [Alarm::new_async] over this very - /// specific helper. - pub fn split_async(self) -> SysTimerAlarms { - static mut UNIT0: Option> = None; - let unit0 = unsafe { &mut *addr_of_mut!(UNIT0) }; - - let unit0 = unit0.insert(self.unit0.into()); - let unit = FrozenUnit::new(unit0); - - SysTimerAlarms { - alarm0: Alarm::new_async(self.comparator0.into(), &unit), - alarm1: Alarm::new_async(self.comparator1.into(), &unit), - alarm2: Alarm::new_async(self.comparator2.into(), &unit), - #[cfg(not(esp32s2))] - unit1: self.unit1, - } + /// This can be used to load back the sleep time recorded by RTC timer + /// via software after Light-sleep + /// + /// # Safety + /// + /// - Modifying a unit's count whilst [`Alarm`]s are using it may cause + /// unexpected behaviour + /// - Any modification of the unit0 count will affect + /// [`now`](crate::time::now). + pub unsafe fn set_unit_value(unit: Unit, value: u64) { + unit.set_count(value) } } @@ -222,14 +151,22 @@ impl SystemTimer<'static> { #[cfg_attr(esp32s2, doc = "64-bit")] #[cfg_attr(not(esp32s2), doc = "52-bit")] /// counter. -pub trait Unit { - /// Returns the unit number. - fn channel(&self) -> u8; +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Unit { + /// Unit 0 + Unit0 = 0, + #[cfg(not(esp32s2))] + /// Unit 1 + Unit1 = 1, +} + +impl Unit { + #[inline] + fn channel(&self) -> u8 { + *self as _ + } #[cfg(not(esp32s2))] - /// Configures when this counter can run. - /// It can be configured to stall or continue running when CPU stalls - /// or enters on-chip-debugging mode fn configure(&self, config: UnitConfig) { let systimer = unsafe { &*SYSTIMER::ptr() }; let conf = systimer.conf(); @@ -271,11 +208,6 @@ pub trait Unit { }); } - /// Set the value of the counter immediately. If the unit is at work, - /// the counter will continue to count up from the new reloaded value. - /// - /// This can be used to load back the sleep time recorded by RTC timer - /// via software after Light-sleep fn set_count(&self, value: u64) { let systimer = unsafe { &*SYSTIMER::ptr() }; #[cfg(not(esp32s2))] @@ -303,7 +235,6 @@ pub trait Unit { } } - /// Reads the current counter value. fn read_count(&self) -> u64 { // This can be a shared reference as long as this type isn't Sync. @@ -332,54 +263,26 @@ pub trait Unit { } } -/// A specific [Unit]. i.e. Either unit 0 or unit 1. +/// An alarm unit #[derive(Debug)] -pub struct SpecificUnit<'d, const CHANNEL: u8>(PhantomData<&'d ()>); - -impl SpecificUnit<'_, CHANNEL> { - fn new() -> Self { - Self(PhantomData) - } +pub struct Alarm { + comp: u8, + unit: Unit, } -impl Unit for SpecificUnit<'_, CHANNEL> { - fn channel(&self) -> u8 { - CHANNEL - } -} - -/// Any [Unit]. Could be either unit 0 or unit 1. -#[derive(Debug)] -pub struct AnyUnit<'d>(PhantomData<&'d ()>, u8); - -impl Unit for AnyUnit<'_> { - fn channel(&self) -> u8 { - self.1 - } -} - -impl<'d, const CHANNEL: u8> From> for AnyUnit<'d> { - fn from(_value: SpecificUnit<'d, CHANNEL>) -> Self { - Self(PhantomData, CHANNEL) - } -} - -impl<'d, const CHANNEL: u8> TryFrom> for SpecificUnit<'d, CHANNEL> { - type Error = u8; - - fn try_from(value: AnyUnit<'d>) -> Result { - if value.1 == CHANNEL { - Ok(SpecificUnit::new()) - } else { - Err(value.1) +impl Alarm { + const fn new(comp: u8) -> Self { + Alarm { + comp, + unit: Unit::Unit0, } } -} -/// A comparator that can generate alarms/interrupts based on values of a unit. -pub trait Comparator { - /// Returns the comparators number. - fn channel(&self) -> u8; + /// Returns the comparator's number. + #[inline] + fn channel(&self) -> u8 { + self.comp + } /// Enables/disables the comparator. If enabled, this means /// it will generate interrupt based on its configuration. @@ -431,12 +334,12 @@ pub trait Comparator { /// Sets the unit this comparator uses as a reference count. #[cfg(not(esp32s2))] - fn set_unit(&self, is_unit0: bool) { + pub fn set_unit(&self, unit: Unit) { let tconf = unsafe { let systimer = &*SYSTIMER::ptr(); systimer.target_conf(self.channel() as usize) }; - tconf.modify(|_, w| w.timer_unit_sel().bit(is_unit0)); + tconf.modify(|_, w| w.timer_unit_sel().bit(matches!(unit, Unit::Unit1))); } /// Set the mode of the comparator to be either target or periodic. @@ -496,18 +399,6 @@ pub trait Comparator { } } - /// Get the actual target value of the comparator. - fn actual_target(&self) -> u64 { - let target = unsafe { - let systimer = &*SYSTIMER::ptr(); - systimer.trgt(self.channel() as usize) - }; - let hi = target.hi().read().hi().bits(); - let lo = target.lo().read().lo().bits(); - - ((hi as u64) << 32) | (lo as u64) - } - /// Set the interrupt handler for this comparator. fn set_interrupt_handler(&self, handler: InterruptHandler) { let interrupt = match self.channel() { @@ -566,66 +457,9 @@ pub trait Comparator { } } -/// A specific [Comparator]. i.e. Either comparator 0, comparator 1, etc. -#[derive(Debug)] -pub struct SpecificComparator<'d, const CHANNEL: u8>(PhantomData<&'d ()>); - -impl SpecificComparator<'_, CHANNEL> { - fn new() -> Self { - Self(PhantomData) - } -} - -impl Comparator for SpecificComparator<'_, CHANNEL> { - fn channel(&self) -> u8 { - CHANNEL - } -} - -/// Any [Comparator]. Could be either comparator 0, comparator 1, etc. -#[derive(Debug)] -pub struct AnyComparator<'d>(PhantomData<&'d ()>, u8); - -impl Comparator for AnyComparator<'_> { - fn channel(&self) -> u8 { - self.1 - } -} - -impl<'d, const CHANNEL: u8> From> for AnyComparator<'d> { - fn from(_value: SpecificComparator<'d, CHANNEL>) -> Self { - Self(PhantomData, CHANNEL) - } -} - -impl<'d, const CHANNEL: u8> TryFrom> for SpecificComparator<'d, CHANNEL> { - type Error = u8; - - fn try_from(value: AnyComparator<'d>) -> Result { - if value.1 == CHANNEL { - Ok(SpecificComparator::new()) - } else { - Err(value.1) - } - } -} - -/// The configuration of a unit. -#[derive(Copy, Clone)] -pub enum UnitConfig { - /// Unit is not counting. - Disabled, - - /// Unit is counting unless the Cpu is stalled. - DisabledIfCpuIsStalled(Cpu), - - /// Unit is counting. - Enabled, -} - /// The modes of a comparator. #[derive(Copy, Clone)] -pub enum ComparatorMode { +enum ComparatorMode { /// The comparator will generate interrupts periodically. Period, @@ -634,208 +468,13 @@ pub enum ComparatorMode { Target, } -impl SpecificUnit<'static, 0> { - /// Conjure a system timer unit out of thin air. - /// - /// # Safety - /// - /// Users must take care to ensure that only one reference to the unit is - /// in scope at any given time. - pub const unsafe fn conjure() -> Self { - Self(PhantomData) - } -} - -#[cfg(not(esp32s2))] -impl SpecificUnit<'static, 1> { - /// Conjure a system timer unit out of thin air. - /// - /// # Safety - /// - /// Users must take care to ensure that only one reference to the unit is - /// in scope at any given time. - pub const unsafe fn conjure() -> Self { - Self(PhantomData) - } -} - -/// A unit whose value cannot be updated. -pub struct FrozenUnit<'d, U: Unit>(&'d U); - -impl<'d, U: Unit> FrozenUnit<'d, U> { - /// Creates a frozen unit. You will no longer be allowed - /// direct access to this unit until all the alarms created - /// from the unit are dropped. - pub fn new(unit: &'d mut U) -> Self { - Self(unit) - } - - fn borrow(&self) -> &'d U { - self.0 - } -} - -/// Alarms created from the System Timer peripheral. -pub struct SysTimerAlarms { - /// Alarm 0 - pub alarm0: Alarm<'static, MODE, DM>, - /// Alarm 1 - pub alarm1: Alarm<'static, MODE, DM>, - /// Alarm 2 - pub alarm2: Alarm<'static, MODE, DM>, - - /// Unit 1 - /// - /// Leftover unit which wasn't used to create the three alarms. - #[cfg(not(esp32s2))] - pub unit1: SpecificUnit<'static, 1>, -} - -/// A marker for a [Alarm] in target mode. -#[derive(Debug)] -pub struct Target; - -/// A marker for a [Alarm] in periodic mode. -#[derive(Debug)] -pub struct Periodic; - -/// A single alarm. -pub struct Alarm<'d, MODE, DM, COMP = AnyComparator<'d>, UNIT = AnyUnit<'d>> -where - DM: Mode, -{ - comparator: COMP, - unit: &'d UNIT, - _pd: PhantomData<(MODE, DM)>, -} - -impl Debug for Alarm<'_, T, DM, COMP, UNIT> -where - DM: Mode, -{ - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - f.debug_struct("Alarm") - .field("comparator", &self.comparator.channel()) - .field("unit", &self.unit.channel()) - .finish() - } -} - -impl<'d, T, COMP: Comparator, UNIT: Unit> Alarm<'d, T, Blocking, COMP, UNIT> { - /// Creates a new alarm from a comparator and unit, in blocking mode. - pub fn new(comparator: COMP, unit: &FrozenUnit<'d, UNIT>) -> Self { - Self { - comparator, - unit: unit.borrow(), - _pd: PhantomData, - } - } -} - -impl<'d, T, COMP: Comparator, UNIT: Unit> Alarm<'d, T, Async, COMP, UNIT> { - /// Creates a new alarm from a comparator and unit, in async mode. - pub fn new_async(comparator: COMP, unit: &FrozenUnit<'d, UNIT>) -> Self { - Self { - comparator, - unit: unit.0, - _pd: PhantomData, - } - } -} - -impl InterruptConfigurable for Alarm<'_, T, Blocking, COMP, UNIT> { - fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - self.comparator.set_interrupt_handler(handler) - } -} - -impl<'d, DM, COMP: Comparator, UNIT: Unit> Alarm<'d, Target, DM, COMP, UNIT> -where - DM: Mode, -{ - /// Set the target value of this [Alarm] - pub fn set_target(&self, timestamp: u64) { - #[cfg(esp32s2)] - unsafe { - let systimer = &*SYSTIMER::ptr(); - // run at XTAL freq, not 80 * XTAL freq - systimer.step().write(|w| w.xtal_step().bits(0x1)); - } - - self.comparator.set_mode(ComparatorMode::Target); - self.comparator.set_target(timestamp); - self.comparator.set_enable(true); - } - - /// Block waiting until the timer reaches the `timestamp` - pub fn wait_until(&self, timestamp: u64) { - self.clear_interrupt(); - self.set_target(timestamp); - - let r = unsafe { &*crate::peripherals::SYSTIMER::PTR }.int_raw(); - loop { - if r.read().target(self.comparator.channel()).bit_is_set() { - break; - } - } - } - - /// Converts this [Alarm] into [Periodic] mode - pub fn into_periodic(self) -> Alarm<'d, Periodic, DM, COMP, UNIT> { - Alarm { - comparator: self.comparator, - unit: self.unit, - _pd: PhantomData, - } - } -} - -impl<'d, DM, COMP: Comparator, UNIT: Unit> Alarm<'d, Periodic, DM, COMP, UNIT> -where - DM: Mode, -{ - /// Set the period of this [Alarm] - pub fn set_period(&self, period: MicrosDurationU32) { - #[cfg(esp32s2)] - unsafe { - let systimer = &*SYSTIMER::ptr(); - // run at XTAL freq, not 80 * XTAL freq - systimer.step().write(|w| w.xtal_step().bits(0x1)); - } - - let us = period.ticks(); - let ticks = us * (SystemTimer::ticks_per_second() / 1_000_000) as u32; - - self.comparator.set_mode(ComparatorMode::Period); - self.comparator.set_period(ticks); - self.comparator.set_enable(true); - } - - /// Converts this [Alarm] into [Target] mode - pub fn into_target(self) -> Alarm<'d, Target, DM, COMP, UNIT> { - Alarm { - comparator: self.comparator, - unit: self.unit, - _pd: PhantomData, - } - } -} - -impl crate::private::Sealed for Alarm<'_, T, DM, COMP, UNIT> where - DM: Mode -{ -} - -impl super::Timer for Alarm<'_, T, DM, COMP, UNIT> -where - DM: Mode, -{ +impl super::Timer for Alarm { fn start(&self) { - self.comparator.set_enable(true); + self.set_enable(true); } fn stop(&self) { - self.comparator.set_enable(false); + self.set_enable(false); } fn reset(&self) { @@ -856,7 +495,7 @@ where } fn is_running(&self) -> bool { - self.comparator.is_enabled() + self.is_enabled() } fn now(&self) -> Instant { @@ -871,7 +510,7 @@ where } fn load_value(&self, value: MicrosDurationU64) -> Result<(), Error> { - let mode = self.comparator.mode(); + let mode = self.mode(); let us = value.ticks(); let ticks = us * (SystemTimer::ticks_per_second() / 1_000_000); @@ -886,12 +525,12 @@ where return Err(Error::InvalidTimeout); } - self.comparator.set_period(ticks as u32); + self.set_period(ticks as u32); // Clear and then set SYSTIMER_TARGETx_PERIOD_MODE to configure COMPx into // period mode - self.comparator.set_mode(ComparatorMode::Target); - self.comparator.set_mode(ComparatorMode::Period); + self.set_mode(ComparatorMode::Target); + self.set_mode(ComparatorMode::Period); } else { // Target mode @@ -906,7 +545,7 @@ where let v = self.unit.read_count(); let t = v + ticks; - self.comparator.set_target(t); + self.set_target(t); } Ok(()) @@ -919,28 +558,28 @@ where } else { ComparatorMode::Target }; - self.comparator.set_mode(mode) + self.set_mode(mode) } fn enable_interrupt(&self, state: bool) { lock(&INT_ENA_LOCK, || { unsafe { &*SYSTIMER::PTR } .int_ena() - .modify(|_, w| w.target(self.comparator.channel()).bit(state)); + .modify(|_, w| w.target(self.channel()).bit(state)); }); } fn clear_interrupt(&self) { unsafe { &*SYSTIMER::PTR } .int_clr() - .write(|w| w.target(self.comparator.channel()).clear_bit_by_one()); + .write(|w| w.target(self.channel()).clear_bit_by_one()); } fn is_interrupt_set(&self) -> bool { unsafe { &*SYSTIMER::PTR } .int_raw() .read() - .target(self.comparator.channel()) + .target(self.channel()) .bit_is_set() } @@ -949,27 +588,30 @@ where } fn set_interrupt_handler(&self, handler: InterruptHandler) { - self.comparator.set_interrupt_handler(handler); + self.set_interrupt_handler(handler); } } -impl Peripheral for Alarm<'_, T, DM, COMP, UNIT> -where - DM: Mode, -{ +impl Peripheral for Alarm { type P = Self; #[inline] unsafe fn clone_unchecked(&self) -> Self::P { - core::ptr::read(self as *const _) + Alarm { + comp: self.comp, + unit: self.unit, + } } } +impl crate::private::Sealed for Alarm {} + static CONF_LOCK: Lock = Lock::new(); static INT_ENA_LOCK: Lock = Lock::new(); // Async functionality of the system timer. mod asynch { + #![allow(unused)] // FIXME (mabez) use core::{ pin::Pin, task::{Context, Poll}, @@ -985,15 +627,15 @@ mod asynch { static WAKERS: [AtomicWaker; NUM_ALARMS] = [const { AtomicWaker::new() }; NUM_ALARMS]; #[must_use = "futures do nothing unless you `.await` or poll them"] - pub(crate) struct AlarmFuture<'a, COMP: Comparator, UNIT: Unit> { - alarm: &'a Alarm<'a, Target, crate::Async, COMP, UNIT>, + pub(crate) struct AlarmFuture<'a> { + alarm: &'a Alarm, } - impl<'a, COMP: Comparator, UNIT: Unit> AlarmFuture<'a, COMP, UNIT> { - pub(crate) fn new(alarm: &'a Alarm<'a, Target, crate::Async, COMP, UNIT>) -> Self { + impl<'a> AlarmFuture<'a> { + pub(crate) fn new(alarm: &'a Alarm) -> Self { alarm.clear_interrupt(); - let (interrupt, handler) = match alarm.comparator.channel() { + let (interrupt, handler) = match alarm.channel() { 0 => (Interrupt::SYSTIMER_TARGET0, target0_handler), 1 => (Interrupt::SYSTIMER_TARGET1, target1_handler), _ => (Interrupt::SYSTIMER_TARGET2, target2_handler), @@ -1015,16 +657,16 @@ mod asynch { unsafe { &*crate::peripherals::SYSTIMER::PTR } .int_ena() .read() - .target(self.alarm.comparator.channel()) + .target(self.alarm.channel()) .bit_is_clear() } } - impl core::future::Future for AlarmFuture<'_, COMP, UNIT> { + impl core::future::Future for AlarmFuture<'_> { type Output = (); fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll { - WAKERS[self.alarm.comparator.channel() as usize].register(ctx.waker()); + WAKERS[self.alarm.channel() as usize].register(ctx.waker()); if self.event_bit_is_clear() { Poll::Ready(()) @@ -1034,27 +676,8 @@ mod asynch { } } - impl embedded_hal_async::delay::DelayNs - for Alarm<'_, Target, crate::Async, COMP, UNIT> - { - async fn delay_ns(&mut self, nanos: u32) { - self.set_target( - self.unit.read_count() - + (nanos as u64 * SystemTimer::ticks_per_second()).div_ceil(1_000_000_000), - ); - - AlarmFuture::new(self).await; - } - - async fn delay_ms(&mut self, ms: u32) { - for _ in 0..ms { - self.delay_us(1000).await; - } - } - } - #[handler] - fn target0_handler() { + pub(crate) fn target0_handler() { lock(&INT_ENA_LOCK, || { unsafe { &*crate::peripherals::SYSTIMER::PTR } .int_ena() @@ -1065,7 +688,7 @@ mod asynch { } #[handler] - fn target1_handler() { + pub(crate) fn target1_handler() { lock(&INT_ENA_LOCK, || { unsafe { &*crate::peripherals::SYSTIMER::PTR } .int_ena() @@ -1076,7 +699,7 @@ mod asynch { } #[handler] - fn target2_handler() { + pub(crate) fn target2_handler() { lock(&INT_ENA_LOCK, || { unsafe { &*crate::peripherals::SYSTIMER::PTR } .int_ena() @@ -1100,51 +723,33 @@ pub mod etm { //! The system timer can generate the following ETM events: //! - SYSTIMER_EVT_CNT_CMPx: Indicates the alarm pulses generated by //! COMPx - //! - //! ## Example - //! ```rust, no_run - #![doc = crate::before_snippet!()] - //! # use esp_hal::timer::systimer::{etm::Event, SystemTimer}; - //! # use fugit::ExtU32; - //! let syst = SystemTimer::new(peripherals.SYSTIMER); - //! let syst_alarms = syst.split(); - //! let mut alarm0 = syst_alarms.alarm0.into_periodic(); - //! alarm0.set_period(1u32.secs()); - //! - //! let timer_event = Event::new(&mut alarm0); - //! # } - //! ``` + // FIXME(mabez) use super::*; /// An ETM controlled SYSTIMER event - pub struct Event<'a, 'd, M, DM: crate::Mode, COMP, UNIT> { - alarm: &'a mut Alarm<'d, M, DM, COMP, UNIT>, + pub struct Event<'a> { + alarm: &'a mut Alarm, } - impl<'a, 'd, M, DM: crate::Mode, COMP: Comparator, UNIT: Unit> Event<'a, 'd, M, DM, COMP, UNIT> { + impl<'a> Event<'a> { /// Creates an ETM event from the given [Alarm] - pub fn new(alarm: &'a mut Alarm<'d, M, DM, COMP, UNIT>) -> Self { + pub fn new(alarm: &'a mut Alarm) -> Self { Self { alarm } } /// Execute closure f with mutable access to the wrapped [Alarm]. - pub fn with(&self, f: impl FnOnce(&&'a mut Alarm<'d, M, DM, COMP, UNIT>) -> R) -> R { + pub fn with(&self, f: impl FnOnce(&&'a mut Alarm) -> R) -> R { let alarm = &self.alarm; f(alarm) } } - impl crate::private::Sealed - for Event<'_, '_, M, DM, COMP, UNIT> - { - } + impl crate::private::Sealed for Event<'_> {} - impl crate::etm::EtmEvent - for Event<'_, '_, M, DM, COMP, UNIT> - { + impl crate::etm::EtmEvent for Event<'_> { fn id(&self) -> u8 { - 50 + self.alarm.comparator.channel() + 50 + self.alarm.channel() } } diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index 71699066f..c38399c8e 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -293,12 +293,7 @@ where } #[cfg(not(feature = "esp32"))] -impl IntoAnyTimer for Alarm<'_, T, DM, COMP, UNIT> -where - DM: esp_hal::Mode, - Self: Into, -{ -} +impl IntoAnyTimer for Alarm where Self: Into {} impl private::Sealed for AnyTimer {} impl IntoAnyTimer for AnyTimer {} @@ -326,12 +321,7 @@ where { } #[cfg(not(feature = "esp32"))] -impl private::Sealed for Alarm<'_, T, DM, COMP, UNIT> -where - DM: esp_hal::Mode, - Self: Into, -{ -} +impl private::Sealed for Alarm where Self: Into {} /// A marker trait for suitable Rng sources for esp-wifi pub trait EspWifiRngSource: rand_core::RngCore + private::Sealed {} diff --git a/examples/src/bin/embassy_multiprio.rs b/examples/src/bin/embassy_multiprio.rs index 2a4f5de8a..bbb9778b9 100644 --- a/examples/src/bin/embassy_multiprio.rs +++ b/examples/src/bin/embassy_multiprio.rs @@ -80,8 +80,8 @@ async fn main(low_prio_spawner: Spawner) { cfg_if::cfg_if! { if #[cfg(feature = "esp32c2")] { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); let timer1: AnyTimer = systimer.alarm0.into(); } else { let timg1 = TimerGroup::new(peripherals.TIMG1); diff --git a/examples/src/bin/embassy_parl_io_rx.rs b/examples/src/bin/embassy_parl_io_rx.rs index 5117252fa..511e356e0 100644 --- a/examples/src/bin/embassy_parl_io_rx.rs +++ b/examples/src/bin/embassy_parl_io_rx.rs @@ -19,7 +19,7 @@ use esp_hal::{ gpio::NoPin, parl_io::{BitPackOrder, ParlIoRxOnly, RxFourBits}, prelude::*, - timer::systimer::{SystemTimer, Target}, + timer::systimer::SystemTimer, }; use esp_println::println; @@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) { esp_println::println!("Init!"); let peripherals = esp_hal::init(esp_hal::Config::default()); - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); let (rx_buffer, rx_descriptors, _, _) = dma_buffers!(32000, 0); diff --git a/examples/src/bin/embassy_parl_io_tx.rs b/examples/src/bin/embassy_parl_io_tx.rs index ca5c3a2aa..28cd2cdd1 100644 --- a/examples/src/bin/embassy_parl_io_tx.rs +++ b/examples/src/bin/embassy_parl_io_tx.rs @@ -29,7 +29,7 @@ use esp_hal::{ TxPinConfigWithValidPin, }, prelude::*, - timer::systimer::{SystemTimer, Target}, + timer::systimer::SystemTimer, }; use esp_println::println; @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { esp_println::println!("Init!"); let peripherals = esp_hal::init(esp_hal::Config::default()); - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 32000); diff --git a/examples/src/bin/etm_blinky_systimer.rs b/examples/src/bin/etm_blinky_systimer.rs deleted file mode 100644 index 1cdb361e2..000000000 --- a/examples/src/bin/etm_blinky_systimer.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! Control LED by the systimer via ETM without involving the CPU. - -//! The following wiring is assumed: -//! - LED => GPIO1 - -//% CHIPS: esp32c6 esp32h2 - -#![no_std] -#![no_main] - -use esp_backtrace as _; -use esp_hal::{ - etm::Etm, - gpio::{ - etm::{Channels, OutputConfig}, - Level, - Pull, - }, - prelude::*, - timer::systimer::{etm::Event, Periodic, SystemTimer}, -}; -use fugit::ExtU32; - -#[entry] -fn main() -> ! { - let peripherals = esp_hal::init(esp_hal::Config::default()); - - let syst = SystemTimer::new(peripherals.SYSTIMER); - let syst_alarms = syst.split::(); - let mut alarm0 = syst_alarms.alarm0; - alarm0.set_period(1u32.secs()); - - let mut led = peripherals.GPIO1; - - // setup ETM - let gpio_ext = Channels::new(peripherals.GPIO_SD); - let led_task = gpio_ext.channel0_task.toggle( - &mut led, - OutputConfig { - open_drain: false, - pull: Pull::None, - initial_state: Level::High, - }, - ); - - let timer_event = Event::new(&mut alarm0); - - let etm = Etm::new(peripherals.SOC_ETM); - let channel0 = etm.channel0; - - // make sure the configured channel doesn't get dropped - dropping it will - // disable the channel - let _configured_channel = channel0.setup(&timer_event, &led_task); - - // the LED is controlled by the timer without involving the CPU - loop {} -} diff --git a/examples/src/bin/hmac.rs b/examples/src/bin/hmac.rs index 87b5118c1..ee605325c 100644 --- a/examples/src/bin/hmac.rs +++ b/examples/src/bin/hmac.rs @@ -62,7 +62,6 @@ use esp_hal::{ hmac::{Hmac, HmacPurpose, KeyId}, prelude::*, rng::Rng, - timer::systimer::SystemTimer, }; use esp_println::println; use hmac::{Hmac as HmacSw, Mac}; @@ -94,18 +93,18 @@ fn main() -> ! { let mut remaining = nsrc; hw_hmac.init(); block!(hw_hmac.configure(HmacPurpose::ToUser, KeyId::Key0)).expect("Key purpose mismatch"); - let pre_hw_hmac = SystemTimer::now(); + let pre_hw_hmac = esp_hal::time::now(); while remaining.len() > 0 { remaining = block!(hw_hmac.update(remaining)).unwrap(); } block!(hw_hmac.finalize(output.as_mut_slice())).unwrap(); - let post_hw_hmac = SystemTimer::now(); + let post_hw_hmac = esp_hal::time::now(); let hw_time = post_hw_hmac - pre_hw_hmac; let mut sw_hmac = HmacSha256::new_from_slice(key).expect("HMAC can take key of any size"); - let pre_sw_hash = SystemTimer::now(); + let pre_sw_hash = esp_hal::time::now(); sw_hmac.update(nsrc); let soft_result = sw_hmac.finalize().into_bytes(); - let post_sw_hash = SystemTimer::now(); + let post_sw_hash = esp_hal::time::now(); let soft_time = post_sw_hash - pre_sw_hash; for (a, b) in output.iter().zip(soft_result) { assert_eq!(*a, b); diff --git a/examples/src/bin/systimer.rs b/examples/src/bin/systimer.rs deleted file mode 100644 index e648e98d8..000000000 --- a/examples/src/bin/systimer.rs +++ /dev/null @@ -1,125 +0,0 @@ -//! This shows how to use the SYSTIMER peripheral including interrupts. -//! -//! It's an additional timer besides the TIMG peripherals. - -//% CHIPS: esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 - -#![no_std] -#![no_main] - -use core::cell::RefCell; - -use critical_section::Mutex; -use esp_backtrace as _; -use esp_hal::{ - delay::Delay, - prelude::*, - timer::systimer::{ - Alarm, - FrozenUnit, - Periodic, - SpecificComparator, - SpecificUnit, - SystemTimer, - Target, - }, - Blocking, -}; -use esp_println::println; -use fugit::ExtU32; -use static_cell::StaticCell; - -static ALARM0: Mutex< - RefCell< - Option, SpecificUnit<'static, 0>>>, - >, -> = Mutex::new(RefCell::new(None)); -static ALARM1: Mutex< - RefCell< - Option, SpecificUnit<'static, 0>>>, - >, -> = Mutex::new(RefCell::new(None)); -static ALARM2: Mutex< - RefCell< - Option, SpecificUnit<'static, 0>>>, - >, -> = Mutex::new(RefCell::new(None)); - -#[entry] -fn main() -> ! { - let peripherals = esp_hal::init(esp_hal::Config::default()); - - let systimer = SystemTimer::new(peripherals.SYSTIMER); - println!("SYSTIMER Current value = {}", SystemTimer::now()); - - static UNIT0: StaticCell> = StaticCell::new(); - - let unit0 = UNIT0.init(systimer.unit0); - - let frozen_unit = FrozenUnit::new(unit0); - - let alarm0 = Alarm::new(systimer.comparator0, &frozen_unit); - let alarm1 = Alarm::new(systimer.comparator1, &frozen_unit); - let alarm2 = Alarm::new(systimer.comparator2, &frozen_unit); - - critical_section::with(|cs| { - let alarm0 = alarm0.into_periodic(); - alarm0.set_interrupt_handler(systimer_target0); - alarm0.set_period(1u32.secs()); - alarm0.enable_interrupt(true); - - alarm1.set_interrupt_handler(systimer_target1); - alarm1.set_target(SystemTimer::now() + (SystemTimer::ticks_per_second() * 2)); - alarm1.enable_interrupt(true); - - alarm2.set_interrupt_handler(systimer_target2); - alarm2.set_target(SystemTimer::now() + (SystemTimer::ticks_per_second() * 3)); - alarm2.enable_interrupt(true); - - ALARM0.borrow_ref_mut(cs).replace(alarm0); - ALARM1.borrow_ref_mut(cs).replace(alarm1); - ALARM2.borrow_ref_mut(cs).replace(alarm2); - }); - - let delay = Delay::new(); - - loop { - delay.delay_millis(500); - } -} - -#[handler(priority = esp_hal::interrupt::Priority::min())] -fn systimer_target0() { - println!("Interrupt lvl1 (alarm0)"); - critical_section::with(|cs| { - ALARM0 - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); -} - -#[handler(priority = esp_hal::interrupt::Priority::Priority1)] -fn systimer_target1() { - println!("Interrupt lvl2 (alarm1)"); - critical_section::with(|cs| { - ALARM1 - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); -} - -#[handler(priority = esp_hal::interrupt::Priority::max())] -fn systimer_target2() { - println!("Interrupt lvl2 (alarm2)"); - critical_section::with(|cs| { - ALARM2 - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); -} diff --git a/examples/src/bin/wifi_embassy_access_point.rs b/examples/src/bin/wifi_embassy_access_point.rs index 6296dbc59..21704a3f3 100644 --- a/examples/src/bin/wifi_embassy_access_point.rs +++ b/examples/src/bin/wifi_embassy_access_point.rs @@ -86,8 +86,8 @@ async fn main(spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_access_point_with_sta.rs b/examples/src/bin/wifi_embassy_access_point_with_sta.rs index 15eea34e0..fd52e8328 100644 --- a/examples/src/bin/wifi_embassy_access_point_with_sta.rs +++ b/examples/src/bin/wifi_embassy_access_point_with_sta.rs @@ -94,8 +94,8 @@ async fn main(spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_bench.rs b/examples/src/bin/wifi_embassy_bench.rs index cb3b84365..30536e2a3 100644 --- a/examples/src/bin/wifi_embassy_bench.rs +++ b/examples/src/bin/wifi_embassy_bench.rs @@ -117,8 +117,8 @@ async fn main(spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_ble.rs b/examples/src/bin/wifi_embassy_ble.rs index 22ad06076..17d52f211 100644 --- a/examples/src/bin/wifi_embassy_ble.rs +++ b/examples/src/bin/wifi_embassy_ble.rs @@ -83,8 +83,8 @@ async fn main(_spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_dhcp.rs b/examples/src/bin/wifi_embassy_dhcp.rs index 2f896c422..2f514c352 100644 --- a/examples/src/bin/wifi_embassy_dhcp.rs +++ b/examples/src/bin/wifi_embassy_dhcp.rs @@ -79,8 +79,8 @@ async fn main(spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_esp_now.rs b/examples/src/bin/wifi_embassy_esp_now.rs index a99b3c74a..fc3b93022 100644 --- a/examples/src/bin/wifi_embassy_esp_now.rs +++ b/examples/src/bin/wifi_embassy_esp_now.rs @@ -65,8 +65,8 @@ async fn main(_spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_esp_now_duplex.rs b/examples/src/bin/wifi_embassy_esp_now_duplex.rs index f75d5d65e..8f0b3e646 100644 --- a/examples/src/bin/wifi_embassy_esp_now_duplex.rs +++ b/examples/src/bin/wifi_embassy_esp_now_duplex.rs @@ -65,8 +65,8 @@ async fn main(spawner: Spawner) -> ! { let timg1 = TimerGroup::new(peripherals.TIMG1); esp_hal_embassy::init(timg1.timer0); } else { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } } diff --git a/examples/src/bin/wifi_embassy_trouble.rs b/examples/src/bin/wifi_embassy_trouble.rs index a5f55a027..7f8af099b 100644 --- a/examples/src/bin/wifi_embassy_trouble.rs +++ b/examples/src/bin/wifi_embassy_trouble.rs @@ -72,8 +72,7 @@ async fn main(_s: Spawner) { #[cfg(not(feature = "esp32"))] { - let systimer = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER) - .split::(); + let systimer = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init(systimer.alarm0); } diff --git a/examples/src/lib.rs b/examples/src/lib.rs deleted file mode 100644 index d81eda6f5..000000000 --- a/examples/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![no_std] - -pub fn cycles() -> u64 { - #[cfg(feature = "esp32")] - { - esp_hal::xtensa_lx::timer::get_cycle_count() as u64 - } - - #[cfg(not(feature = "esp32"))] - { - esp_hal::timer::systimer::SystemTimer::now() - } -} diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml index 48565ad8d..e70b9021e 100644 --- a/hil-test/Cargo.toml +++ b/hil-test/Cargo.toml @@ -31,10 +31,6 @@ harness = false name = "delay" harness = false -[[test]] -name = "delay_async" -harness = false - [[test]] name = "dma_macros" harness = false @@ -111,10 +107,6 @@ harness = false name = "spi_slave" harness = false -[[test]] -name = "systimer" -harness = false - [[test]] name = "parl_io_tx" harness = false @@ -168,11 +160,6 @@ harness = false name = "uart_tx_rx_async" harness = false -[[test]] -name = "embassy_timers_executors" -harness = false -required-features = ["embassy"] - [[test]] name = "embassy_interrupt_executor" harness = false diff --git a/hil-test/tests/delay_async.rs b/hil-test/tests/delay_async.rs deleted file mode 100644 index 3afe7b325..000000000 --- a/hil-test/tests/delay_async.rs +++ /dev/null @@ -1,173 +0,0 @@ -//! Async Delay Test -//! -//! Specifically tests the various implementations of the -//! `embedded_hal_async::delay::DelayNs` trait. - -//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 - -#![no_std] -#![no_main] - -use embedded_hal_async::delay::DelayNs; -#[cfg(systimer)] -use esp_hal::timer::systimer::{Alarm, FrozenUnit, SystemTimer}; -use esp_hal::{peripherals::Peripherals, timer::timg::TimerGroup}; -use hil_test as _; - -struct Context { - peripherals: Peripherals, -} - -async fn test_async_delay_ns(mut timer: impl DelayNs, duration: u32) { - for _ in 1..5 { - let t1 = esp_hal::time::now(); - timer.delay_ns(duration).await; - let t2 = esp_hal::time::now(); - - assert!(t2 > t1); - assert!( - (t2 - t1).to_nanos() >= duration as u64, - "diff: {:?}", - (t2 - t1).to_nanos() - ); - } -} - -async fn test_async_delay_us(mut timer: impl DelayNs, duration: u32) { - for _ in 1..5 { - let t1 = esp_hal::time::now(); - timer.delay_us(duration).await; - let t2 = esp_hal::time::now(); - - assert!(t2 > t1); - assert!( - (t2 - t1).to_nanos() >= duration as u64, - "diff: {:?}", - (t2 - t1).to_nanos() - ); - } -} - -async fn test_async_delay_ms(mut timer: impl DelayNs, duration: u32) { - for _ in 1..5 { - let t1 = esp_hal::time::now(); - timer.delay_ms(duration).await; - let t2 = esp_hal::time::now(); - - assert!(t2 > t1); - assert!( - (t2 - t1).to_nanos() >= duration as u64, - "diff: {:?}", - (t2 - t1).to_nanos() - ); - } -} - -#[cfg(test)] -#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())] -mod tests { - use super::*; - - #[init] - fn init() -> Context { - Context { - peripherals: esp_hal::init(esp_hal::Config::default()), - } - } - - #[cfg(systimer)] - #[test] - #[timeout(2)] - async fn test_systimer_async_delay_ns(ctx: Context) { - let mut alarms = SystemTimer::new(ctx.peripherals.SYSTIMER); - let unit = FrozenUnit::new(&mut alarms.unit0); - let alarm0 = Alarm::new_async(alarms.comparator0, &unit); - - test_async_delay_ns(alarm0, 10_000_000).await; - } - - #[test] - #[timeout(2)] - async fn test_timg0_async_delay_ns(ctx: Context) { - let timg0 = TimerGroup::new_async(ctx.peripherals.TIMG0); - - test_async_delay_ns(timg0.timer0, 10_000_000).await; - #[cfg(timg_timer1)] - test_async_delay_ns(timg0.timer1, 10_000_000).await; - } - - #[cfg(timg1)] - #[test] - #[timeout(2)] - async fn test_timg1_async_delay_ns(ctx: Context) { - let timg1 = TimerGroup::new_async(ctx.peripherals.TIMG1); - - test_async_delay_ns(timg1.timer0, 10_000_000).await; - #[cfg(timg_timer1)] - test_async_delay_ns(timg1.timer1, 10_000_000).await; - } - - #[cfg(systimer)] - #[test] - #[timeout(2)] - async fn test_systimer_async_delay_us(ctx: Context) { - let mut alarms = SystemTimer::new(ctx.peripherals.SYSTIMER); - let unit = FrozenUnit::new(&mut alarms.unit0); - let alarm0 = Alarm::new_async(alarms.comparator0, &unit); - - test_async_delay_us(alarm0, 10_000).await; - } - - #[test] - #[timeout(2)] - async fn test_timg0_async_delay_us(ctx: Context) { - let timg0 = TimerGroup::new_async(ctx.peripherals.TIMG0); - - test_async_delay_us(timg0.timer0, 10_000).await; - #[cfg(timg_timer1)] - test_async_delay_us(timg0.timer1, 10_000).await; - } - - #[cfg(timg1)] - #[test] - #[timeout(2)] - async fn test_timg1_async_delay_us(ctx: Context) { - let timg1 = TimerGroup::new_async(ctx.peripherals.TIMG1); - - test_async_delay_us(timg1.timer0, 10_000).await; - #[cfg(timg_timer1)] - test_async_delay_us(timg1.timer1, 10_000).await; - } - - #[cfg(systimer)] - #[test] - #[timeout(2)] - async fn test_systimer_async_delay_ms(ctx: Context) { - let mut alarms = SystemTimer::new(ctx.peripherals.SYSTIMER); - let unit = FrozenUnit::new(&mut alarms.unit0); - let alarm0 = Alarm::new_async(alarms.comparator0, &unit); - - test_async_delay_ms(alarm0, 10).await; - } - - #[test] - #[timeout(2)] - async fn test_timg0_async_delay_ms(ctx: Context) { - let timg0 = TimerGroup::new_async(ctx.peripherals.TIMG0); - - test_async_delay_ms(timg0.timer0, 10).await; - #[cfg(timg_timer1)] - test_async_delay_ms(timg0.timer1, 10).await; - } - - #[cfg(timg1)] - #[test] - #[timeout(2)] - async fn test_timg1_async_delay_ms(ctx: Context) { - let timg1 = TimerGroup::new_async(ctx.peripherals.TIMG1); - - test_async_delay_ms(timg1.timer0, 10).await; - #[cfg(timg_timer1)] - test_async_delay_ms(timg1.timer1, 10).await; - } -} diff --git a/hil-test/tests/embassy_interrupt_executor.rs b/hil-test/tests/embassy_interrupt_executor.rs index c21fed86d..f4ddd521f 100644 --- a/hil-test/tests/embassy_interrupt_executor.rs +++ b/hil-test/tests/embassy_interrupt_executor.rs @@ -73,8 +73,8 @@ mod test { AnyTimer::from(timg1.timer0), ]); } else if #[cfg(systimer)] { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init([ AnyTimer::from(systimer.alarm0), AnyTimer::from(systimer.alarm1), diff --git a/hil-test/tests/embassy_interrupt_spi_dma.rs b/hil-test/tests/embassy_interrupt_spi_dma.rs index caf7b1b40..cc9121bff 100644 --- a/hil-test/tests/embassy_interrupt_spi_dma.rs +++ b/hil-test/tests/embassy_interrupt_spi_dma.rs @@ -87,8 +87,8 @@ mod test { cfg_if::cfg_if! { if #[cfg(systimer)] { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init([ AnyTimer::from(systimer.alarm0), AnyTimer::from(systimer.alarm1), @@ -257,8 +257,8 @@ mod test { cfg_if::cfg_if! { if #[cfg(systimer)] { - use esp_hal::timer::systimer::{SystemTimer, Target}; - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); + use esp_hal::timer::systimer::SystemTimer; + let systimer = SystemTimer::new(peripherals.SYSTIMER); esp_hal_embassy::init([ AnyTimer::from(systimer.alarm0), AnyTimer::from(systimer.alarm1), diff --git a/hil-test/tests/embassy_timers_executors.rs b/hil-test/tests/embassy_timers_executors.rs deleted file mode 100644 index 24cb26954..000000000 --- a/hil-test/tests/embassy_timers_executors.rs +++ /dev/null @@ -1,294 +0,0 @@ -//! Embassy timer and executor Test - -//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 -//% FEATURES: integrated-timers -//% FEATURES: generic-queue - -#![no_std] -#![no_main] - -use embassy_time::{Duration, Ticker, Timer}; -#[cfg(not(feature = "esp32"))] -use esp_hal::{ - interrupt::software::SoftwareInterruptControl, - interrupt::Priority, - timer::systimer::{Alarm, FrozenUnit, Periodic, SystemTimer, Target}, - timer::AnyTimer, -}; -use esp_hal::{ - peripherals::Peripherals, - prelude::*, - timer::{timg::TimerGroup, OneShotTimer, PeriodicTimer}, -}; -#[cfg(not(feature = "esp32"))] -use esp_hal_embassy::InterruptExecutor; -use hil_test as _; - -#[cfg(not(feature = "esp32"))] -macro_rules! mk_static { - ($t:ty,$val:expr) => {{ - static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); - #[deny(unused_attributes)] - let x = STATIC_CELL.uninit().write(($val)); - x - }}; -} - -// List of the functions that are ACTUALLY TESTS but are called in the invokers -mod test_helpers { - use super::*; - - #[embassy_executor::task] - pub async fn e_task30ms() { - Timer::after_millis(30).await; - } -} - -mod test_cases { - use esp_hal::peripheral::Peripheral; - - use super::*; - - pub async fn run_test_one_shot_async() { - let t1 = esp_hal::time::now(); - Timer::after_millis(50).await; - Timer::after_millis(30).await; - let t2 = esp_hal::time::now(); - - assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1); - assert!( - (t2 - t1).to_millis() >= 80u64, - "diff: {:?}", - (t2 - t1).to_millis() - ); - } - - pub fn run_test_periodic_timer(timer: impl Peripheral

) { - let mut periodic = PeriodicTimer::new(timer); - - let t1 = esp_hal::time::now(); - periodic.start(100.millis()).unwrap(); - - nb::block!(periodic.wait()).unwrap(); - let t2 = esp_hal::time::now(); - - assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1); - assert!( - (t2 - t1).to_millis() >= 100u64, - "diff: {:?}", - (t2 - t1).to_millis() - ); - } - - pub fn run_test_oneshot_timer(timer: impl Peripheral

) { - let timer = OneShotTimer::new(timer); - - let t1 = esp_hal::time::now(); - timer.delay_millis(50); - let t2 = esp_hal::time::now(); - - assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1); - assert!( - (t2 - t1).to_millis() >= 50u64, - "diff: {:?}", - (t2 - t1).to_millis() - ); - } - - pub async fn run_join_test() { - let t1 = esp_hal::time::now(); - embassy_futures::join::join(Timer::after_millis(50), Timer::after_millis(30)).await; - Timer::after_millis(50).await; - let t2 = esp_hal::time::now(); - - assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1); - assert!( - (t2 - t1).to_millis() >= 100u64, - "diff: {:?}", - (t2 - t1).to_millis() - ); - } -} - -fn set_up_embassy_with_timg0(peripherals: Peripherals) { - let timg0 = TimerGroup::new(peripherals.TIMG0); - esp_hal_embassy::init(timg0.timer0); -} - -#[cfg(not(feature = "esp32"))] -fn set_up_embassy_with_systimer(peripherals: Peripherals) { - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); - esp_hal_embassy::init(systimer.alarm0); -} - -#[cfg(test)] -#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())] -mod test { - use super::*; - use crate::test_cases::*; - #[cfg(not(feature = "esp32"))] - use crate::test_helpers::*; - - #[init] - fn init() -> Peripherals { - esp_hal::init(esp_hal::Config::default()) - } - - #[test] - #[timeout(3)] - async fn test_one_shot_timg(peripherals: Peripherals) { - set_up_embassy_with_timg0(peripherals); - - run_test_one_shot_async().await; - } - - #[test] - #[timeout(3)] - #[cfg(not(feature = "esp32"))] - async fn test_one_shot_systimer(peripherals: Peripherals) { - set_up_embassy_with_systimer(peripherals); - - run_test_one_shot_async().await; - } - - #[test] - #[timeout(3)] - fn test_periodic_timg(peripherals: Peripherals) { - let timg0 = TimerGroup::new(peripherals.TIMG0); - - run_test_periodic_timer(timg0.timer0); - } - - #[test] - #[timeout(3)] - #[cfg(not(feature = "esp32"))] - fn test_periodic_systimer(peripherals: Peripherals) { - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); - - run_test_periodic_timer(systimer.alarm0); - } - - #[test] - #[timeout(3)] - fn test_periodic_oneshot_timg(mut peripherals: Peripherals) { - let mut timg0 = TimerGroup::new(&mut peripherals.TIMG0); - run_test_periodic_timer(&mut timg0.timer0); - - let mut timg0 = TimerGroup::new(&mut peripherals.TIMG0); - run_test_oneshot_timer(&mut timg0.timer0); - } - - #[test] - #[timeout(3)] - #[cfg(not(feature = "esp32"))] - fn test_periodic_oneshot_systimer(mut peripherals: Peripherals) { - let mut systimer = SystemTimer::new(&mut peripherals.SYSTIMER); - let unit = FrozenUnit::new(&mut systimer.unit0); - let mut alarm: Alarm<'_, Periodic, _, _, _> = Alarm::new(systimer.comparator0, &unit); - run_test_periodic_timer(&mut alarm); - - let mut systimer = SystemTimer::new(&mut peripherals.SYSTIMER); - let unit = FrozenUnit::new(&mut systimer.unit0); - let mut alarm: Alarm<'_, Target, _, _, _> = Alarm::new(systimer.comparator0, &unit); - run_test_oneshot_timer(&mut alarm); - } - - #[test] - #[timeout(3)] - async fn test_join_timg(peripherals: Peripherals) { - set_up_embassy_with_timg0(peripherals); - - run_join_test().await; - } - - #[test] - #[timeout(3)] - #[cfg(not(feature = "esp32"))] - async fn test_join_systimer(peripherals: Peripherals) { - set_up_embassy_with_systimer(peripherals); - - run_join_test().await; - } - - /// Test that the ticker works in tasks ran by the interrupt executors. - #[test] - #[timeout(3)] - #[cfg(not(feature = "esp32"))] - async fn test_interrupt_executor(peripherals: Peripherals) { - let timg0 = TimerGroup::new(peripherals.TIMG0); - let timer0: AnyTimer = timg0.timer0.into(); - - let systimer = SystemTimer::new(peripherals.SYSTIMER).split::(); - let alarm0: AnyTimer = systimer.alarm0.into(); - - esp_hal_embassy::init([timer0, alarm0]); - - let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); - - let executor = mk_static!( - InterruptExecutor<2>, - InterruptExecutor::new(sw_ints.software_interrupt2) - ); - - #[embassy_executor::task] - #[cfg(not(feature = "esp32"))] - async fn test_interrupt_executor_invoker() { - let outcome = async { - let mut ticker = Ticker::every(Duration::from_millis(30)); - - let t1 = esp_hal::time::now(); - ticker.next().await; - ticker.next().await; - ticker.next().await; - let t2 = esp_hal::time::now(); - - assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1); - assert!( - (t2 - t1).to_micros() >= 85000u64, - "diff: {:?}", - (t2 - t1).to_micros() - ); - }; - - embedded_test::export::check_outcome(outcome.await); - } - - let spawner_int = executor.start(Priority::Priority3); - spawner_int.must_spawn(test_interrupt_executor_invoker()); - - let spawner = embassy_executor::Spawner::for_current_executor().await; - spawner.must_spawn(e_task30ms()); - - // The test ends once the interrupt executor's task has finished - loop {} - } - - /// Test that timg0 and systimer don't have vastly different tick rates. - #[test] - #[timeout(3)] - async fn tick_test_timer_tick_rates(peripherals: Peripherals) { - set_up_embassy_with_timg0(peripherals); - - // We are retrying 5 times because probe-rs polling RTT may introduce some - // jitter. - for _ in 0..5 { - let t1 = esp_hal::time::now(); - - let mut ticker = Ticker::every(Duration::from_hz(100_000)); - for _ in 0..2000 { - ticker.next().await; - } - let t2 = esp_hal::time::now(); - - assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1); - let duration = (t2 - t1).to_micros(); - - assert!(duration >= 19000, "diff: {:?}", (t2 - t1).to_micros()); - if duration <= 21000 { - return; - } - } - - assert!(false, "Test failed after 5 retries"); - } -} diff --git a/hil-test/tests/systimer.rs b/hil-test/tests/systimer.rs deleted file mode 100644 index cd2d53f14..000000000 --- a/hil-test/tests/systimer.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! System Timer Test - -// esp32 disabled as it does not have a systimer -//% CHIPS: esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 - -#![no_std] -#![no_main] - -use core::cell::RefCell; - -use critical_section::Mutex; -use embedded_hal::delay::DelayNs; -use esp_hal::{ - delay::Delay, - prelude::*, - timer::systimer::{ - Alarm, - FrozenUnit, - Periodic, - SpecificComparator, - SpecificUnit, - SystemTimer, - Target, - }, - Blocking, -}; -use fugit::ExtU32; -use hil_test as _; -use portable_atomic::{AtomicUsize, Ordering}; -use static_cell::StaticCell; - -type TestAlarm = - Alarm<'static, M, Blocking, SpecificComparator<'static, C>, SpecificUnit<'static, 0>>; - -static ALARM_TARGET: Mutex>>> = Mutex::new(RefCell::new(None)); -static ALARM_PERIODIC: Mutex>>> = - Mutex::new(RefCell::new(None)); - -struct Context { - unit: FrozenUnit<'static, SpecificUnit<'static, 0>>, - comparator0: SpecificComparator<'static, 0>, - comparator1: SpecificComparator<'static, 1>, -} - -#[handler(priority = esp_hal::interrupt::Priority::min())] -fn pass_test_if_called() { - critical_section::with(|cs| { - ALARM_TARGET - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); - embedded_test::export::check_outcome(()); -} - -#[handler(priority = esp_hal::interrupt::Priority::min())] -fn handle_periodic_interrupt() { - critical_section::with(|cs| { - ALARM_PERIODIC - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); -} - -static COUNTER: AtomicUsize = AtomicUsize::new(0); - -#[handler(priority = esp_hal::interrupt::Priority::min())] -fn pass_test_if_called_twice() { - critical_section::with(|cs| { - ALARM_PERIODIC - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); - COUNTER.fetch_add(1, Ordering::Relaxed); - if COUNTER.load(Ordering::Relaxed) == 2 { - embedded_test::export::check_outcome(()); - } -} - -#[handler(priority = esp_hal::interrupt::Priority::min())] -fn target_fail_test_if_called_twice() { - critical_section::with(|cs| { - ALARM_TARGET - .borrow_ref_mut(cs) - .as_mut() - .unwrap() - .clear_interrupt() - }); - COUNTER.fetch_add(1, Ordering::Relaxed); - assert!(COUNTER.load(Ordering::Relaxed) != 2); -} - -#[cfg(test)] -#[embedded_test::tests] -mod tests { - use super::*; - - #[init] - fn init() -> Context { - let peripherals = esp_hal::init(esp_hal::Config::default()); - - let systimer = SystemTimer::new(peripherals.SYSTIMER); - static UNIT0: StaticCell> = StaticCell::new(); - - let unit0 = UNIT0.init(systimer.unit0); - let frozen_unit = FrozenUnit::new(unit0); - - Context { - unit: frozen_unit, - comparator0: systimer.comparator0, - comparator1: systimer.comparator1, - } - } - - #[test] - #[timeout(3)] - fn target_interrupt_is_handled(ctx: Context) { - let alarm0 = Alarm::new(ctx.comparator0, &ctx.unit); - - critical_section::with(|cs| { - alarm0.set_interrupt_handler(pass_test_if_called); - alarm0.set_target(SystemTimer::now() + SystemTimer::ticks_per_second() / 10); - alarm0.enable_interrupt(true); - - ALARM_TARGET.borrow_ref_mut(cs).replace(alarm0); - }); - - // We'll end the test in the interrupt handler. - loop {} - } - - #[test] - #[timeout(3)] - fn target_interrupt_is_handled_once(ctx: Context) { - let alarm0 = Alarm::new(ctx.comparator0, &ctx.unit); - let alarm1 = Alarm::new(ctx.comparator1, &ctx.unit); - - COUNTER.store(0, Ordering::Relaxed); - - critical_section::with(|cs| { - alarm0.set_interrupt_handler(target_fail_test_if_called_twice); - alarm0.set_target(SystemTimer::now() + SystemTimer::ticks_per_second() / 10); - alarm0.enable_interrupt(true); - - let alarm1 = alarm1.into_periodic(); - alarm1.set_interrupt_handler(handle_periodic_interrupt); - alarm1.set_period(100u32.millis()); - alarm1.enable_interrupt(true); - - ALARM_TARGET.borrow_ref_mut(cs).replace(alarm0); - ALARM_PERIODIC.borrow_ref_mut(cs).replace(alarm1); - }); - - let mut delay = Delay::new(); - delay.delay_ms(300); - } - - #[test] - #[timeout(3)] - fn periodic_interrupt_is_handled(ctx: Context) { - let alarm1 = Alarm::new(ctx.comparator1, &ctx.unit); - - COUNTER.store(0, Ordering::Relaxed); - - critical_section::with(|cs| { - let alarm1 = alarm1.into_periodic(); - alarm1.set_interrupt_handler(pass_test_if_called_twice); - alarm1.set_period(100u32.millis()); - alarm1.enable_interrupt(true); - - ALARM_PERIODIC.borrow_ref_mut(cs).replace(alarm1); - }); - - // We'll end the test in the interrupt handler. - loop {} - } -}