Skip to content

Commit

Permalink
Newtype fugit Rate, Instant and Duration
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Feb 3, 2025
1 parent fe53061 commit e204b06
Show file tree
Hide file tree
Showing 111 changed files with 913 additions and 613 deletions.
11 changes: 5 additions & 6 deletions esp-hal-embassy/src/time_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use embassy_time_driver::Driver;
use esp_hal::{
interrupt::{InterruptHandler, Priority},
sync::Locked,
time::{now, ExtU64},
time::{now, Duration},
timer::OneShotTimer,
Blocking,
};
Expand Down Expand Up @@ -203,11 +203,10 @@ impl EmbassyTimer {
/// Returns `true` if the timer was armed, `false` if the timestamp is in
/// the past.
fn arm(timer: &mut Timer, timestamp: u64) -> bool {
let now = now().duration_since_epoch();
let ts = timestamp.micros();
let now = now().duration_since_epoch().as_micros();

if ts > now {
let timeout = ts - now;
if timestamp > now {
let timeout = Duration::from_micros(timestamp - now);
unwrap!(timer.schedule(timeout));
true
} else {
Expand Down Expand Up @@ -295,7 +294,7 @@ impl EmbassyTimer {

impl Driver for EmbassyTimer {
fn now(&self) -> u64 {
now().ticks()
now().duration_since_epoch().as_micros()
}

fn schedule_wake(&self, at: u64, waker: &core::task::Waker) {
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-embassy/src/timer_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl TimerQueue {
}

pub fn dispatch(&self) {
let now = esp_hal::time::now().ticks();
let now = esp_hal::time::now().duration_since_epoch().as_micros();
self.arm_alarm(now);
}

Expand Down
1 change: 1 addition & 0 deletions esp-hal/src/clock/clocks_ll/esp32s2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) {
} as u8)
});

// FIXME untangle this
let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16);
rtc_cntl.store5().modify(|_, w| w.scratch5().bits(value));
}
Expand Down
5 changes: 1 addition & 4 deletions esp-hal/src/clock/clocks_ll/esp32s3.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::ops::Div;

use crate::{
clock::{Clock, CpuClock},
rom,
Expand All @@ -24,6 +22,5 @@ pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) {
});
}

let ticks_per_us = cpu_clock_speed.frequency().div(1_000_000);
rom::ets_update_cpu_frequency_rom(ticks_per_us.raw());
rom::ets_update_cpu_frequency_rom(cpu_clock_speed.frequency().as_mhz());
}
99 changes: 49 additions & 50 deletions esp-hal/src/clock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@
//! # }
//! ```
use fugit::HertzU32;

#[cfg(any(esp32, esp32c2))]
use crate::rtc_cntl::RtcClock;
use crate::time::Rate;

#[cfg_attr(esp32, path = "clocks_ll/esp32.rs")]
#[cfg_attr(esp32c2, path = "clocks_ll/esp32c2.rs")]
Expand All @@ -61,17 +60,17 @@ pub(crate) mod clocks_ll;
/// Clock properties
#[doc(hidden)]
pub trait Clock {
/// Frequency of the clock in [Hertz](fugit::HertzU32), using [fugit] types.
fn frequency(&self) -> HertzU32;
/// Frequency of the clock in [Rate].
fn frequency(&self) -> Rate;

/// Frequency of the clock in Megahertz
fn mhz(&self) -> u32 {
self.frequency().to_MHz()
self.frequency().as_mhz()
}

/// Frequency of the clock in Hertz
fn hz(&self) -> u32 {
self.frequency().to_Hz()
self.frequency().as_hz()
}
}

Expand Down Expand Up @@ -136,8 +135,8 @@ impl CpuClock {
}

