embassy-rs/embassy · error

Period cannot exceed

Error message

Period cannot exceed {} microseconds

What it means

The watchdog period is stored in a 24-bit load register, and on RP2040 the counter decrements by 2 due to errata RP2040-E1, halving the effective maximum. `Watchdog::start`/`feed` computes the microsecond timeout and panics if it exceeds MAX_PERIOD (0xFFFFFF/2 us on RP2040, 0xFFFFFF us on RP235x) because the requested period cannot be represented in the hardware register.

Solutions

  1. Clamp or validate the watchdog timeout to <= 8_388_607 microseconds (8.386 s) on RP2040 before calling start
  2. Use a shorter watchdog period and feed it more frequently from a scheduled task
  3. Implement a software watchdog chain: hardware watchdog at a short period fed by a task that checks a longer logical deadline
  4. On RP235x you get the full 0xFFFFFF (~16.7 s) range since the errata is fixed

Example fix

// before
watchdog.start(Duration::from_secs(15)); // panics on RP2040
// after
const MAX_PERIOD_US: u64 = 0xFFFFFF / 2;
let period = Duration::from_secs(15).min(Duration::from_micros(MAX_PERIOD_US));
watchdog.start(period); // ~8.39s max on RP2040
Defensive patterns

Strategy: validation

Validate before calling

fn watchdog_period_ok(d: std::time::Duration) -> bool {
    const MAX_PERIOD_US: u64 = 0xFFFFFF / 2; // RP2040; RP235x: 0xFFFFFF
    d.as_micros() <= MAX_PERIOD_US
}

Try / catch

// panic in no_std: clamp before start
watchdog.start(d.min(Duration::from_micros(0xFFFFFF / 2)));

Prevention

When it happens

Trigger: Calling `watchdog.start(Duration)` with a timeout whose microsecond value exceeds 8,388,607 us (~8.39 s) on RP2040 or 16,777,215 us (~16.78 s) on RP235x.

Common situations: Configuring a 10-second or 30-second watchdog on RP2040 assuming the full 24-bit range; porting RP235x watchdog timings back to RP2040 where the errata halves the limit; computing the timeout from a config value without clamping.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/fc9ab53f3d2fba03. Report an issue: GitHub.

Appendix: source

Thrown at embassy-rp/src/watchdog.rs:91

    // Configure which hardware will be reset by the watchdog
    // (everything except ROSC, XOSC)
    fn configure_wdog_reset_triggers(&self) {
        let psm = pac::PSM;
        psm.wdsel().write_value(pac::psm::regs::Wdsel(
            0x0001ffff & !(0x01 << 0usize) & !(0x01 << 1usize),
        ));
    }

    /// Feed the watchdog timer
    pub fn feed(&mut self, timeout: Duration) {
        #[cfg(feature = "rp2040")]
        const MAX_PERIOD: u32 = 0xFFFFFF / 2;
        #[cfg(feature = "_rp235x")]
        const MAX_PERIOD: u32 = 0xFFFFFF;

        let timeout_us = timeout.as_micros();
        if timeout_us > (MAX_PERIOD) as u64 {
            panic!("Period cannot exceed {} microseconds", MAX_PERIOD);
        }
        let timeout_us = timeout_us as u32;

        // Due to a logic error, the watchdog decrements by 2 and
        // the load value must be compensated; see RP2040-E1
        // This errata is fixed in the RP235x
        let load_value = if cfg!(feature = "rp2040") {
            timeout_us * 2
        } else {
            timeout_us
        };

        self.load_counter(load_value)
    }

    /// Start the watchdog timer
    pub fn start(&mut self, initial_timeout: Duration) {
        self.enable(false);

View on GitHub (pinned to 463a07b963)