diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 96e80b87a3f..4f9ac9064fd 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -141,6 +141,9 @@ pub enum Peripheral { /// LCD Camera peripheral. #[cfg(lcd_cam)] LcdCam, + /// Systimer peripheral. + #[cfg(systimer)] + Systimer, } /// The `DPORT`/`PCR`/`SYSTEM` peripheral split into its different logical @@ -540,6 +543,11 @@ impl PeripheralClockControl { perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().set_bit()); perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit()); } + #[cfg(systimer)] + Peripheral::Systimer => { + perip_clk_en0.modify(|_, w| w.systimer_clk_en().set_bit()); + perip_rst_en0.modify(|_, w| w.systimer_rst().clear_bit()); + } }); } @@ -744,6 +752,11 @@ impl PeripheralClockControl { perip_rst_en1.modify(|_, w| w.lcd_cam_rst().set_bit()); perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit()); } + #[cfg(systimer)] + Peripheral::Systimer => { + perip_rst_en0.modify(|_, w| w.systimer_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.systimer_rst().clear_bit()); + } }); } } @@ -962,6 +975,15 @@ impl PeripheralClockControl { .trace_conf() .modify(|_, w| w.trace_rst_en().clear_bit()); } + #[cfg(systimer)] + Peripheral::Systimer => { + system + .systimer_conf() + .modify(|_, w| w.systimer_clk_en().set_bit()); + system + .systimer_conf() + .modify(|_, w| w.systimer_rst_en().clear_bit()); + } } } @@ -1154,6 +1176,15 @@ impl PeripheralClockControl { .trace_conf() .modify(|_, w| w.trace_rst_en().clear_bit()); } + #[cfg(systimer)] + Peripheral::Systimer => { + system + .systimer_conf() + .modify(|_, w| w.systimer_rst_en().set_bit()); + system + .systimer_conf() + .modify(|_, w| w.systimer_rst_en().clear_bit()); + } } } } diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index ed7969e1a86..d2e36f38179 100644 --- a/esp-hal/src/timer/systimer.rs +++ b/esp-hal/src/timer/systimer.rs @@ -81,6 +81,7 @@ use crate::{ interrupt::{self, InterruptHandler}, peripheral::Peripheral, peripherals::{Interrupt, SYSTIMER}, + system::{Peripheral as PeripheralEnable, PeripheralClockControl}, Async, Blocking, Cpu, @@ -145,6 +146,9 @@ impl<'d> SystemTimer<'d> { /// Create a new instance. pub fn new(_systimer: impl Peripheral

+ 'd) -> Self { + // Don't reset Systimer as it will break `current_time`, only enable it + PeripheralClockControl::enable(PeripheralEnable::Systimer); + #[cfg(soc_etm)] etm::enable_etm(); diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml index c8444811cba..fad3a4f8f10 100644 --- a/hil-test/Cargo.toml +++ b/hil-test/Cargo.toml @@ -175,6 +175,10 @@ p256 = { version = "0.13.2", default-features = false, features = sha1 = { version = "0.10.6", default-features = false } sha2 = { version = "0.10.8", default-features = false } +[build-dependencies] +esp-build = { version = "0.1.0", path = "../esp-build" } +esp-metadata = { version = "0.2.0", path = "../esp-metadata" } + [features] default = ["async", "embassy"] @@ -232,3 +236,6 @@ incremental = false opt-level = 3 lto = "fat" overflow-checks = false + +[lints.rust] +unexpected_cfgs = "allow" diff --git a/hil-test/build.rs b/hil-test/build.rs new file mode 100644 index 00000000000..1c7ecfc2ff6 --- /dev/null +++ b/hil-test/build.rs @@ -0,0 +1,41 @@ +use std::{error::Error, str::FromStr}; + +use esp_build::assert_unique_used_features; +use esp_metadata::{Chip, Config}; + +fn main() -> Result<(), Box> { + // NOTE: update when adding new device support! + // Ensure that exactly one chip has been specified: + assert_unique_used_features!( + "esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3" + ); + + // NOTE: update when adding new device support! + // Determine the name of the configured device: + let device_name = if cfg!(feature = "esp32") { + "esp32" + } else if cfg!(feature = "esp32c2") { + "esp32c2" + } else if cfg!(feature = "esp32c3") { + "esp32c3" + } else if cfg!(feature = "esp32c6") { + "esp32c6" + } else if cfg!(feature = "esp32h2") { + "esp32h2" + } else if cfg!(feature = "esp32s2") { + "esp32s2" + } else if cfg!(feature = "esp32s3") { + "esp32s3" + } else { + unreachable!() // We've confirmed exactly one known device was selected + }; + + // Load the configuration file for the configured device: + let chip = Chip::from_str(device_name)?; + let config = Config::for_chip(&chip); + + // Define all necessary configuration symbols for the configured device: + config.define_symbols(); + + Ok(()) +} diff --git a/hil-test/tests/get_time.rs b/hil-test/tests/get_time.rs index 72b065ced05..31afab56ed5 100644 --- a/hil-test/tests/get_time.rs +++ b/hil-test/tests/get_time.rs @@ -5,11 +5,15 @@ #![no_std] #![no_main] +#[cfg(esp32)] +use esp_hal::clock::Clocks; use esp_hal::{clock::ClockControl, delay::Delay, peripherals::Peripherals, system::SystemControl}; use hil_test as _; struct Context { delay: Delay, + #[cfg(esp32)] + clocks: Clocks<'static>, } impl Context { @@ -20,10 +24,22 @@ impl Context { let delay = Delay::new(&clocks); - Context { delay } + Context { + delay, + #[cfg(esp32)] + clocks, + } } } +fn time_moves_forward_during(ctx: Context, f: F) { + let t1 = esp_hal::time::current_time(); + f(ctx); + let t2 = esp_hal::time::current_time(); + + assert!(t2 > t1); +} + #[cfg(test)] #[embedded_test::tests] mod tests { @@ -44,4 +60,29 @@ mod tests { assert!(t2 > t1); assert!((t2 - t1).to_millis() >= 500u64); } + + #[cfg(systimer)] + #[test] + #[timeout(3)] + fn test_current_time_construct_systimer(ctx: Context) { + time_moves_forward_during(ctx, |_| { + // construct the timer in between calls to current_time + let _ = esp_hal::timer::systimer::SystemTimer::new(unsafe { + esp_hal::peripherals::SYSTIMER::steal() + }); + }) + } + + #[cfg(esp32)] + #[test] + #[timeout(3)] + fn test_current_time_construct_timg0(ctx: Context) { + time_moves_forward_during(ctx, |ctx| { + // construct the timer in between calls to current_time + let _ = esp_hal::timer::timg::TimerGroup::new( + unsafe { esp_hal::peripherals::TIMG0::steal() }, + &ctx.clocks, + ); + }) + } }