diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index 1ea6bd258..fc4b294df 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -272,7 +272,7 @@ extern "C" fn EspDefaultHandler(_interrupt: peripherals::Interrupt) { ); } -/// A marker trait for intializing drivers in a specific mode. +/// A marker trait for initializing drivers in a specific mode. pub trait Mode: crate::private::Sealed {} /// Driver initialized in blocking mode. @@ -766,9 +766,9 @@ pub fn init(config: Config) -> Peripherals { rtc.rwdt.disable(); unsafe { - crate::timer::timg::Wdt::::set_wdt_enabled(false); + crate::timer::timg::Wdt::::set_wdt_enabled(false); #[cfg(timg1)] - crate::timer::timg::Wdt::::set_wdt_enabled(false); + crate::timer::timg::Wdt::::set_wdt_enabled(false); } Clocks::init(config.cpu_clock); diff --git a/esp-hal/src/timer/timg.rs b/esp-hal/src/timer/timg.rs index 3323c97ec..3c1c54460 100644 --- a/esp-hal/src/timer/timg.rs +++ b/esp-hal/src/timer/timg.rs @@ -71,8 +71,6 @@ use core::{ use fugit::{HertzU32, Instant, MicrosDurationU64}; use super::Error; -#[cfg(timg1)] -use crate::peripherals::TIMG1; #[cfg(any(esp32c6, esp32h2))] use crate::soc::constants::TIMG_DEFAULT_CLK_SRC; use crate::{ @@ -92,8 +90,10 @@ use crate::{ static INT_ENA_LOCK: LockState = LockState::new(); -/// A timer group consisting of up to 2 timers (chip dependent) and a watchdog -/// timer. +/// A timer group consisting of +#[cfg_attr(not(timg_timer1), doc = "a general purpose timer")] +#[cfg_attr(timg_timer1, doc = "2 timers")] +/// and a watchdog timer. pub struct TimerGroup<'d, T, DM> where T: TimerGroupInstance, @@ -106,7 +106,7 @@ where #[cfg(timg_timer1)] pub timer1: Timer, DM>, /// Watchdog timer - pub wdt: Wdt, + pub wdt: Wdt, } #[doc(hidden)] @@ -117,6 +117,7 @@ pub trait TimerGroupInstance { fn enable_peripheral(); fn reset_peripheral(); fn configure_wdt_src_clk(); + fn wdt_interrupt() -> Interrupt; } impl TimerGroupInstance for TIMG0 { @@ -126,32 +127,26 @@ impl TimerGroupInstance for TIMG0 { #[inline(always)] fn register_block() -> *const RegisterBlock { - TIMG0::PTR + Self::PTR } - #[inline(always)] - #[cfg(any(esp32c6, esp32h2))] fn configure_src_clk() { - unsafe { &*crate::peripherals::PCR::PTR } - .timergroup0_timer_clk_conf() - .modify(|_, w| unsafe { w.tg0_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); - } - - #[inline(always)] - #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] - fn configure_src_clk() { - unsafe { - (*Self::register_block()) - .t(0) - .config() - .modify(|_, w| w.use_xtal().clear_bit()) - }; - } - - #[inline(always)] - #[cfg(esp32)] - fn configure_src_clk() { - // ESP32 has only APB clock source, do nothing + cfg_if::cfg_if! { + if #[cfg(esp32)] { + // ESP32 has only APB clock source, do nothing + } else if #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] { + unsafe { + (*Self::register_block()) + .t(0) + .config() + .modify(|_, w| w.use_xtal().clear_bit()); + } + } else if #[cfg(any(esp32c6, esp32h2))] { + unsafe { &*crate::peripherals::PCR::PTR } + .timergroup0_timer_clk_conf() + .modify(|_, w| unsafe { w.tg0_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); + } + } } fn enable_peripheral() { @@ -159,101 +154,94 @@ impl TimerGroupInstance for TIMG0 { } fn reset_peripheral() { - // for TIMG0 do nothing for now because the reset breaks `time::now` + // FIXME: for TIMG0 do nothing for now because the reset breaks + // `time::now` } - #[inline(always)] - #[cfg(any(esp32c2, esp32c3))] fn configure_wdt_src_clk() { - unsafe { - (*Self::register_block()) - .wdtconfig0() - .modify(|_, w| w.wdt_use_xtal().clear_bit()) - }; + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2, esp32s3))] { + // ESP32, ESP32-S2, and ESP32-S3 use only ABP, do nothing + } else if #[cfg(any(esp32c2, esp32c3))] { + unsafe { + (*Self::register_block()) + .wdtconfig0() + .modify(|_, w| w.wdt_use_xtal().clear_bit()); + } + } else if #[cfg(any(esp32c6, esp32h2))] { + unsafe { &*crate::peripherals::PCR::PTR } + .timergroup0_wdt_clk_conf() + .modify(|_, w| unsafe { w.tg0_wdt_clk_sel().bits(1) }); + } + } } - #[inline(always)] - #[cfg(any(esp32c6, esp32h2))] - fn configure_wdt_src_clk() { - unsafe { &*crate::peripherals::PCR::PTR } - .timergroup0_wdt_clk_conf() - .modify(|_, w| unsafe { w.tg0_wdt_clk_sel().bits(1) }); - } - - #[inline(always)] - #[cfg(any(esp32, esp32s2, esp32s3))] - fn configure_wdt_src_clk() { - // ESP32, ESP32-S2, and ESP32-S3 use only ABP, do nothing + fn wdt_interrupt() -> Interrupt { + Interrupt::TG0_WDT_LEVEL } } #[cfg(timg1)] -impl TimerGroupInstance for TIMG1 { +impl TimerGroupInstance for crate::peripherals::TIMG1 { fn id() -> u8 { 1 } #[inline(always)] fn register_block() -> *const RegisterBlock { - TIMG1::PTR + Self::PTR } - #[inline(always)] - #[cfg(any(esp32c6, esp32h2))] fn configure_src_clk() { - unsafe { &*crate::peripherals::PCR::PTR } - .timergroup1_timer_clk_conf() - .modify(|_, w| unsafe { w.tg1_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32c2, esp32c3))] { + // ESP32 has only APB clock source, do nothing + // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing + } else if #[cfg(any(esp32c6, esp32h2))] { + unsafe { &*crate::peripherals::PCR::PTR } + .timergroup1_timer_clk_conf() + .modify(|_, w| unsafe { w.tg1_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); + } else if #[cfg(any(esp32s2, esp32s3))] { + unsafe { + (*Self::register_block()) + .t(1) + .config() + .modify(|_, w| w.use_xtal().clear_bit()); + } + } + } } - #[inline(always)] - #[cfg(any(esp32s2, esp32s3))] - fn configure_src_clk() { - unsafe { - (*Self::register_block()) - .t(1) - .config() - .modify(|_, w| w.use_xtal().clear_bit()) - }; - } - - #[inline(always)] - #[cfg(any(esp32, esp32c2, esp32c3))] - fn configure_src_clk() { - // ESP32 has only APB clock source, do nothing - // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing - } - - #[inline(always)] fn enable_peripheral() { crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg1) } - #[inline(always)] fn reset_peripheral() { crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Timg1) } - #[inline(always)] - #[cfg(any(esp32c6, esp32h2))] fn configure_wdt_src_clk() { - unsafe { &*crate::peripherals::PCR::PTR } - .timergroup1_wdt_clk_conf() - .modify(|_, w| unsafe { w.tg1_wdt_clk_sel().bits(1) }); + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2, esp32s3, esp32c2, esp32c3))] { + // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing + // ESP32, ESP32-S2, and ESP32-S3 use only ABP, do nothing + } else if #[cfg(any(esp32c6, esp32h2))] { + unsafe { &*crate::peripherals::PCR::PTR } + .timergroup1_wdt_clk_conf() + .modify(|_, w| unsafe { w.tg1_wdt_clk_sel().bits(1) }); + } + } } - #[inline(always)] - #[cfg(any(esp32, esp32s2, esp32s3, esp32c2, esp32c3))] - fn configure_wdt_src_clk() { - // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing - // ESP32, ESP32-S2, and ESP32-S3 use only ABP, do nothing + fn wdt_interrupt() -> Interrupt { + Interrupt::TG1_WDT_LEVEL } } impl<'d, T, DM> TimerGroup<'d, T, DM> where T: TimerGroupInstance, - DM: crate::Mode, + DM: Mode, { /// Construct a new instance of [`TimerGroup`] in blocking mode pub fn new_inner(_timer_group: impl Peripheral

