#[derive(Debug, Clone, Copy)]
pub struct Delay;
impl Delay {
pub fn delay_millis(&self, mut ms: u32) {
const MICROS_PER_MILLI: u32 = 1_000;
const MAX_MILLIS: u32 = u32::MAX / MICROS_PER_MILLI;
while ms > MAX_MILLIS {
ms -= MAX_MILLIS;
self.delay_micros(MAX_MILLIS * MICROS_PER_MILLI);
}
self.delay_micros(ms * MICROS_PER_MILLI);
}
pub fn delay_micros(&self, mut us: u32) {
const NANOS_PER_MICRO: u32 = 1_000;
const MAX_MICROS: u32 = u32::MAX / NANOS_PER_MICRO;
while us > MAX_MICROS {
us -= MAX_MICROS;
self.delay_nanos(MAX_MICROS * NANOS_PER_MICRO);
}
self.delay_nanos(us * NANOS_PER_MICRO);
}
pub fn delay_nanos(&self, ns: u32) {
let ticks_seconds = unsafe { crate::CPU_CLOCK };
let clock = (ns as u64 * (ticks_seconds as u64)) / 1_000_000_000u64;
let t0 = cycles();
while cycles().wrapping_sub(t0) <= clock {}
}
}
#[cfg(feature = "esp32c6")]
#[inline(always)]
fn cycles() -> u64 {
riscv::register::mcycle::read64()
}
#[cfg(any(feature = "esp32s2", feature = "esp32s3"))]
#[inline(always)]
fn cycles() -> u64 {
let mut cycles: u32;
unsafe {
core::arch::asm!(
"rdcycle {cycles}",
cycles = out(reg) cycles,
)
}
cycles as u64
}
#[cfg(feature = "embedded-hal")]
impl embedded_hal::delay::DelayNs for Delay {
#[inline(always)]
fn delay_ns(&mut self, ns: u32) {
self.delay_nanos(ns);
}
}