From 147d8de98884e17c64e497da072dfa657dbcbef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 20 Jul 2022 15:51:39 +0200 Subject: [PATCH] Separate TIMG into timer0, (timer1), wdt (#104) * Separate TIMG into timer0, (timer1), wdt * Apply suggestions from code review * Remove left-over code * Ignore settings.json --- .gitignore | 3 + esp-hal-common/.vscode/esp32.settings.json | 23 + .../{settings.json => esp32c3.settings.json} | 0 esp-hal-common/.vscode/esp32s2.settings.json | 23 + esp-hal-common/.vscode/esp32s3.settings.json | 23 + esp-hal-common/Cargo.toml | 8 +- esp-hal-common/src/timer.rs | 497 +++++++++++++++--- esp32-hal/examples/adc.rs | 7 +- esp32-hal/examples/advanced_serial.rs | 7 +- esp32-hal/examples/blinky.rs | 7 +- esp32-hal/examples/dac.rs | 7 +- esp32-hal/examples/gpio_interrupt.rs | 8 +- esp32-hal/examples/hello_rgb.rs | 7 +- esp32-hal/examples/hello_world.rs | 15 +- esp32-hal/examples/i2c_display.rs | 8 +- esp32-hal/examples/multicore.rs | 22 +- esp32-hal/examples/ram.rs | 8 +- esp32-hal/examples/read_efuse.rs | 7 +- esp32-hal/examples/serial_interrupts.rs | 15 +- esp32-hal/examples/spi_loopback.rs | 7 +- esp32-hal/examples/timer_interrupt.rs | 141 +++-- esp32-hal/examples/watchdog.rs | 44 ++ esp32-hal/src/lib.rs | 2 +- esp32c3-hal/examples/adc.rs | 12 +- esp32c3-hal/examples/advanced_serial.rs | 13 +- esp32c3-hal/examples/blinky.rs | 12 +- esp32c3-hal/examples/gpio_interrupt.rs | 12 +- esp32c3-hal/examples/hello_rgb.rs | 7 +- esp32c3-hal/examples/hello_world.rs | 20 +- esp32c3-hal/examples/i2c_display.rs | 13 +- esp32c3-hal/examples/ram.rs | 9 +- esp32c3-hal/examples/read_efuse.rs | 12 +- esp32c3-hal/examples/serial_interrupts.rs | 13 +- esp32c3-hal/examples/spi_loopback.rs | 13 +- esp32c3-hal/examples/systimer.rs | 13 +- esp32c3-hal/examples/timer_interrupt.rs | 20 +- esp32c3-hal/examples/usb_serial_jtag.rs | 12 +- esp32c3-hal/examples/watchdog.rs | 49 ++ esp32c3-hal/src/lib.rs | 2 +- esp32s2-hal/examples/adc.rs | 7 +- esp32s2-hal/examples/advanced_serial.rs | 7 +- esp32s2-hal/examples/blinky.rs | 7 +- esp32s2-hal/examples/dac.rs | 7 +- esp32s2-hal/examples/gpio_interrupt.rs | 7 +- esp32s2-hal/examples/hello_rgb.rs | 7 +- esp32s2-hal/examples/hello_world.rs | 15 +- esp32s2-hal/examples/i2c_display.rs | 8 +- esp32s2-hal/examples/ram.rs | 8 +- esp32s2-hal/examples/read_efuse.rs | 7 +- esp32s2-hal/examples/serial_interrupts.rs | 13 +- esp32s2-hal/examples/spi_loopback.rs | 7 +- esp32s2-hal/examples/systimer.rs | 7 +- esp32s2-hal/examples/timer_interrupt.rs | 141 +++-- esp32s2-hal/examples/watchdog.rs | 44 ++ esp32s2-hal/src/lib.rs | 2 +- esp32s3-hal/examples/advanced_serial.rs | 7 +- esp32s3-hal/examples/blinky.rs | 7 +- esp32s3-hal/examples/gpio_interrupt.rs | 7 +- esp32s3-hal/examples/hello_rgb.rs | 7 +- esp32s3-hal/examples/hello_world.rs | 15 +- esp32s3-hal/examples/i2c_display.rs | 8 +- esp32s3-hal/examples/multicore.rs | 22 +- esp32s3-hal/examples/ram.rs | 8 +- esp32s3-hal/examples/read_efuse.rs | 7 +- esp32s3-hal/examples/serial_interrupts.rs | 15 +- esp32s3-hal/examples/spi_loopback.rs | 7 +- esp32s3-hal/examples/systimer.rs | 7 +- esp32s3-hal/examples/timer_interrupt.rs | 141 +++-- esp32s3-hal/examples/usb_serial_jtag.rs | 7 +- esp32s3-hal/examples/watchdog.rs | 44 ++ esp32s3-hal/src/lib.rs | 2 +- 71 files changed, 1324 insertions(+), 402 deletions(-) create mode 100644 esp-hal-common/.vscode/esp32.settings.json rename esp-hal-common/.vscode/{settings.json => esp32c3.settings.json} (100%) create mode 100644 esp-hal-common/.vscode/esp32s2.settings.json create mode 100644 esp-hal-common/.vscode/esp32s3.settings.json create mode 100644 esp32-hal/examples/watchdog.rs create mode 100644 esp32c3-hal/examples/watchdog.rs create mode 100644 esp32s2-hal/examples/watchdog.rs create mode 100644 esp32s3-hal/examples/watchdog.rs diff --git a/.gitignore b/.gitignore index 6985cf1bd..4d990a5a8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +# Other +**/settings.json diff --git a/esp-hal-common/.vscode/esp32.settings.json b/esp-hal-common/.vscode/esp32.settings.json new file mode 100644 index 000000000..0aab4bf55 --- /dev/null +++ b/esp-hal-common/.vscode/esp32.settings.json @@ -0,0 +1,23 @@ +{ + "rust-analyzer.cargo.features": [ + "esp32" + ], + "rust-analyzer.cargo.allFeatures": false, + "editor.formatOnSave": false, + "rust-analyzer.checkOnSave.allTargets": true, + "rust-analyzer.checkOnSave.allFeatures": false, + "rust-analyzer.checkOnSave.overrideCommand": [ + "cargo", + "check", + "--features", + "esp32", + "--message-format=json", + "-Z", + "build-std=core", + "--target", + "xtensa-esp32-none-elf", + "--examples", + "--lib", + ], + "rust-analyzer.cargo.buildScripts.enable": false +} \ No newline at end of file diff --git a/esp-hal-common/.vscode/settings.json b/esp-hal-common/.vscode/esp32c3.settings.json similarity index 100% rename from esp-hal-common/.vscode/settings.json rename to esp-hal-common/.vscode/esp32c3.settings.json diff --git a/esp-hal-common/.vscode/esp32s2.settings.json b/esp-hal-common/.vscode/esp32s2.settings.json new file mode 100644 index 000000000..5c7e60350 --- /dev/null +++ b/esp-hal-common/.vscode/esp32s2.settings.json @@ -0,0 +1,23 @@ +{ + "rust-analyzer.cargo.features": [ + "esp32s2" + ], + "rust-analyzer.cargo.allFeatures": false, + "editor.formatOnSave": false, + "rust-analyzer.checkOnSave.allTargets": true, + "rust-analyzer.checkOnSave.allFeatures": false, + "rust-analyzer.checkOnSave.overrideCommand": [ + "cargo", + "check", + "--features", + "esp32s2", + "--message-format=json", + "-Z", + "build-std=core", + "--target", + "xtensa-esp32s2-none-elf", + "--examples", + "--lib", + ], + "rust-analyzer.cargo.buildScripts.enable": false +} \ No newline at end of file diff --git a/esp-hal-common/.vscode/esp32s3.settings.json b/esp-hal-common/.vscode/esp32s3.settings.json new file mode 100644 index 000000000..13b90a45b --- /dev/null +++ b/esp-hal-common/.vscode/esp32s3.settings.json @@ -0,0 +1,23 @@ +{ + "rust-analyzer.cargo.features": [ + "esp32s3" + ], + "rust-analyzer.cargo.allFeatures": false, + "editor.formatOnSave": false, + "rust-analyzer.checkOnSave.allTargets": true, + "rust-analyzer.checkOnSave.allFeatures": false, + "rust-analyzer.checkOnSave.overrideCommand": [ + "cargo", + "check", + "--features", + "esp32s3", + "--message-format=json", + "-Z", + "build-std=core", + "--target", + "xtensa-esp32s3-none-elf", + "--examples", + "--lib", + ], + "rust-analyzer.cargo.buildScripts.enable": false +} \ No newline at end of file diff --git a/esp-hal-common/Cargo.toml b/esp-hal-common/Cargo.toml index 6d9a1c25b..a66af238a 100644 --- a/esp-hal-common/Cargo.toml +++ b/esp-hal-common/Cargo.toml @@ -41,10 +41,10 @@ smart-leds-trait = { version = "0.2.1", optional = true } # # Please note: for now we use git-dependencies from the `with_source` branch however we pin the dependency # to specific commits. -esp32_pac = { package = "esp32", git = "https://github.com/esp-rs/esp-pacs.git", rev = "f5905f30f4796ed4da8fe333b6ed9700901c515b", optional = true } -esp32c3_pac = { package = "esp32c3", git = "https://github.com/esp-rs/esp-pacs.git", rev = "f5905f30f4796ed4da8fe333b6ed9700901c515b", optional = true } -esp32s2_pac = { package = "esp32s2", git = "https://github.com/esp-rs/esp-pacs.git", rev = "f5905f30f4796ed4da8fe333b6ed9700901c515b", optional = true } -esp32s3_pac = { package = "esp32s3", git = "https://github.com/esp-rs/esp-pacs.git", rev = "f5905f30f4796ed4da8fe333b6ed9700901c515b", optional = true } +esp32_pac = { package = "esp32", git = "https://github.com/esp-rs/esp-pacs.git", rev = "148dbb843cba3c311364aa994b8f3f773d15b04f", optional = true } +esp32c3_pac = { package = "esp32c3", git = "https://github.com/esp-rs/esp-pacs.git", rev = "148dbb843cba3c311364aa994b8f3f773d15b04f", optional = true } +esp32s2_pac = { package = "esp32s2", git = "https://github.com/esp-rs/esp-pacs.git", rev = "148dbb843cba3c311364aa994b8f3f773d15b04f", optional = true } +esp32s3_pac = { package = "esp32s3", git = "https://github.com/esp-rs/esp-pacs.git", rev = "148dbb843cba3c311364aa994b8f3f773d15b04f", optional = true } [features] esp32 = [ "esp32_pac/rt", "xtensa", "dual_core", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "smartled"] diff --git a/esp-hal-common/src/timer.rs b/esp-hal-common/src/timer.rs index 6cd1e2361..c9e0b9b19 100644 --- a/esp-hal-common/src/timer.rs +++ b/esp-hal-common/src/timer.rs @@ -1,13 +1,18 @@ //! General-purpose timers +use core::marker::PhantomData; + use embedded_hal::{ timer::{Cancel, CountDown, Periodic}, - watchdog::WatchdogDisable, + watchdog::{Watchdog, WatchdogDisable, WatchdogEnable}, }; use fugit::{MegahertzU32, MicrosDurationU64}; use void::Void; -use crate::pac::{timg0::RegisterBlock, TIMG0, TIMG1}; +use crate::{ + clock::Clocks, + pac::{timg0::RegisterBlock, TIMG0, TIMG1}, +}; /// Custom timer error type #[derive(Debug)] @@ -17,6 +22,67 @@ pub enum Error { AlarmInactive, } +// A timergroup consisting of up to 2 timers (chip dependent) and a watchdog +// timer +pub struct TimerGroup +where + T: TimerGroupInstance, +{ + pub timer0: Timer>, + #[cfg(not(feature = "esp32c3"))] + pub timer1: Timer>, + pub wdt: Wdt, +} + +pub trait TimerGroupInstance { + fn register_block() -> *const RegisterBlock; +} + +impl TimerGroupInstance for TIMG0 { + #[inline(always)] + fn register_block() -> *const RegisterBlock { + crate::pac::TIMG0::PTR + } +} + +impl TimerGroupInstance for TIMG1 { + #[inline(always)] + fn register_block() -> *const RegisterBlock { + crate::pac::TIMG1::PTR + } +} + +impl TimerGroup +where + T: TimerGroupInstance, +{ + pub fn new(_timer_group: T, clocks: &Clocks) -> Self { + let timer0 = Timer::new( + Timer0 { + phantom: PhantomData::default(), + }, + clocks.apb_clock, + ); + + #[cfg(not(feature = "esp32c3"))] + let timer1 = Timer::new( + Timer1 { + phantom: PhantomData::default(), + }, + clocks.apb_clock, + ); + + let wdt = Wdt::new(); + + Self { + timer0, + #[cfg(not(feature = "esp32c3"))] + timer1, + wdt, + } + } +} + /// General-purpose timer pub struct Timer { timg: T, @@ -50,11 +116,16 @@ where self.timg.unlisten(); } - /// Clear intterupt status + /// Clear interrupt status pub fn clear_interrupt(&mut self) { self.timg.clear_interrupt(); } + /// Check if the interrupt is asserted + pub fn is_interrupt_set(&self) -> bool { + self.timg.is_interrupt_set() + } + /// Read current raw timer value in timer ticks pub fn read_raw(&self) -> u64 { self.timg.read_raw() @@ -63,56 +134,92 @@ where /// Timer peripheral instance pub trait Instance { - fn register_block(&self) -> &RegisterBlock; + fn reset_counter(&mut self); + fn set_counter_active(&mut self, state: bool); + + fn is_counter_active(&self) -> bool; + + fn set_counter_decrementing(&mut self, decrementing: bool); + + fn set_auto_reload(&mut self, auto_reload: bool); + + fn set_alarm_active(&mut self, state: bool); + + fn is_alarm_active(&self) -> bool; + + fn load_alarm_value(&mut self, value: u64); + + fn listen(&mut self); + + fn unlisten(&mut self); + + fn clear_interrupt(&mut self); + + fn read_raw(&self) -> u64; + + fn divider(&self) -> u32; + + fn is_interrupt_set(&self) -> bool; +} + +pub struct Timer0 { + phantom: PhantomData, +} + +/// Timer peripheral instance +impl Instance for Timer0 +where + TG: TimerGroupInstance, +{ fn reset_counter(&mut self) { - let reg_block = self.register_block(); + let reg_block = unsafe { &*TG::register_block() }; - reg_block - .t0loadlo - .write(|w| unsafe { w.t0_load_lo().bits(0) }); + reg_block.t0loadlo.write(|w| unsafe { w.load_lo().bits(0) }); - reg_block - .t0loadhi - .write(|w| unsafe { w.t0_load_hi().bits(0) }); + reg_block.t0loadhi.write(|w| unsafe { w.load_hi().bits(0) }); - reg_block.t0load.write(|w| unsafe { w.t0_load().bits(1) }); + reg_block.t0load.write(|w| unsafe { w.load().bits(1) }); } fn set_counter_active(&mut self, state: bool) { - self.register_block() - .t0config - .modify(|_, w| w.t0_en().bit(state)); + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t0config.modify(|_, w| w.en().bit(state)); } fn is_counter_active(&self) -> bool { - self.register_block().t0config.read().t0_en().bit_is_set() + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t0config.read().en().bit_is_set() } fn set_counter_decrementing(&mut self, decrementing: bool) { - self.register_block() + let reg_block = unsafe { &*TG::register_block() }; + + reg_block .t0config - .modify(|_, w| w.t0_increase().bit(!decrementing)); + .modify(|_, w| w.increase().bit(!decrementing)); } fn set_auto_reload(&mut self, auto_reload: bool) { - self.register_block() + let reg_block = unsafe { &*TG::register_block() }; + + reg_block .t0config - .modify(|_, w| w.t0_autoreload().bit(auto_reload)); + .modify(|_, w| w.autoreload().bit(auto_reload)); } fn set_alarm_active(&mut self, state: bool) { - self.register_block() - .t0config - .modify(|_, w| w.t0_alarm_en().bit(state)); + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t0config.modify(|_, w| w.alarm_en().bit(state)); } fn is_alarm_active(&self) -> bool { - self.register_block() - .t0config - .read() - .t0_alarm_en() - .bit_is_set() + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t0config.read().alarm_en().bit_is_set() } fn load_alarm_value(&mut self, value: u64) { @@ -120,96 +227,211 @@ pub trait Instance { let high = (value >> 32) as u32; let low = (value & 0xFFFF_FFFF) as u32; - let reg_block = self.register_block(); + let reg_block = unsafe { &*TG::register_block() }; reg_block .t0alarmlo - .write(|w| unsafe { w.t0_alarm_lo().bits(low) }); + .write(|w| unsafe { w.alarm_lo().bits(low) }); reg_block .t0alarmhi - .write(|w| unsafe { w.t0_alarm_hi().bits(high) }); - } - - fn set_wdt_enabled(&mut self, enabled: bool) { - let reg_block = self.register_block(); - - reg_block - .wdtwprotect - .write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) }); - - if !enabled { - reg_block.wdtconfig0.write(|w| unsafe { w.bits(0) }); - } else { - reg_block.wdtconfig0.write(|w| w.wdt_en().bit(true)); - } - - reg_block - .wdtwprotect - .write(|w| unsafe { w.wdt_wkey().bits(0u32) }); + .write(|w| unsafe { w.alarm_hi().bits(high) }); } fn listen(&mut self) { + let reg_block = unsafe { &*TG::register_block() }; + // always use level interrupt #[cfg(any(feature = "esp32", feature = "esp32s2"))] - self.register_block() - .t0config - .modify(|_, w| w.t0_level_int_en().set_bit()); + reg_block.t0config.modify(|_, w| w.level_int_en().set_bit()); - self.register_block() + reg_block .int_ena_timers .modify(|_, w| w.t0_int_ena().set_bit()); } fn unlisten(&mut self) { - self.register_block() + let reg_block = unsafe { &*TG::register_block() }; + + reg_block .int_ena_timers .modify(|_, w| w.t0_int_ena().clear_bit()); } fn clear_interrupt(&mut self) { - self.register_block() - .int_clr_timers - .write(|w| w.t0_int_clr().set_bit()); + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.int_clr_timers.write(|w| w.t0_int_clr().set_bit()); } fn read_raw(&self) -> u64 { - self.register_block() - .t0update - .write(|w| unsafe { w.bits(0) }); + let reg_block = unsafe { &*TG::register_block() }; - let value_lo = self.register_block().t0lo.read().bits() as u64; - let value_hi = (self.register_block().t0hi.read().bits() as u64) << 32; + reg_block.t0update.write(|w| unsafe { w.bits(0) }); + + let value_lo = reg_block.t0lo.read().bits() as u64; + let value_hi = (reg_block.t0hi.read().bits() as u64) << 32; (value_lo | value_hi) as u64 } fn divider(&self) -> u32 { + let reg_block = unsafe { &*TG::register_block() }; + // From the ESP32 TRM, "11.2.1 16­-bit Prescaler and Clock Selection": // // "The prescaler can divide the APB clock by a factor from 2 to 65536. // Specifically, when TIMGn_Tx_DIVIDER is either 1 or 2, the clock divisor is 2; // when TIMGn_Tx_DIVIDER is 0, the clock divisor is 65536. Any other value will // cause the clock to be divided by exactly that value." - match self.register_block().t0config.read().t0_divider().bits() { + match reg_block.t0config.read().divider().bits() { 0 => 65536, 1 | 2 => 2, n => n as u32, } } -} -impl Instance for TIMG0 { - #[inline(always)] - fn register_block(&self) -> &RegisterBlock { - self + fn is_interrupt_set(&self) -> bool { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.int_raw_timers.read().t0_int_raw().bit_is_set() } } -impl Instance for TIMG1 { - #[inline(always)] - fn register_block(&self) -> &RegisterBlock { - self +#[cfg(not(feature = "esp32c3"))] +pub struct Timer1 { + phantom: PhantomData, +} + +/// Timer peripheral instance +#[cfg(not(feature = "esp32c3"))] +impl Instance for Timer1 +where + TG: TimerGroupInstance, +{ + fn reset_counter(&mut self) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t1loadlo.write(|w| unsafe { w.load_lo().bits(0) }); + + reg_block.t1loadhi.write(|w| unsafe { w.load_hi().bits(0) }); + + reg_block.t1load.write(|w| unsafe { w.load().bits(1) }); + } + + fn set_counter_active(&mut self, state: bool) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t1config.modify(|_, w| w.en().bit(state)); + } + + fn is_counter_active(&self) -> bool { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t1config.read().en().bit_is_set() + } + + fn set_counter_decrementing(&mut self, decrementing: bool) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .t1config + .modify(|_, w| w.increase().bit(!decrementing)); + } + + fn set_auto_reload(&mut self, auto_reload: bool) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .t1config + .modify(|_, w| w.autoreload().bit(auto_reload)); + } + + fn set_alarm_active(&mut self, state: bool) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t1config.modify(|_, w| w.alarm_en().bit(state)); + } + + fn is_alarm_active(&self) -> bool { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t1config.read().alarm_en().bit_is_set() + } + + fn load_alarm_value(&mut self, value: u64) { + let value = value & 0x3F_FFFF_FFFF_FFFF; + let high = (value >> 32) as u32; + let low = (value & 0xFFFF_FFFF) as u32; + + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .t1alarmlo + .write(|w| unsafe { w.alarm_lo().bits(low) }); + + reg_block + .t1alarmhi + .write(|w| unsafe { w.alarm_hi().bits(high) }); + } + + fn listen(&mut self) { + let reg_block = unsafe { &*TG::register_block() }; + + // always use level interrupt + #[cfg(any(feature = "esp32", feature = "esp32s2"))] + reg_block.t1config.modify(|_, w| w.level_int_en().set_bit()); + + reg_block + .int_ena_timers + .modify(|_, w| w.t1_int_ena().set_bit()); + } + + fn unlisten(&mut self) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .int_ena_timers + .modify(|_, w| w.t1_int_ena().clear_bit()); + } + + fn clear_interrupt(&mut self) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.int_clr_timers.write(|w| w.t1_int_clr().set_bit()); + } + + fn read_raw(&self) -> u64 { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.t1update.write(|w| unsafe { w.bits(0) }); + + let value_lo = reg_block.t1lo.read().bits() as u64; + let value_hi = (reg_block.t1hi.read().bits() as u64) << 32; + + (value_lo | value_hi) as u64 + } + + fn divider(&self) -> u32 { + let reg_block = unsafe { &*TG::register_block() }; + + // From the ESP32 TRM, "11.2.1 16­-bit Prescaler and Clock Selection": + // + // "The prescaler can divide the APB clock by a factor from 2 to 65536. + // Specifically, when TIMGn_Tx_DIVIDER is either 1 or 2, the clock divisor is 2; + // when TIMGn_Tx_DIVIDER is 0, the clock divisor is 65536. Any other value will + // cause the clock to be divided by exactly that value." + match reg_block.t1config.read().divider().bits() { + 0 => 65536, + 1 | 2 => 2, + n => n as u32, + } + } + + fn is_interrupt_set(&self) -> bool { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block.int_raw_timers.read().t1_int_raw().bit_is_set() } } @@ -261,10 +483,8 @@ where panic!("Called wait on an inactive timer!") } - let reg_block = self.timg.register_block(); - - if reg_block.int_raw_timers.read().t0_int_raw().bit_is_set() { - reg_block.int_clr_timers.write(|w| w.t0_int_clr().set_bit()); + if self.timg.is_interrupt_set() { + self.timg.clear_interrupt(); self.timg.set_alarm_active(true); Ok(()) @@ -295,11 +515,128 @@ where impl Periodic for Timer where T: Instance {} -impl WatchdogDisable for Timer +/// Watchdog timer +pub struct Wdt { + phantom: PhantomData, +} + +/// Watchdog driver +impl Wdt where - T: Instance, + TG: TimerGroupInstance, { - fn disable(&mut self) { - self.timg.set_wdt_enabled(false); + /// Create a new watchdog timer instance + pub fn new() -> Self { + Self { + phantom: PhantomData::default(), + } + } + + fn set_wdt_enabled(&mut self, enabled: bool) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .wdtwprotect + .write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) }); + + if !enabled { + reg_block.wdtconfig0.write(|w| unsafe { w.bits(0) }); + } else { + reg_block.wdtconfig0.write(|w| w.wdt_en().bit(true)); + } + + reg_block + .wdtwprotect + .write(|w| unsafe { w.wdt_wkey().bits(0u32) }); + } + + fn feed(&mut self) { + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .wdtwprotect + .write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) }); + + reg_block.wdtfeed.write(|w| unsafe { w.bits(1) }); + + reg_block + .wdtwprotect + .write(|w| unsafe { w.wdt_wkey().bits(0u32) }); + } + + fn set_timeout(&mut self, timeout: MicrosDurationU64) { + let timeout_raw = (timeout.to_nanos() * 10 / 125) as u32; + + let reg_block = unsafe { &*TG::register_block() }; + + reg_block + .wdtwprotect + .write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) }); + + reg_block + .wdtconfig1 + .write(|w| unsafe { w.wdt_clk_prescale().bits(1) }); + + reg_block + .wdtconfig2 + .write(|w| unsafe { w.wdt_stg0_hold().bits(timeout_raw) }); + + reg_block.wdtconfig0.write(|w| unsafe { + w.wdt_en() + .bit(true) + .wdt_stg0() + .bits(3) + .wdt_cpu_reset_length() + .bits(1) + .wdt_sys_reset_length() + .bits(1) + .wdt_stg1() + .bits(0) + .wdt_stg2() + .bits(0) + .wdt_stg3() + .bits(0) + }); + + #[cfg(feature = "esp32c3")] + reg_block + .wdtconfig0 + .modify(|_, w| w.wdt_conf_update_en().set_bit()); + + reg_block + .wdtwprotect + .write(|w| unsafe { w.wdt_wkey().bits(0u32) }); + } +} + +impl WatchdogDisable for Wdt +where + TG: TimerGroupInstance, +{ + fn disable(&mut self) { + self.set_wdt_enabled(false); + } +} + +impl WatchdogEnable for Wdt +where + TG: TimerGroupInstance, +{ + type Time = MicrosDurationU64; + + fn start(&mut self, period: T) + where + T: Into, + { + self.set_timeout(period.into()); + } +} + +impl Watchdog for Wdt +where + TG: TimerGroupInstance, +{ + fn feed(&mut self) { + self.feed(); } } diff --git a/esp32-hal/examples/adc.rs b/esp32-hal/examples/adc.rs index f949178fc..08e0e709b 100644 --- a/esp32-hal/examples/adc.rs +++ b/esp32-hal/examples/adc.rs @@ -11,9 +11,9 @@ use esp32_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use esp_println::println; use panic_halt as _; @@ -25,11 +25,12 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32-hal/examples/advanced_serial.rs b/esp32-hal/examples/advanced_serial.rs index f45b8186d..2fd725ae7 100644 --- a/esp32-hal/examples/advanced_serial.rs +++ b/esp32-hal/examples/advanced_serial.rs @@ -15,10 +15,10 @@ use esp32_hal::{ config::{Config, DataBits, Parity, StopBits}, TxRxPins, }, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use esp_println::println; use nb::block; @@ -31,11 +31,12 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let config = Config { diff --git a/esp32-hal/examples/blinky.rs b/esp32-hal/examples/blinky.rs index c3500711d..c4a893d73 100644 --- a/esp32-hal/examples/blinky.rs +++ b/esp32-hal/examples/blinky.rs @@ -6,9 +6,9 @@ use esp32_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -19,11 +19,12 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Set GPIO15 as an output, and set its state high initially. diff --git a/esp32-hal/examples/dac.rs b/esp32-hal/examples/dac.rs index 41be2590a..6d30e0ab6 100644 --- a/esp32-hal/examples/dac.rs +++ b/esp32-hal/examples/dac.rs @@ -11,9 +11,9 @@ use esp32_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -24,11 +24,12 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32-hal/examples/gpio_interrupt.rs b/esp32-hal/examples/gpio_interrupt.rs index d94c160e7..3ad53d2ec 100644 --- a/esp32-hal/examples/gpio_interrupt.rs +++ b/esp32-hal/examples/gpio_interrupt.rs @@ -10,11 +10,11 @@ use esp32_hal::{ interrupt, pac::{self, Peripherals, UART0}, prelude::*, + timer::TimerGroup, Cpu, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx::mutex::{Mutex, SpinLockMutex}; @@ -31,13 +31,15 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; + // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); let serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Set GPIO15 as an output, and set its state high initially. diff --git a/esp32-hal/examples/hello_rgb.rs b/esp32-hal/examples/hello_rgb.rs index 9446f9637..b761b9b27 100644 --- a/esp32-hal/examples/hello_rgb.rs +++ b/esp32-hal/examples/hello_rgb.rs @@ -17,11 +17,11 @@ use esp32_hal::{ clock::ClockControl, pac, prelude::*, + timer::TimerGroup, utils::{smartLedAdapter, SmartLedsAdapter}, Delay, PulseControl, RtcCntl, - Timer, IO, }; #[allow(unused_imports)] @@ -41,11 +41,12 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Configure RMT peripheral globally diff --git a/esp32-hal/examples/hello_world.rs b/esp32-hal/examples/hello_world.rs index b998d08a3..9bbe65f3a 100644 --- a/esp32-hal/examples/hello_world.rs +++ b/esp32-hal/examples/hello_world.rs @@ -3,7 +3,14 @@ use core::fmt::Write; -use esp32_hal::{clock::ClockControl, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; use nb::block; use panic_halt as _; use xtensa_lx_rt::entry; @@ -14,12 +21,14 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); timer0.start(1u64.secs()); diff --git a/esp32-hal/examples/i2c_display.rs b/esp32-hal/examples/i2c_display.rs index 03afcaf4e..b4cc87e72 100644 --- a/esp32-hal/examples/i2c_display.rs +++ b/esp32-hal/examples/i2c_display.rs @@ -27,9 +27,9 @@ use esp32_hal::{ i2c::I2C, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -42,12 +42,14 @@ fn main() -> ! { let mut system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable watchdog timer - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32-hal/examples/multicore.rs b/esp32-hal/examples/multicore.rs index b203f4c9b..aae6a0096 100644 --- a/esp32-hal/examples/multicore.rs +++ b/esp32-hal/examples/multicore.rs @@ -7,10 +7,11 @@ use esp32_hal::{ clock::ClockControl, pac::{Peripherals, TIMG1}, prelude::*, + timer::{Timer0, TimerGroup}, CpuControl, RtcCntl, - Timer, }; +use esp_hal_common::Timer; use esp_println::println; use nb::block; use panic_halt as _; @@ -27,13 +28,19 @@ fn _main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut timer1 = timer_group1.timer0; + let mut wdt1 = timer_group1.wdt; + let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); timer0.start(1u64.secs()); @@ -55,7 +62,10 @@ fn _main() -> ! { } } -fn cpu1_task(timer: &mut Timer, counter: &xtensa_lx::mutex::SpinLockMutex) -> ! { +fn cpu1_task( + timer: &mut Timer>, + counter: &xtensa_lx::mutex::SpinLockMutex, +) -> ! { println!("Hello World - Core 1!"); loop { block!(timer.wait()).unwrap(); diff --git a/esp32-hal/examples/ram.rs b/esp32-hal/examples/ram.rs index 4b69662fb..db3992911 100644 --- a/esp32-hal/examples/ram.rs +++ b/esp32-hal/examples/ram.rs @@ -8,8 +8,8 @@ use esp32_hal::{ pac::{Peripherals, UART0}, prelude::*, ram, + timer::TimerGroup, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -30,11 +30,13 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT flash boot protection - timer0.disable(); + wdt.disable(); // The RWDT flash boot protection remains enabled and it being triggered is part // of the example diff --git a/esp32-hal/examples/read_efuse.rs b/esp32-hal/examples/read_efuse.rs index 5d9a07156..642d4e3b7 100644 --- a/esp32-hal/examples/read_efuse.rs +++ b/esp32-hal/examples/read_efuse.rs @@ -8,9 +8,9 @@ use esp32_hal::{ efuse::Efuse, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -21,12 +21,13 @@ fn main() -> ! { let system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap(); diff --git a/esp32-hal/examples/serial_interrupts.rs b/esp32-hal/examples/serial_interrupts.rs index e37f5738c..238ebe95c 100644 --- a/esp32-hal/examples/serial_interrupts.rs +++ b/esp32-hal/examples/serial_interrupts.rs @@ -13,10 +13,10 @@ use esp32_hal::{ pac::{self, Peripherals, UART0}, prelude::*, serial::config::AtCmdConfig, + timer::TimerGroup, Cpu, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -33,14 +33,19 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; + let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); serial0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None)); diff --git a/esp32-hal/examples/spi_loopback.rs b/esp32-hal/examples/spi_loopback.rs index 9be90ae22..2ef374328 100644 --- a/esp32-hal/examples/spi_loopback.rs +++ b/esp32-hal/examples/spi_loopback.rs @@ -24,10 +24,10 @@ use esp32_hal::{ pac::Peripherals, prelude::*, spi::{Spi, SpiMode}, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -41,10 +41,11 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32-hal/examples/timer_interrupt.rs b/esp32-hal/examples/timer_interrupt.rs index b51adf18e..5ffad1e0a 100644 --- a/esp32-hal/examples/timer_interrupt.rs +++ b/esp32-hal/examples/timer_interrupt.rs @@ -8,20 +8,25 @@ use esp32_hal::{ interrupt, pac::{self, Peripherals, TIMG0, TIMG1, UART0}, prelude::*, + timer::{Timer0, Timer1, TimerGroup}, Cpu, RtcCntl, Serial, - Timer, }; +use esp_hal_common::Timer; use panic_halt as _; use xtensa_lx::mutex::{Mutex, SpinLockMutex}; use xtensa_lx_rt::entry; static mut SERIAL: SpinLockMutex>>> = SpinLockMutex::new(RefCell::new(None)); -static mut TIMER0: SpinLockMutex>>> = +static mut TIMER00: SpinLockMutex>>>> = SpinLockMutex::new(RefCell::new(None)); -static mut TIMER1: SpinLockMutex>>> = +static mut TIMER01: SpinLockMutex>>>> = + SpinLockMutex::new(RefCell::new(None)); +static mut TIMER10: SpinLockMutex>>>> = + SpinLockMutex::new(RefCell::new(None)); +static mut TIMER11: SpinLockMutex>>>> = SpinLockMutex::new(RefCell::new(None)); #[entry] @@ -31,14 +36,22 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer00 = timer_group0.timer0; + let mut timer01 = timer_group0.timer1; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut timer10 = timer_group1.timer0; + let mut timer11 = timer_group1.timer1; + let mut wdt1 = timer_group1.wdt; + let serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); interrupt::enable( @@ -46,21 +59,37 @@ fn main() -> ! { pac::Interrupt::TG0_T0_LEVEL, interrupt::CpuInterrupt::Interrupt20LevelPriority2, ); - timer0.start(500u64.millis()); - timer0.listen(); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG0_T1_LEVEL, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + timer00.start(500u64.millis()); + timer00.listen(); + timer01.start(2500u64.millis()); + timer01.listen(); interrupt::enable( Cpu::ProCpu, pac::Interrupt::TG1_T0_LEVEL, interrupt::CpuInterrupt::Interrupt23LevelPriority3, ); - timer1.start(1u64.secs()); - timer1.listen(); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG1_T1_LEVEL, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + timer10.start(1u64.secs()); + timer10.listen(); + timer11.start(3u64.secs()); + timer11.listen(); unsafe { (&SERIAL).lock(|data| (*data).replace(Some(serial0))); - (&TIMER0).lock(|data| (*data).replace(Some(timer0))); - (&TIMER1).lock(|data| (*data).replace(Some(timer1))); + (&TIMER00).lock(|data| (*data).replace(Some(timer00))); + (&TIMER01).lock(|data| (*data).replace(Some(timer01))); + (&TIMER10).lock(|data| (*data).replace(Some(timer10))); + (&TIMER11).lock(|data| (*data).replace(Some(timer11))); } unsafe { @@ -74,50 +103,84 @@ fn main() -> ! { #[no_mangle] pub fn level2_interrupt() { - unsafe { - (&SERIAL).lock(|data| { - let mut serial = data.borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt Level 2").ok(); - }); - } - interrupt::clear( Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt20LevelPriority2, ); unsafe { - (&TIMER0).lock(|data| { - let mut timer0 = data.borrow_mut(); - let timer0 = timer0.as_mut().unwrap(); - timer0.clear_interrupt(); - timer0.start(500u64.millis()); + (&TIMER00).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(500u64.millis()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 2 - Timer0").ok(); + }); + } + }); + + (&TIMER01).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(2500u64.millis()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 2 - Timer1").ok(); + }); + } }); } } #[no_mangle] pub fn level3_interrupt() { - unsafe { - (&SERIAL).lock(|data| { - let mut serial = data.borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt Level 3").ok(); - }); - } - interrupt::clear( Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt23LevelPriority3, ); unsafe { - (&TIMER1).lock(|data| { - let mut timer1 = data.borrow_mut(); - let timer1 = timer1.as_mut().unwrap(); - timer1.clear_interrupt(); - timer1.start(1u64.secs()); + (&TIMER10).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(1u64.secs()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 3 - Timer0").ok(); + }); + } + }); + + (&TIMER11).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(3u64.secs()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 3 - Timer1").ok(); + }); + } }); } } diff --git a/esp32-hal/examples/watchdog.rs b/esp32-hal/examples/watchdog.rs new file mode 100644 index 000000000..27a6df1f9 --- /dev/null +++ b/esp32-hal/examples/watchdog.rs @@ -0,0 +1,44 @@ +//! This demos the watchdog timer. +//! Basically the same as `hello_world` but if you remove the call to +//! `wdt.feed()` the watchdog will reset the system. + +#![no_std] +#![no_main] + +use core::fmt::Write; + +use esp32_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; +use nb::block; +use panic_halt as _; +use xtensa_lx_rt::entry; + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.DPORT.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; + let mut serial0 = Serial::new(peripherals.UART0); + let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); + + rtc_cntl.set_wdt_global_enable(false); + + wdt.start(2u64.secs()); + timer0.start(1u64.secs()); + + loop { + wdt.feed(); + writeln!(serial0, "Hello world!").unwrap(); + block!(timer0.wait()).unwrap(); + } +} diff --git a/esp32-hal/src/lib.rs b/esp32-hal/src/lib.rs index 72f495660..f6eda61d6 100644 --- a/esp32-hal/src/lib.rs +++ b/esp32-hal/src/lib.rs @@ -14,6 +14,7 @@ pub use esp_hal_common::{ ram, serial, spi, + timer, utils, Cpu, Delay, @@ -21,7 +22,6 @@ pub use esp_hal_common::{ Rng, RtcCntl, Serial, - Timer, }; pub use self::gpio::IO; diff --git a/esp32c3-hal/examples/adc.rs b/esp32c3-hal/examples/adc.rs index 31d3248a3..6d0a24925 100644 --- a/esp32c3-hal/examples/adc.rs +++ b/esp32c3-hal/examples/adc.rs @@ -13,9 +13,9 @@ use esp32c3_hal::{ pac::Peripherals, prelude::*, system::SystemExt, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use esp_println::println; use panic_halt as _; @@ -30,13 +30,15 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); let mut pin = io.pins.gpio2.into_analog(); diff --git a/esp32c3-hal/examples/advanced_serial.rs b/esp32c3-hal/examples/advanced_serial.rs index 900627fbf..ac0e73066 100644 --- a/esp32c3-hal/examples/advanced_serial.rs +++ b/esp32c3-hal/examples/advanced_serial.rs @@ -14,9 +14,9 @@ use esp32c3_hal::{ config::{Config, DataBits, Parity, StopBits}, TxRxPins, }, + timer::TimerGroup, RtcCntl, Serial, - Timer, IO, }; use esp_println::println; @@ -31,14 +31,17 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; // Disable watchdog timers rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); let config = Config { baudrate: 115200, diff --git a/esp32c3-hal/examples/blinky.rs b/esp32c3-hal/examples/blinky.rs index c856d6226..f737f6310 100644 --- a/esp32c3-hal/examples/blinky.rs +++ b/esp32c3-hal/examples/blinky.rs @@ -7,9 +7,9 @@ use esp32c3_hal::{ pac::Peripherals, prelude::*, system::SystemExt, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use panic_halt as _; use riscv_rt::entry; @@ -23,13 +23,15 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); // Set GPIO5 as an output, and set its state high initially. let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32c3-hal/examples/gpio_interrupt.rs b/esp32c3-hal/examples/gpio_interrupt.rs index 58a2047be..4fca90159 100644 --- a/esp32c3-hal/examples/gpio_interrupt.rs +++ b/esp32c3-hal/examples/gpio_interrupt.rs @@ -11,11 +11,11 @@ use esp32c3_hal::{ interrupt, pac::{self, Peripherals, UART0}, prelude::*, + timer::TimerGroup, Cpu, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use riscv_rt::entry; @@ -32,14 +32,16 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; let serial0 = Serial::new(peripherals.UART0); rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); // Set GPIO5 as an output let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32c3-hal/examples/hello_rgb.rs b/esp32c3-hal/examples/hello_rgb.rs index a658e5fc4..a4a3b41ec 100644 --- a/esp32c3-hal/examples/hello_rgb.rs +++ b/esp32c3-hal/examples/hello_rgb.rs @@ -16,11 +16,11 @@ use esp32c3_hal::{ pac, prelude::*, pulse_control::ClockSource, + timer::TimerGroup, utils::{smartLedAdapter, SmartLedsAdapter}, Delay, PulseControl, RtcCntl, - Timer, IO, }; #[allow(unused_imports)] @@ -40,13 +40,14 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); // Disable watchdogs rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); + wdt0.disable(); // Configure RMT peripheral globally let pulse = PulseControl::new( diff --git a/esp32c3-hal/examples/hello_world.rs b/esp32c3-hal/examples/hello_world.rs index 76ba788f2..031739cff 100644 --- a/esp32c3-hal/examples/hello_world.rs +++ b/esp32c3-hal/examples/hello_world.rs @@ -3,7 +3,14 @@ use core::fmt::Write; -use esp32c3_hal::{clock::ClockControl, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32c3_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; use nb::block; use panic_halt as _; use riscv_rt::entry; @@ -16,14 +23,17 @@ fn main() -> ! { let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut serial0 = Serial::new(peripherals.UART0); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; // Disable watchdog timers rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); timer0.start(1u64.secs()); diff --git a/esp32c3-hal/examples/i2c_display.rs b/esp32c3-hal/examples/i2c_display.rs index 9dd52534f..b68ac8349 100644 --- a/esp32c3-hal/examples/i2c_display.rs +++ b/esp32c3-hal/examples/i2c_display.rs @@ -25,8 +25,8 @@ use esp32c3_hal::{ i2c::I2C, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, - Timer, }; use nb::block; use panic_halt as _; @@ -40,14 +40,17 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; // Disable watchdog timers rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32c3-hal/examples/ram.rs b/esp32c3-hal/examples/ram.rs index 8a8572a00..4870bffc9 100644 --- a/esp32c3-hal/examples/ram.rs +++ b/esp32c3-hal/examples/ram.rs @@ -8,8 +8,8 @@ use esp32c3_hal::{ pac::{Peripherals, UART0}, prelude::*, ram, + timer::TimerGroup, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -30,11 +30,14 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT flash boot protection - timer0.disable(); + wdt0.disable(); // The RWDT flash boot protection remains enabled and it being triggered is part // of the example diff --git a/esp32c3-hal/examples/read_efuse.rs b/esp32c3-hal/examples/read_efuse.rs index 11de2a5e9..bcfec333d 100644 --- a/esp32c3-hal/examples/read_efuse.rs +++ b/esp32c3-hal/examples/read_efuse.rs @@ -8,9 +8,9 @@ use esp32c3_hal::{ efuse::Efuse, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use panic_halt as _; use riscv_rt::entry; @@ -23,14 +23,16 @@ fn main() -> ! { let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut serial0 = Serial::new(peripherals.UART0); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; // Disable watchdog timers rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap(); writeln!( diff --git a/esp32c3-hal/examples/serial_interrupts.rs b/esp32c3-hal/examples/serial_interrupts.rs index 15da3d458..6d7214ff4 100644 --- a/esp32c3-hal/examples/serial_interrupts.rs +++ b/esp32c3-hal/examples/serial_interrupts.rs @@ -14,10 +14,10 @@ use esp32c3_hal::{ pac::{self, Peripherals, UART0}, prelude::*, serial::config::AtCmdConfig, + timer::TimerGroup, Cpu, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -33,14 +33,17 @@ fn main() -> ! { let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut serial0 = Serial::new(peripherals.UART0); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; // Disable watchdog timers rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); serial0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None)); serial0.set_rx_fifo_full_threshold(30); diff --git a/esp32c3-hal/examples/spi_loopback.rs b/esp32c3-hal/examples/spi_loopback.rs index 08994a53b..3b66f5a7b 100644 --- a/esp32c3-hal/examples/spi_loopback.rs +++ b/esp32c3-hal/examples/spi_loopback.rs @@ -24,10 +24,10 @@ use esp32c3_hal::{ pac::Peripherals, prelude::*, spi::{Spi, SpiMode}, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use riscv_rt::entry; @@ -41,14 +41,17 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; + let mut serial0 = Serial::new(peripherals.UART0); rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio6; diff --git a/esp32c3-hal/examples/systimer.rs b/esp32c3-hal/examples/systimer.rs index f15a2ef57..d53315a9a 100644 --- a/esp32c3-hal/examples/systimer.rs +++ b/esp32c3-hal/examples/systimer.rs @@ -10,10 +10,10 @@ use esp32c3_hal::{ pac::{self, Peripherals, UART0}, prelude::*, systimer::{Alarm, SystemTimer, Target}, + timer::TimerGroup, Cpu, RtcCntl, Serial, - Timer, }; use panic_halt as _; use riscv_rt::entry; @@ -32,14 +32,17 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; + let mut serial0 = Serial::new(peripherals.UART0); rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); writeln!(serial0, "SYSTIMER Demo start!").ok(); diff --git a/esp32c3-hal/examples/timer_interrupt.rs b/esp32c3-hal/examples/timer_interrupt.rs index 788222232..89b6a4ca2 100644 --- a/esp32c3-hal/examples/timer_interrupt.rs +++ b/esp32c3-hal/examples/timer_interrupt.rs @@ -9,17 +9,18 @@ use esp32c3_hal::{ interrupt, pac::{self, Peripherals, TIMG0, TIMG1, UART0}, prelude::*, + timer::{Timer0, TimerGroup}, Cpu, RtcCntl, Serial, - Timer, }; +use esp_hal_common::Timer; use panic_halt as _; use riscv_rt::entry; static mut SERIAL: Mutex>>> = Mutex::new(RefCell::new(None)); -static mut TIMER0: Mutex>>> = Mutex::new(RefCell::new(None)); -static mut TIMER1: Mutex>>> = Mutex::new(RefCell::new(None)); +static mut TIMER0: Mutex>>>> = Mutex::new(RefCell::new(None)); +static mut TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); #[entry] fn main() -> ! { @@ -30,14 +31,19 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut timer1 = timer_group1.timer0; + let mut wdt1 = timer_group1.wdt; + let serial0 = Serial::new(peripherals.UART0); rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); interrupt::enable( Cpu::ProCpu, diff --git a/esp32c3-hal/examples/usb_serial_jtag.rs b/esp32c3-hal/examples/usb_serial_jtag.rs index 6f76da83b..926712cce 100644 --- a/esp32c3-hal/examples/usb_serial_jtag.rs +++ b/esp32c3-hal/examples/usb_serial_jtag.rs @@ -7,9 +7,9 @@ use esp32c3_hal::{ clock::ClockControl, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, UsbSerialJtag, }; use panic_halt as _; @@ -23,14 +23,16 @@ fn main() -> ! { let mut delay = Delay::new(&clocks); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; // Disable watchdog timers rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); loop { writeln!(UsbSerialJtag, "Hello world!").ok(); diff --git a/esp32c3-hal/examples/watchdog.rs b/esp32c3-hal/examples/watchdog.rs new file mode 100644 index 000000000..021b786ce --- /dev/null +++ b/esp32c3-hal/examples/watchdog.rs @@ -0,0 +1,49 @@ +//! This demos the watchdog timer. +//! Basically the same as `hello_world` but if you remove the call to +//! `wdt.feed()` the watchdog will reset the system. + +#![no_std] +#![no_main] + +use core::fmt::Write; + +use esp32c3_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; +use nb::block; +use panic_halt as _; +use riscv_rt::entry; + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); + let mut serial0 = Serial::new(peripherals.UART0); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; + + // Disable watchdog timers + rtc_cntl.set_super_wdt_enable(false); + rtc_cntl.set_wdt_enable(false); + wdt0.start(2u64.secs()); + wdt1.disable(); + + timer0.start(1u64.secs()); + + loop { + wdt0.feed(); + writeln!(serial0, "Hello world!").unwrap(); + block!(timer0.wait()).unwrap(); + } +} diff --git a/esp32c3-hal/src/lib.rs b/esp32c3-hal/src/lib.rs index 9f03c3371..2b305017c 100644 --- a/esp32c3-hal/src/lib.rs +++ b/esp32c3-hal/src/lib.rs @@ -17,13 +17,13 @@ pub use esp_hal_common::{ spi, system, systimer, + timer, utils, Cpu, Delay, PulseControl, Rng, Serial, - Timer, UsbSerialJtag, }; #[cfg(feature = "direct-boot")] diff --git a/esp32s2-hal/examples/adc.rs b/esp32s2-hal/examples/adc.rs index 86c4d0bb9..dbf238a47 100644 --- a/esp32s2-hal/examples/adc.rs +++ b/esp32s2-hal/examples/adc.rs @@ -11,9 +11,9 @@ use esp32s2_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use esp_println::println; use panic_halt as _; @@ -25,11 +25,12 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32s2-hal/examples/advanced_serial.rs b/esp32s2-hal/examples/advanced_serial.rs index 3613c11b7..934dc4365 100644 --- a/esp32s2-hal/examples/advanced_serial.rs +++ b/esp32s2-hal/examples/advanced_serial.rs @@ -16,10 +16,10 @@ use esp32s2_hal::{ config::{Config, DataBits, Parity, StopBits}, TxRxPins, }, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use esp_println::println; use panic_halt as _; @@ -31,11 +31,12 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let config = Config { diff --git a/esp32s2-hal/examples/blinky.rs b/esp32s2-hal/examples/blinky.rs index 2a2606669..a0fcca810 100644 --- a/esp32s2-hal/examples/blinky.rs +++ b/esp32s2-hal/examples/blinky.rs @@ -6,9 +6,9 @@ use esp32s2_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -19,11 +19,12 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Set GPIO4 as an output, and set its state high initially. diff --git a/esp32s2-hal/examples/dac.rs b/esp32s2-hal/examples/dac.rs index 07dd63ff4..7b055c928 100644 --- a/esp32s2-hal/examples/dac.rs +++ b/esp32s2-hal/examples/dac.rs @@ -11,9 +11,9 @@ use esp32s2_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -24,11 +24,12 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32s2-hal/examples/gpio_interrupt.rs b/esp32s2-hal/examples/gpio_interrupt.rs index 9740f8f02..06c4c6b88 100644 --- a/esp32s2-hal/examples/gpio_interrupt.rs +++ b/esp32s2-hal/examples/gpio_interrupt.rs @@ -10,11 +10,11 @@ use esp32s2_hal::{ interrupt, pac::{self, Peripherals, UART0}, prelude::*, + timer::TimerGroup, Cpu, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx::mutex::{CriticalSectionMutex, Mutex}; @@ -31,12 +31,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let serial0 = Serial::new(peripherals.UART0); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Set GPIO4 as an output, and set its state high initially. diff --git a/esp32s2-hal/examples/hello_rgb.rs b/esp32s2-hal/examples/hello_rgb.rs index 8e3d22886..0a39850d1 100644 --- a/esp32s2-hal/examples/hello_rgb.rs +++ b/esp32s2-hal/examples/hello_rgb.rs @@ -15,11 +15,11 @@ use esp32s2_hal::{ clock::ClockControl, pac::Peripherals, prelude::*, + timer::TimerGroup, utils::{smartLedAdapter, SmartLedsAdapter}, Delay, PulseControl, RtcCntl, - Timer, IO, }; #[allow(unused_imports)] @@ -39,11 +39,12 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Configure RMT peripheral globally diff --git a/esp32s2-hal/examples/hello_world.rs b/esp32s2-hal/examples/hello_world.rs index ff64306de..4721e0fc3 100644 --- a/esp32s2-hal/examples/hello_world.rs +++ b/esp32s2-hal/examples/hello_world.rs @@ -3,7 +3,14 @@ use core::fmt::Write; -use esp32s2_hal::{clock::ClockControl, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32s2_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; use nb::block; use panic_halt as _; use xtensa_lx_rt::entry; @@ -14,12 +21,14 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); timer0.start(1u64.secs()); diff --git a/esp32s2-hal/examples/i2c_display.rs b/esp32s2-hal/examples/i2c_display.rs index 22132997b..5c194efd2 100644 --- a/esp32s2-hal/examples/i2c_display.rs +++ b/esp32s2-hal/examples/i2c_display.rs @@ -27,9 +27,9 @@ use esp32s2_hal::{ i2c::I2C, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -42,12 +42,14 @@ fn main() -> ! { let mut system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable watchdog timer - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32s2-hal/examples/ram.rs b/esp32s2-hal/examples/ram.rs index 518bdd261..f21bf638d 100644 --- a/esp32s2-hal/examples/ram.rs +++ b/esp32s2-hal/examples/ram.rs @@ -8,8 +8,8 @@ use esp32s2_hal::{ pac::{Peripherals, UART0}, prelude::*, ram, + timer::TimerGroup, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -30,11 +30,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT flash boot protection - timer0.disable(); + wdt.disable(); // The RWDT flash boot protection remains enabled and it being triggered is part // of the example diff --git a/esp32s2-hal/examples/read_efuse.rs b/esp32s2-hal/examples/read_efuse.rs index e609df6c9..7c5a9bb3f 100644 --- a/esp32s2-hal/examples/read_efuse.rs +++ b/esp32s2-hal/examples/read_efuse.rs @@ -8,9 +8,9 @@ use esp32s2_hal::{ efuse::Efuse, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -21,12 +21,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap(); writeln!( diff --git a/esp32s2-hal/examples/serial_interrupts.rs b/esp32s2-hal/examples/serial_interrupts.rs index 2241d79fa..45799bbae 100644 --- a/esp32s2-hal/examples/serial_interrupts.rs +++ b/esp32s2-hal/examples/serial_interrupts.rs @@ -13,10 +13,10 @@ use esp32s2_hal::{ pac::{self, Peripherals, UART0}, prelude::*, serial::config::AtCmdConfig, + timer::TimerGroup, Cpu, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -33,14 +33,17 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); serial0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None)); diff --git a/esp32s2-hal/examples/spi_loopback.rs b/esp32s2-hal/examples/spi_loopback.rs index a3a17094b..25027d17f 100644 --- a/esp32s2-hal/examples/spi_loopback.rs +++ b/esp32s2-hal/examples/spi_loopback.rs @@ -24,10 +24,10 @@ use esp32s2_hal::{ pac::Peripherals, prelude::*, spi::{Spi, SpiMode}, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -41,10 +41,11 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32s2-hal/examples/systimer.rs b/esp32s2-hal/examples/systimer.rs index 797068efd..1abd7416d 100644 --- a/esp32s2-hal/examples/systimer.rs +++ b/esp32s2-hal/examples/systimer.rs @@ -9,11 +9,11 @@ use esp32s2_hal::{ pac::{self, Peripherals, UART0}, prelude::*, systimer::{Alarm, SystemTimer, Target}, + timer::TimerGroup, Cpu, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx::mutex::{CriticalSectionMutex, Mutex}; @@ -34,12 +34,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let syst = SystemTimer::new(peripherals.SYSTIMER); diff --git a/esp32s2-hal/examples/timer_interrupt.rs b/esp32s2-hal/examples/timer_interrupt.rs index 5364ac333..4d2f87633 100644 --- a/esp32s2-hal/examples/timer_interrupt.rs +++ b/esp32s2-hal/examples/timer_interrupt.rs @@ -8,20 +8,25 @@ use esp32s2_hal::{ interrupt, pac::{self, Peripherals, TIMG0, TIMG1, UART0}, prelude::*, + timer::{Timer0, Timer1, TimerGroup}, Cpu, RtcCntl, Serial, - Timer, }; +use esp_hal_common::Timer; use panic_halt as _; use xtensa_lx::mutex::{CriticalSectionMutex, Mutex}; use xtensa_lx_rt::entry; static mut SERIAL: CriticalSectionMutex>>> = CriticalSectionMutex::new(RefCell::new(None)); -static mut TIMER0: CriticalSectionMutex>>> = +static mut TIMER00: CriticalSectionMutex>>>> = CriticalSectionMutex::new(RefCell::new(None)); -static mut TIMER1: CriticalSectionMutex>>> = +static mut TIMER01: CriticalSectionMutex>>>> = + CriticalSectionMutex::new(RefCell::new(None)); +static mut TIMER10: CriticalSectionMutex>>>> = + CriticalSectionMutex::new(RefCell::new(None)); +static mut TIMER11: CriticalSectionMutex>>>> = CriticalSectionMutex::new(RefCell::new(None)); #[entry] @@ -31,14 +36,22 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer00 = timer_group0.timer0; + let mut timer01 = timer_group0.timer1; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut timer10 = timer_group1.timer0; + let mut timer11 = timer_group1.timer1; + let mut wdt1 = timer_group1.wdt; + let serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); interrupt::enable( @@ -46,21 +59,37 @@ fn main() -> ! { pac::Interrupt::TG0_T0_LEVEL, interrupt::CpuInterrupt::Interrupt20LevelPriority2, ); - timer0.start(500u64.millis()); - timer0.listen(); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG0_T1_LEVEL, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + timer00.start(500u64.millis()); + timer00.listen(); + timer01.start(2500u64.millis()); + timer01.listen(); interrupt::enable( Cpu::ProCpu, pac::Interrupt::TG1_T0_LEVEL, interrupt::CpuInterrupt::Interrupt23LevelPriority3, ); - timer1.start(1u64.secs()); - timer1.listen(); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG1_T1_LEVEL, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + timer10.start(1u64.secs()); + timer10.listen(); + timer11.start(3u64.secs()); + timer11.listen(); unsafe { (&SERIAL).lock(|data| (*data).replace(Some(serial0))); - (&TIMER0).lock(|data| (*data).replace(Some(timer0))); - (&TIMER1).lock(|data| (*data).replace(Some(timer1))); + (&TIMER00).lock(|data| (*data).replace(Some(timer00))); + (&TIMER01).lock(|data| (*data).replace(Some(timer01))); + (&TIMER10).lock(|data| (*data).replace(Some(timer10))); + (&TIMER11).lock(|data| (*data).replace(Some(timer11))); } unsafe { @@ -74,50 +103,84 @@ fn main() -> ! { #[no_mangle] pub fn level2_interrupt() { - unsafe { - (&SERIAL).lock(|data| { - let mut serial = data.borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt Level 2").ok(); - }); - } - interrupt::clear( Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt20LevelPriority2, ); unsafe { - (&TIMER0).lock(|data| { - let mut timer0 = data.borrow_mut(); - let timer0 = timer0.as_mut().unwrap(); - timer0.clear_interrupt(); - timer0.start(500u64.millis()); + (&TIMER00).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(500u64.millis()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 2 - Timer0").ok(); + }); + } + }); + + (&TIMER01).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(2500u64.millis()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 2 - Timer1").ok(); + }); + } }); } } #[no_mangle] pub fn level3_interrupt() { - unsafe { - (&SERIAL).lock(|data| { - let mut serial = data.borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt Level 3").ok(); - }); - } - interrupt::clear( Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt23LevelPriority3, ); unsafe { - (&TIMER1).lock(|data| { - let mut timer1 = data.borrow_mut(); - let timer1 = timer1.as_mut().unwrap(); - timer1.clear_interrupt(); - timer1.start(1u64.secs()); + (&TIMER10).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(1u64.secs()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 3 - Timer0").ok(); + }); + } + }); + + (&TIMER11).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(3u64.secs()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 3 - Timer1").ok(); + }); + } }); } } diff --git a/esp32s2-hal/examples/watchdog.rs b/esp32s2-hal/examples/watchdog.rs new file mode 100644 index 000000000..d6d8719e2 --- /dev/null +++ b/esp32s2-hal/examples/watchdog.rs @@ -0,0 +1,44 @@ +//! This demos the watchdog timer. +//! Basically the same as `hello_world` but if you remove the call to +//! `wdt.feed()` the watchdog will reset the system.#![no_std] + +#![no_std] +#![no_main] + +use core::fmt::Write; + +use esp32s2_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; +use nb::block; +use panic_halt as _; +use xtensa_lx_rt::entry; + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; + let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); + let mut serial0 = Serial::new(peripherals.UART0); + + wdt.start(2u64.secs()); + rtc_cntl.set_wdt_global_enable(false); + + timer0.start(1u64.secs()); + + loop { + wdt.feed(); + writeln!(serial0, "Hello world!").unwrap(); + block!(timer0.wait()).unwrap(); + } +} diff --git a/esp32s2-hal/src/lib.rs b/esp32s2-hal/src/lib.rs index ec2530be9..d5769dcd7 100644 --- a/esp32s2-hal/src/lib.rs +++ b/esp32s2-hal/src/lib.rs @@ -14,6 +14,7 @@ pub use esp_hal_common::{ serial, spi, systimer, + timer, utils, Cpu, Delay, @@ -21,7 +22,6 @@ pub use esp_hal_common::{ Rng, RtcCntl, Serial, - Timer, }; pub use self::gpio::IO; diff --git a/esp32s3-hal/examples/advanced_serial.rs b/esp32s3-hal/examples/advanced_serial.rs index 69332e512..93e40f9de 100644 --- a/esp32s3-hal/examples/advanced_serial.rs +++ b/esp32s3-hal/examples/advanced_serial.rs @@ -16,10 +16,10 @@ use esp32s3_hal::{ config::{Config, DataBits, Parity, StopBits}, TxRxPins, }, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use esp_println::println; use panic_halt as _; @@ -31,11 +31,12 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let config = Config { diff --git a/esp32s3-hal/examples/blinky.rs b/esp32s3-hal/examples/blinky.rs index 3a1c5eb52..316b96e68 100644 --- a/esp32s3-hal/examples/blinky.rs +++ b/esp32s3-hal/examples/blinky.rs @@ -6,9 +6,9 @@ use esp32s3_hal::{ gpio::IO, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -19,11 +19,12 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Set GPIO4 as an output, and set its state high initially. diff --git a/esp32s3-hal/examples/gpio_interrupt.rs b/esp32s3-hal/examples/gpio_interrupt.rs index 1d6c03a08..33f885420 100644 --- a/esp32s3-hal/examples/gpio_interrupt.rs +++ b/esp32s3-hal/examples/gpio_interrupt.rs @@ -10,11 +10,11 @@ use esp32s3_hal::{ interrupt, pac::{self, Peripherals, UART0}, prelude::*, + timer::TimerGroup, Cpu, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx::mutex::{Mutex, SpinLockMutex}; @@ -31,12 +31,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let serial0 = Serial::new(peripherals.UART0); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Set GPIO4 as an output, and set its state high initially. diff --git a/esp32s3-hal/examples/hello_rgb.rs b/esp32s3-hal/examples/hello_rgb.rs index 04633a52a..93c46788a 100644 --- a/esp32s3-hal/examples/hello_rgb.rs +++ b/esp32s3-hal/examples/hello_rgb.rs @@ -16,11 +16,11 @@ use esp32s3_hal::{ pac::Peripherals, prelude::*, pulse_control::ClockSource, + timer::TimerGroup, utils::{smartLedAdapter, SmartLedsAdapter}, Delay, PulseControl, RtcCntl, - Timer, IO, }; #[allow(unused_imports)] @@ -40,11 +40,12 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); // Configure RMT peripheral globally diff --git a/esp32s3-hal/examples/hello_world.rs b/esp32s3-hal/examples/hello_world.rs index 6a14d7b08..42c1a66ed 100644 --- a/esp32s3-hal/examples/hello_world.rs +++ b/esp32s3-hal/examples/hello_world.rs @@ -3,7 +3,14 @@ use core::fmt::Write; -use esp32s3_hal::{clock::ClockControl, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32s3_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; use nb::block; use panic_halt as _; use xtensa_lx_rt::entry; @@ -14,12 +21,14 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); timer0.start(1u64.secs()); diff --git a/esp32s3-hal/examples/i2c_display.rs b/esp32s3-hal/examples/i2c_display.rs index 8a4374d99..d35f3464f 100644 --- a/esp32s3-hal/examples/i2c_display.rs +++ b/esp32s3-hal/examples/i2c_display.rs @@ -27,9 +27,9 @@ use esp32s3_hal::{ i2c::I2C, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -42,12 +42,14 @@ fn main() -> ! { let mut system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable watchdog timer - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32s3-hal/examples/multicore.rs b/esp32s3-hal/examples/multicore.rs index 8c4d3a50a..32a58a1ec 100644 --- a/esp32s3-hal/examples/multicore.rs +++ b/esp32s3-hal/examples/multicore.rs @@ -7,10 +7,11 @@ use esp32s3_hal::{ clock::ClockControl, pac::{Peripherals, TIMG1}, prelude::*, + timer::{Timer0, TimerGroup}, CpuControl, RtcCntl, - Timer, }; +use esp_hal_common::Timer; use esp_println::println; use nb::block; use panic_halt as _; @@ -23,13 +24,19 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut timer1 = timer_group1.timer0; + let mut wdt1 = timer_group1.wdt; + let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); timer0.start(1u64.secs()); @@ -51,7 +58,10 @@ fn main() -> ! { } } -fn cpu1_task(timer: &mut Timer, counter: &xtensa_lx::mutex::SpinLockMutex) -> ! { +fn cpu1_task( + timer: &mut Timer>, + counter: &xtensa_lx::mutex::SpinLockMutex, +) -> ! { println!("Hello World - Core 1!"); loop { block!(timer.wait()).unwrap(); diff --git a/esp32s3-hal/examples/ram.rs b/esp32s3-hal/examples/ram.rs index af4e644ff..1c719b375 100644 --- a/esp32s3-hal/examples/ram.rs +++ b/esp32s3-hal/examples/ram.rs @@ -8,8 +8,8 @@ use esp32s3_hal::{ pac::{Peripherals, UART0}, prelude::*, ram, + timer::TimerGroup, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -30,11 +30,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); // Disable MWDT flash boot protection - timer0.disable(); + wdt.disable(); // The RWDT flash boot protection remains enabled and it being triggered is part // of the example diff --git a/esp32s3-hal/examples/read_efuse.rs b/esp32s3-hal/examples/read_efuse.rs index f98cb4005..5a0b45498 100644 --- a/esp32s3-hal/examples/read_efuse.rs +++ b/esp32s3-hal/examples/read_efuse.rs @@ -8,9 +8,9 @@ use esp32s3_hal::{ efuse::Efuse, pac::Peripherals, prelude::*, + timer::TimerGroup, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -21,12 +21,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap(); writeln!( diff --git a/esp32s3-hal/examples/serial_interrupts.rs b/esp32s3-hal/examples/serial_interrupts.rs index 1822b1bbc..88dcbc165 100644 --- a/esp32s3-hal/examples/serial_interrupts.rs +++ b/esp32s3-hal/examples/serial_interrupts.rs @@ -13,10 +13,10 @@ use esp32s3_hal::{ pac::{self, Peripherals, UART0}, prelude::*, serial::config::AtCmdConfig, + timer::TimerGroup, Cpu, RtcCntl, Serial, - Timer, }; use nb::block; use panic_halt as _; @@ -33,14 +33,19 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut wdt1 = timer_group1.wdt; + let mut serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); serial0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None)); diff --git a/esp32s3-hal/examples/spi_loopback.rs b/esp32s3-hal/examples/spi_loopback.rs index 2ae18d2a6..8937456b2 100644 --- a/esp32s3-hal/examples/spi_loopback.rs +++ b/esp32s3-hal/examples/spi_loopback.rs @@ -24,10 +24,10 @@ use esp32s3_hal::{ pac::Peripherals, prelude::*, spi::{Spi, SpiMode}, + timer::TimerGroup, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx_rt::entry; @@ -41,10 +41,11 @@ fn main() -> ! { // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut serial0 = Serial::new(peripherals.UART0); - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); diff --git a/esp32s3-hal/examples/systimer.rs b/esp32s3-hal/examples/systimer.rs index 9eaf000da..1aea536f9 100644 --- a/esp32s3-hal/examples/systimer.rs +++ b/esp32s3-hal/examples/systimer.rs @@ -9,11 +9,11 @@ use esp32s3_hal::{ pac::{self, Peripherals, UART0}, prelude::*, systimer::{Alarm, SystemTimer, Target}, + timer::TimerGroup, Cpu, Delay, RtcCntl, Serial, - Timer, }; use panic_halt as _; use xtensa_lx::mutex::{Mutex, SpinLockMutex}; @@ -34,12 +34,13 @@ fn main() -> ! { let system = peripherals.SYSTEM.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let serial0 = Serial::new(peripherals.UART0); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); let syst = SystemTimer::new(peripherals.SYSTIMER); diff --git a/esp32s3-hal/examples/timer_interrupt.rs b/esp32s3-hal/examples/timer_interrupt.rs index a7db2d3c5..ac40be7e9 100644 --- a/esp32s3-hal/examples/timer_interrupt.rs +++ b/esp32s3-hal/examples/timer_interrupt.rs @@ -8,20 +8,25 @@ use esp32s3_hal::{ interrupt, pac::{self, Peripherals, TIMG0, TIMG1, UART0}, prelude::*, + timer::{Timer0, Timer1, TimerGroup}, Cpu, RtcCntl, Serial, - Timer, }; +use esp_hal_common::Timer; use panic_halt as _; use xtensa_lx::mutex::{Mutex, SpinLockMutex}; use xtensa_lx_rt::entry; static mut SERIAL: SpinLockMutex>>> = SpinLockMutex::new(RefCell::new(None)); -static mut TIMER0: SpinLockMutex>>> = +static mut TIMER00: SpinLockMutex>>>> = SpinLockMutex::new(RefCell::new(None)); -static mut TIMER1: SpinLockMutex>>> = +static mut TIMER01: SpinLockMutex>>>> = + SpinLockMutex::new(RefCell::new(None)); +static mut TIMER10: SpinLockMutex>>>> = + SpinLockMutex::new(RefCell::new(None)); +static mut TIMER11: SpinLockMutex>>>> = SpinLockMutex::new(RefCell::new(None)); #[entry] @@ -31,14 +36,22 @@ fn main() -> ! { let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); - let mut timer1 = Timer::new(peripherals.TIMG1, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer00 = timer_group0.timer0; + let mut timer01 = timer_group0.timer1; + let mut wdt0 = timer_group0.wdt; + + let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); + let mut timer10 = timer_group1.timer0; + let mut timer11 = timer_group1.timer1; + let mut wdt1 = timer_group1.wdt; + let serial0 = Serial::new(peripherals.UART0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); - timer1.disable(); + wdt0.disable(); + wdt1.disable(); rtc_cntl.set_wdt_global_enable(false); interrupt::enable( @@ -46,21 +59,37 @@ fn main() -> ! { pac::Interrupt::TG0_T0_LEVEL, interrupt::CpuInterrupt::Interrupt20LevelPriority2, ); - timer0.start(500u64.millis()); - timer0.listen(); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG0_T1_LEVEL, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + timer00.start(500u64.millis()); + timer00.listen(); + timer01.start(2500u64.millis()); + timer01.listen(); interrupt::enable( Cpu::ProCpu, pac::Interrupt::TG1_T0_LEVEL, interrupt::CpuInterrupt::Interrupt23LevelPriority3, ); - timer1.start(1u64.secs()); - timer1.listen(); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG1_T1_LEVEL, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + timer10.start(1u64.secs()); + timer10.listen(); + timer11.start(3u64.secs()); + timer11.listen(); unsafe { (&SERIAL).lock(|data| (*data).replace(Some(serial0))); - (&TIMER0).lock(|data| (*data).replace(Some(timer0))); - (&TIMER1).lock(|data| (*data).replace(Some(timer1))); + (&TIMER00).lock(|data| (*data).replace(Some(timer00))); + (&TIMER01).lock(|data| (*data).replace(Some(timer01))); + (&TIMER10).lock(|data| (*data).replace(Some(timer10))); + (&TIMER11).lock(|data| (*data).replace(Some(timer11))); } unsafe { @@ -74,50 +103,84 @@ fn main() -> ! { #[no_mangle] pub fn level2_interrupt() { - unsafe { - (&SERIAL).lock(|data| { - let mut serial = data.borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt Level 2").ok(); - }); - } - interrupt::clear( Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt20LevelPriority2, ); unsafe { - (&TIMER0).lock(|data| { - let mut timer0 = data.borrow_mut(); - let timer0 = timer0.as_mut().unwrap(); - timer0.clear_interrupt(); - timer0.start(500u64.millis()); + (&TIMER00).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(500u64.millis()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 2 - Timer0").ok(); + }); + } + }); + + (&TIMER01).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(2500u64.millis()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 2 - Timer1").ok(); + }); + } }); } } #[no_mangle] pub fn level3_interrupt() { - unsafe { - (&SERIAL).lock(|data| { - let mut serial = data.borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt Level 3").ok(); - }); - } - interrupt::clear( Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt23LevelPriority3, ); unsafe { - (&TIMER1).lock(|data| { - let mut timer1 = data.borrow_mut(); - let timer1 = timer1.as_mut().unwrap(); - timer1.clear_interrupt(); - timer1.start(1u64.secs()); + (&TIMER10).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(1u64.secs()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 3 - Timer0").ok(); + }); + } + }); + + (&TIMER11).lock(|data| { + let mut timer = data.borrow_mut(); + let timer = timer.as_mut().unwrap(); + + if timer.is_interrupt_set() { + timer.clear_interrupt(); + timer.start(3u64.secs()); + + (&SERIAL).lock(|data| { + let mut serial = data.borrow_mut(); + let serial = serial.as_mut().unwrap(); + writeln!(serial, "Interrupt Level 3 - Timer1").ok(); + }); + } }); } } diff --git a/esp32s3-hal/examples/usb_serial_jtag.rs b/esp32s3-hal/examples/usb_serial_jtag.rs index 5745ccaba..d0e0a0c07 100644 --- a/esp32s3-hal/examples/usb_serial_jtag.rs +++ b/esp32s3-hal/examples/usb_serial_jtag.rs @@ -7,9 +7,9 @@ use esp32s3_hal::{ clock::ClockControl, pac::Peripherals, prelude::*, + timer::TimerGroup, Delay, RtcCntl, - Timer, UsbSerialJtag, }; use panic_halt as _; @@ -23,10 +23,11 @@ fn main() -> ! { let mut delay = Delay::new(&clocks); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); - let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock); + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; // Disable MWDT and RWDT (Watchdog) flash boot protection - timer0.disable(); + wdt.disable(); rtc_cntl.set_wdt_global_enable(false); loop { diff --git a/esp32s3-hal/examples/watchdog.rs b/esp32s3-hal/examples/watchdog.rs new file mode 100644 index 000000000..222585526 --- /dev/null +++ b/esp32s3-hal/examples/watchdog.rs @@ -0,0 +1,44 @@ +//! This demos the watchdog timer. +//! Basically the same as `hello_world` but if you remove the call to +//! `wdt.feed()` the watchdog will reset the system.#![no_std] + +#![no_std] +#![no_main] + +use core::fmt::Write; + +use esp32s3_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + timer::TimerGroup, + RtcCntl, + Serial, +}; +use nb::block; +use panic_halt as _; +use xtensa_lx_rt::entry; + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut timer0 = timer_group0.timer0; + let mut wdt = timer_group0.wdt; + let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); + let mut serial0 = Serial::new(peripherals.UART0); + + wdt.start(2u64.secs()); + rtc_cntl.set_wdt_global_enable(false); + + timer0.start(1u64.secs()); + + loop { + wdt.feed(); + writeln!(serial0, "Hello world!").unwrap(); + block!(timer0.wait()).unwrap(); + } +} diff --git a/esp32s3-hal/src/lib.rs b/esp32s3-hal/src/lib.rs index fe3a035a7..dd8bcfa9e 100644 --- a/esp32s3-hal/src/lib.rs +++ b/esp32s3-hal/src/lib.rs @@ -15,6 +15,7 @@ pub use esp_hal_common::{ serial, spi, systimer, + timer, usb_serial_jtag, utils, Cpu, @@ -23,7 +24,6 @@ pub use esp_hal_common::{ Rng, RtcCntl, Serial, - Timer, UsbSerialJtag, };