diff --git a/rp2040-hal/examples/adc_fifo_dma.rs b/rp2040-hal/examples/adc_fifo_dma.rs index e6159c4ca..f602fd022 100644 --- a/rp2040-hal/examples/adc_fifo_dma.rs +++ b/rp2040-hal/examples/adc_fifo_dma.rs @@ -146,7 +146,7 @@ fn main() -> ! { adc_fifo.resume(); // initialize a timer, to measure the total sampling time (printed below) - let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks.reference_clock); + let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &watchdog, &clocks.reference_clock); // NOTE: in a real-world program, instead of calling `wait` now, you would probably: // 1. Enable one of the DMA interrupts for the channel (e.g. `dma.ch0.enable_irq0()`) diff --git a/rp2040-hal/examples/adc_fifo_poll.rs b/rp2040-hal/examples/adc_fifo_poll.rs index b61ca486c..9c68a6970 100644 --- a/rp2040-hal/examples/adc_fifo_poll.rs +++ b/rp2040-hal/examples/adc_fifo_poll.rs @@ -133,7 +133,7 @@ fn main() -> ! { let mut i = 0; // initialize a timer, to measure the total sampling time (printed below) - let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks.reference_clock); + let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &watchdog, &clocks.reference_clock); loop { // busy-wait until the FIFO contains at least two samples: diff --git a/rp2040-hal/examples/blinky.rs b/rp2040-hal/examples/blinky.rs index 1d14ff4d5..4c195dd8b 100644 --- a/rp2040-hal/examples/blinky.rs +++ b/rp2040-hal/examples/blinky.rs @@ -64,7 +64,7 @@ fn main() -> ! { .ok() .unwrap(); - let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks.reference_clock); + let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &watchdog, &clocks.reference_clock); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); diff --git a/rp2040-hal/examples/vector_table.rs b/rp2040-hal/examples/vector_table.rs index 9b3766e31..70bc620f9 100644 --- a/rp2040-hal/examples/vector_table.rs +++ b/rp2040-hal/examples/vector_table.rs @@ -110,7 +110,7 @@ fn main() -> ! { // Configure GPIO25 as an output let led_pin = pins.gpio25.into_push_pull_output(); - let mut timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks.reference_clock); + let mut timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &watchdog, &clocks.reference_clock); critical_section::with(|cs| { let mut alarm = timer.alarm_0().unwrap(); // Schedule an alarm in 1 second diff --git a/rp2040-hal/src/clocks/mod.rs b/rp2040-hal/src/clocks/mod.rs index 5f280a5c5..35e29e8a3 100644 --- a/rp2040-hal/src/clocks/mod.rs +++ b/rp2040-hal/src/clocks/mod.rs @@ -330,7 +330,7 @@ pub fn init_clocks_and_plls( let xosc = setup_xosc_blocking(xosc_dev, xosc_crystal_freq.Hz()).map_err(InitError::XoscErr)?; // Configure watchdog tick generation to tick over every microsecond - watchdog.enable_tick_generation((xosc_crystal_freq / 1_000_000) as u8); + watchdog.enable_tick_generation((xosc_crystal_freq / 1_000_000) as u16); let mut clocks = ClocksManager::new(clocks_dev); diff --git a/rp2040-hal/src/timer.rs b/rp2040-hal/src/timer.rs index b922bad82..6a07d706e 100644 --- a/rp2040-hal/src/timer.rs +++ b/rp2040-hal/src/timer.rs @@ -16,7 +16,8 @@ use crate::{ clocks::ReferenceClock, pac::{self, RESETS, TIMER}, resets::SubsystemReset, - typelevel::Sealed, Clock, + typelevel::Sealed, + Clock, Watchdog, }; /// Instant type used by the Timer & Alarm methods. @@ -59,8 +60,16 @@ impl Timer { /// Make sure that clocks and watchdog are configured, so /// that timer ticks happen at a frequency of 1MHz. /// Otherwise, `Timer` won't work as expected. - pub fn new(timer: TIMER, resets: &mut RESETS, clocks: &ReferenceClock) -> Self { - assert_eq!(clocks.freq().to_Hz(), 1_000_000); + pub fn new( + timer: TIMER, + resets: &mut RESETS, + watchdog: &Watchdog, + clocks: &ReferenceClock, + ) -> Self { + assert_eq!( + clocks.freq().to_Hz() / u32::from(watchdog.cycles_per_ticks()), + 1_000_000 + ); timer.reset_bring_down(resets); timer.reset_bring_up(resets); Self { _private: () } diff --git a/rp2040-hal/src/watchdog.rs b/rp2040-hal/src/watchdog.rs index bef51cc35..d2da7d7aa 100644 --- a/rp2040-hal/src/watchdog.rs +++ b/rp2040-hal/src/watchdog.rs @@ -60,14 +60,21 @@ impl Watchdog { /// /// * `cycles` - Total number of tick cycles before the next tick is generated. /// It is expected to be the frequency in MHz of clk_ref. - pub fn enable_tick_generation(&mut self, cycles: u8) { + pub fn enable_tick_generation(&mut self, cycles: u16) { const WATCHDOG_TICK_ENABLE_BITS: u32 = 0x200; + assert_eq!(cycles & !0x1FF, 0); + self.watchdog .tick .write(|w| unsafe { w.bits(WATCHDOG_TICK_ENABLE_BITS | cycles as u32) }) } + /// Returns the number of `clk_ref` cycles between each watchdog (and Timer) ticks. + pub fn cycles_per_ticks(&self) -> u16 { + self.watchdog.tick.read().cycles().bits() + } + /// Defines whether or not the watchdog timer should be paused when processor(s) are in debug mode /// or when JTAG is accessing bus fabric ///