+ 'd) -> Self { @@ -605,13 +593,6 @@ pub struct TimerX { phantom: PhantomData, } -/// Timer 0 in the Timer Group. -pub type Timer0 = TimerX; - -/// Timer 1 in the Timer Group. -#[cfg(timg_timer1)] -pub type Timer1 = TimerX; - impl Sealed for TimerX {} impl TimerX @@ -624,7 +605,6 @@ where /// /// You must ensure that you're only using one instance of this type at a /// time. - #[allow(unused)] pub unsafe fn steal() -> Self { Self { phantom: PhantomData, @@ -774,6 +754,13 @@ where } } +/// Timer 0 in the Timer Group. +pub type Timer0 = TimerX; + +/// Timer 1 in the Timer Group. +#[cfg(timg_timer1)] +pub type Timer1 = TimerX; + impl Enable for Timer0 where TG: TimerGroupInstance, @@ -873,15 +860,14 @@ where } /// Watchdog timer -pub struct Wdt { - phantom: PhantomData<(TG, DM)>, +pub struct Wdt { + phantom: PhantomData, } /// Watchdog driver -impl Wdt +impl Wdt where TG: TimerGroupInstance, - DM: Mode, { /// Construct a new instance of [`Wdt`] pub fn new() -> Self { @@ -996,24 +982,14 @@ where } } -impl crate::private::Sealed for Wdt -where - TG: TimerGroupInstance, - DM: Mode, -{ -} +impl crate::private::Sealed for Wdt where TG: TimerGroupInstance {} -impl InterruptConfigurable for Wdt +impl InterruptConfigurable for Wdt where TG: TimerGroupInstance, { fn set_interrupt_handler(&mut self, handler: interrupt::InterruptHandler) { - let interrupt = match TG::id() { - 0 => Interrupt::TG0_WDT_LEVEL, - #[cfg(timg1)] - 1 => Interrupt::TG1_WDT_LEVEL, - _ => unreachable!(), - }; + let interrupt = TG::wdt_interrupt(); unsafe { interrupt::bind_interrupt(interrupt, handler.handler()); interrupt::enable(interrupt, handler.priority()).unwrap(); @@ -1021,30 +997,27 @@ where } } -impl Default for Wdt +impl Default for Wdt where TG: TimerGroupInstance, - DM: Mode, { fn default() -> Self { Self::new() } } -impl embedded_hal_02::watchdog::WatchdogDisable for Wdt +impl embedded_hal_02::watchdog::WatchdogDisable for Wdt where TG: TimerGroupInstance, - DM: Mode, { fn disable(&mut self) { self.disable(); } } -impl embedded_hal_02::watchdog::WatchdogEnable for Wdt +impl embedded_hal_02::watchdog::WatchdogEnable for Wdt where TG: TimerGroupInstance, - DM: Mode, { type Time = MicrosDurationU64; @@ -1057,10 +1030,9 @@ where } } -impl embedded_hal_02::watchdog::Watchdog for Wdt +impl embedded_hal_02::watchdog::Watchdog for Wdt where TG: TimerGroupInstance, - DM: Mode, { fn feed(&mut self) { self.feed();