Skip to content

Commit

Permalink
Implement esp32c3 delay with monotonic SystemTimer::now()
Browse files Browse the repository at this point in the history
  • Loading branch information
MabezDev committed Jun 9, 2022
1 parent f004d3e commit 7374c5b
Show file tree
Hide file tree
Showing 6 changed files with 9 additions and 36 deletions.
35 changes: 4 additions & 31 deletions esp-hal-common/src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,60 +32,33 @@ where
mod delay {
use fugit::HertzU64;

use crate::{clock::Clocks, pac::SYSTIMER};
use crate::{clock::Clocks, systimer::SystemTimer};

/// Uses the `SYSTIMER` peripheral for counting clock cycles, as
/// unfortunately the ESP32-C3 does NOT implement the `mcycle` CSR, which is
/// how we would normally do this.
pub struct Delay {
systimer: SYSTIMER,
freq: HertzU64,
}

impl Delay {
/// Create a new Delay instance
pub fn new(systimer: SYSTIMER, clocks: &Clocks) -> Self {
pub fn new(clocks: &Clocks) -> Self {
// The counters and comparators are driven using `XTAL_CLK`. The average clock
// frequency is fXTAL_CLK/2.5, which is 16 MHz. The timer counting is
// incremented by 1/16 μs on each `CNT_CLK` cycle.

Self {
systimer,
freq: HertzU64::MHz((clocks.xtal_clock.to_MHz() * 10 / 25) as u64),
}
}

/// Return the raw interface to the underlying SYSTIMER instance
pub fn free(self) -> SYSTIMER {
self.systimer
}

/// Delay for the specified number of microseconds
pub fn delay(&self, us: u32) {
let t0 = self.unit0_value();
let t0 = SystemTimer::now();
let clocks = (us as u64 * self.freq.raw()) / HertzU64::MHz(1).raw();

while self.unit0_value().wrapping_sub(t0) <= clocks {}
}

#[inline(always)]
fn unit0_value(&self) -> u64 {
self.systimer
.unit0_op
.write(|w| w.timer_unit0_update().set_bit());

while !self
.systimer
.unit0_op
.read()
.timer_unit0_value_valid()
.bit_is_set()
{}

let value_lo = self.systimer.unit0_value_lo.read().bits();
let value_hi = self.systimer.unit0_value_hi.read().bits();

((value_hi as u64) << 32) | value_lo as u64
while SystemTimer::now().wrapping_sub(t0) <= clocks {}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion esp32c3-hal/examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() -> ! {

// Initialize the Delay peripheral, and use it to toggle the LED state in a
// loop.
let mut delay = Delay::new(peripherals.SYSTIMER, &clocks);
let mut delay = Delay::new(&clocks);

loop {
led.toggle().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion esp32c3-hal/examples/gpio_interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn main() -> ! {
riscv::interrupt::enable();
}

let mut delay = Delay::new(peripherals.SYSTIMER, &clocks);
let mut delay = Delay::new(&clocks);
loop {
led.toggle().unwrap();
delay.delay_ms(500u32);
Expand Down
2 changes: 1 addition & 1 deletion esp32c3-hal/examples/hello_rgb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn main() -> ! {

// Initialize the Delay peripheral, and use it to toggle the LED state in a
// loop.
let mut delay = Delay::new(peripherals.SYSTIMER, &clocks);
let mut delay = Delay::new(&clocks);

let mut color = Hsv {
hue: 0,
Expand Down
2 changes: 1 addition & 1 deletion esp32c3-hal/examples/spi_loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn main() -> ! {
&clocks,
);

let mut delay = Delay::new(peripherals.SYSTIMER, &clocks);
let mut delay = Delay::new(&clocks);

loop {
let mut data = [0xde, 0xca, 0xfb, 0xad];
Expand Down
2 changes: 1 addition & 1 deletion esp32c3-hal/examples/usb_serial_jtag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

let mut delay = Delay::new(peripherals.SYSTIMER, &clocks);
let mut delay = Delay::new(&clocks);
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
let mut timer0 = Timer::new(peripherals.TIMG0);
let mut timer1 = Timer::new(peripherals.TIMG1);
Expand Down

0 comments on commit 7374c5b

Please sign in to comment.