impl Clock for CpuClock {
fn frequency(&self) -> HertzU32 {
HertzU32::MHz(*self as u32)
fn frequency(&self) -> Rate {
Rate::from_mhz(*self as u32)
}
}

Expand All @@ -160,15 +159,15 @@ pub enum XtalClock {
}

impl Clock for XtalClock {
fn frequency(&self) -> HertzU32 {
fn frequency(&self) -> Rate {
match self {
#[cfg(any(esp32, esp32c2))]
XtalClock::_26M => HertzU32::MHz(26),
XtalClock::_26M => Rate::from_mhz(26),
#[cfg(any(esp32c3, esp32h2, esp32s3))]
XtalClock::_32M => HertzU32::MHz(32),
XtalClock::_32M => Rate::from_mhz(32),
#[cfg(not(esp32h2))]
XtalClock::_40M => HertzU32::MHz(40),
XtalClock::Other(mhz) => HertzU32::MHz(*mhz),
XtalClock::_40M => Rate::from_mhz(40),
XtalClock::Other(mhz) => Rate::from_mhz(*mhz),
}
}
}
Expand Down Expand Up @@ -199,28 +198,28 @@ pub(crate) enum PllClock {
}

impl Clock for PllClock {
fn frequency(&self) -> HertzU32 {
fn frequency(&self) -> Rate {
match self {
#[cfg(esp32h2)]
Self::Pll8MHz => HertzU32::MHz(8),
Self::Pll8MHz => Rate::from_mhz(8),
#[cfg(any(esp32c6, esp32h2))]
Self::Pll48MHz => HertzU32::MHz(48),
Self::Pll48MHz => Rate::from_mhz(48),
#[cfg(esp32h2)]
Self::Pll64MHz => HertzU32::MHz(64),
Self::Pll64MHz => Rate::from_mhz(64),
#[cfg(esp32c6)]
Self::Pll80MHz => HertzU32::MHz(80),
Self::Pll80MHz => Rate::from_mhz(80),
#[cfg(esp32h2)]
Self::Pll96MHz => HertzU32::MHz(96),
Self::Pll96MHz => Rate::from_mhz(96),
#[cfg(esp32c6)]
Self::Pll120MHz => HertzU32::MHz(120),
Self::Pll120MHz => Rate::from_mhz(120),
#[cfg(esp32c6)]
Self::Pll160MHz => HertzU32::MHz(160),
Self::Pll160MHz => Rate::from_mhz(160),
#[cfg(esp32c6)]
Self::Pll240MHz => HertzU32::MHz(240),
Self::Pll240MHz => Rate::from_mhz(240),
#[cfg(not(any(esp32c2, esp32c6, esp32h2)))]
Self::Pll320MHz => HertzU32::MHz(320),
Self::Pll320MHz => Rate::from_mhz(320),
#[cfg(not(esp32h2))]
Self::Pll480MHz => HertzU32::MHz(480),
Self::Pll480MHz => Rate::from_mhz(480),
}
}
}
Expand All @@ -238,15 +237,15 @@ pub(crate) enum ApbClock {
}

impl Clock for ApbClock {
fn frequency(&self) -> HertzU32 {
fn frequency(&self) -> Rate {
match self {
#[cfg(esp32h2)]
ApbClock::ApbFreq32MHz => HertzU32::MHz(32),
ApbClock::ApbFreq32MHz => Rate::from_mhz(32),
#[cfg(not(esp32h2))]
ApbClock::ApbFreq40MHz => HertzU32::MHz(40),
ApbClock::ApbFreq40MHz => Rate::from_mhz(40),
#[cfg(not(esp32h2))]
ApbClock::ApbFreq80MHz => HertzU32::MHz(80),
ApbClock::ApbFreqOther(mhz) => HertzU32::MHz(*mhz),
ApbClock::ApbFreq80MHz => Rate::from_mhz(80),
ApbClock::ApbFreqOther(mhz) => Rate::from_mhz(*mhz),
}
}
}
Expand All @@ -258,37 +257,37 @@ impl Clock for ApbClock {
#[doc(hidden)]
pub struct Clocks {
/// CPU clock frequency
pub cpu_clock: HertzU32,
pub cpu_clock: Rate,

/// APB clock frequency
pub apb_clock: HertzU32,
pub apb_clock: Rate,

/// XTAL clock frequency
pub xtal_clock: HertzU32,
pub xtal_clock: Rate,

/// I2C clock frequency
#[cfg(esp32)]
pub i2c_clock: HertzU32,
pub i2c_clock: Rate,

/// PWM clock frequency
#[cfg(esp32)]
pub pwm_clock: HertzU32,
pub pwm_clock: Rate,

/// Crypto PWM clock frequency
#[cfg(esp32s3)]
pub crypto_pwm_clock: HertzU32,
pub crypto_pwm_clock: Rate,

/// Crypto clock frequency
#[cfg(any(esp32c6, esp32h2))]
pub crypto_clock: HertzU32,
pub crypto_clock: Rate,

/// PLL 48M clock frequency (fixed)
#[cfg(esp32h2)]
pub pll_48m_clock: HertzU32,
pub pll_48m_clock: Rate,

/// PLL 96M clock frequency (fixed)
#[cfg(esp32h2)]
pub pll_96m_clock: HertzU32,
pub pll_96m_clock: Rate,
}

static mut ACTIVE_CLOCKS: Option<Clocks> = None;
Expand Down Expand Up @@ -318,7 +317,7 @@ impl Clocks {
/// This function will run the frequency estimation if called before
/// [`crate::init()`].
#[cfg(systimer)]
pub(crate) fn xtal_freq() -> HertzU32 {
pub(crate) fn xtal_freq() -> Rate {
if let Some(clocks) = Self::try_get() {
clocks.xtal_clock
} else {
Expand Down Expand Up @@ -356,13 +355,13 @@ impl Clocks {

Self {
cpu_clock: cpu_clock_speed.frequency(),
apb_clock: HertzU32::MHz(80),
xtal_clock: HertzU32::MHz(xtal_freq.mhz()),
i2c_clock: HertzU32::MHz(80),
apb_clock: Rate::from_mhz(80),
xtal_clock: Rate::from_mhz(xtal_freq.mhz()),
i2c_clock: Rate::from_mhz(80),
// The docs are unclear here. pwm_clock seems to be tied to clocks.apb_clock
// while simultaneously being fixed at 160 MHz.
// Testing showed 160 MHz to be correct for current clock configurations.
pwm_clock: HertzU32::MHz(160),
pwm_clock: Rate::from_mhz(160),
}
}
}
Expand Down Expand Up @@ -476,7 +475,7 @@ impl Clocks {
cpu_clock: cpu_clock_speed.frequency(),
apb_clock: apb_freq.frequency(),
xtal_clock: xtal_freq.frequency(),
crypto_clock: HertzU32::MHz(160),
crypto_clock: Rate::from_mhz(160),
}
}
}
Expand Down Expand Up @@ -513,9 +512,9 @@ impl Clocks {
cpu_clock: cpu_clock_speed.frequency(),
apb_clock: apb_freq.frequency(),
xtal_clock: xtal_freq.frequency(),
pll_48m_clock: HertzU32::MHz(48),
crypto_clock: HertzU32::MHz(96),
pll_96m_clock: HertzU32::MHz(96),
pll_48m_clock: Rate::from_mhz(48),
crypto_clock: Rate::from_mhz(96),
pll_96m_clock: Rate::from_mhz(96),
}
}
}
Expand All @@ -536,7 +535,7 @@ impl Clocks {

Self {
cpu_clock: cpu_clock_speed.frequency(),
apb_clock: HertzU32::MHz(80),
apb_clock: Rate::from_mhz(80),
xtal_clock: xtal_freq.frequency(),
}
}
Expand All @@ -558,9 +557,9 @@ impl Clocks {

Self {
cpu_clock: cpu_clock_speed.frequency(),
apb_clock: HertzU32::MHz(80),
apb_clock: Rate::from_mhz(80),
xtal_clock: xtal_freq.frequency(),
crypto_pwm_clock: HertzU32::MHz(160),
crypto_pwm_clock: Rate::from_mhz(160),
}
}
}
7 changes: 5 additions & 2 deletions esp-hal/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,24 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! use esp_hal::clock::CpuClock;
//! use esp_hal::time::Duration;
//!
//! let config =
//! esp_hal::Config::default().with_cpu_clock(CpuClock::max()).
//! with_watchdog(esp_hal::config::WatchdogConfig::default().
//! with_rwdt(esp_hal::config::WatchdogStatus::Enabled(fugit::MicrosDurationU64::millis(1000u64))));
//! with_rwdt(esp_hal::config::WatchdogStatus::Enabled(Duration::from_millis(1000u64))));
//! let peripherals = esp_hal::init(config);
//! # Ok(())
//! # }
//! ```
use crate::time::Duration;

/// Watchdog status.
#[derive(Default, PartialEq, Clone, Copy)]
pub enum WatchdogStatus {
/// Enables a watchdog timer with the specified timeout.
Enabled(fugit::MicrosDurationU64),
Enabled(Duration),
/// Disables the watchdog timer.
#[default]
Disabled,
Expand Down
35 changes: 8 additions & 27 deletions esp-hal/src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,9 @@
//! [embedded-hal]: https://docs.rs/embedded-hal/1.0.0/embedded_hal/delay/index.html
//! [now]: crate::time::now
pub use fugit::MicrosDurationU64;
use crate::time::{Duration, Instant};

/// Delay driver
///
/// Uses the `SYSTIMER` peripheral internally for RISC-V devices, and the
/// built-in Xtensa timer for Xtensa devices.
/// Delay driver, using [`Instant`].
#[derive(Clone, Copy, Default)]
#[non_exhaustive]
pub struct Delay;
Expand All @@ -55,40 +52,24 @@ impl Delay {
}

/// Delay for the specified time
pub fn delay(&self, delay: MicrosDurationU64) {
let start = crate::time::now();
pub fn delay(&self, delay: Duration) {
let start = Instant::now();

while elapsed_since(start) < delay {}
while start.elapsed() < delay {}
}

/// Delay for the specified number of milliseconds
pub fn delay_millis(&self, ms: u32) {
for _ in 0..ms {
self.delay_micros(1000);
}
self.delay(Duration::from_millis(ms as u64));
}

/// Delay for the specified number of microseconds
pub fn delay_micros(&self, us: u32) {
let delay = MicrosDurationU64::micros(us as u64);
self.delay(delay);
self.delay(Duration::from_micros(us as u64));
}

/// Delay for the specified number of nanoseconds
pub fn delay_nanos(&self, ns: u32) {
let delay = MicrosDurationU64::nanos(ns as u64);
self.delay(delay);
}
}

fn elapsed_since(start: fugit::Instant<u64, 1, 1_000_000>) -> MicrosDurationU64 {
let now = crate::time::now();

if start.ticks() <= now.ticks() {
now - start
} else {
// now specifies at least 7 happy years, let's ignore this issue for
// now.
panic!("Time has wrapped around, which we currently don't handle");
self.delay(Duration::from_micros(ns.div_ceil(1000) as u64));
}
}
Loading

0 comments on commit e204b06

Please sign in to comment.