Skip to content

Instantly share code, notes, and snippets.

@Mictronics
Created March 18, 2025 17:09
Show Gist options
  • Select an option

  • Save Mictronics/06062eb09424e00a64b88908726aaa20 to your computer and use it in GitHub Desktop.

Select an option

Save Mictronics/06062eb09424e00a64b88908726aaa20 to your computer and use it in GitHub Desktop.
RP2040/RP2350 External watchdog based on ATtiny10
/**
* RP2040/RP2350 External watchdog
*
*/
#include <avr/sleep.h>
#define WDT_TIMEOUT 180 // Watchdog timeout 180s/3min (flashing the RP2040 must taken into account!)
volatile uint16_t wdt_count = 0;
static void delay(unsigned long millis) {
// ~1ms delay
for (volatile unsigned long i = 23 * millis; i != 0; i--)
;
}
ISR(PCINT0_vect) {
// Reset the dog on external trigger
wdt_count = 0;
}
ISR(WDT_vect) {
// Feed the dog
wdt_count += 1;
// Check if we need to issue a reset
if (wdt_count > WDT_TIMEOUT) {
PORTB &= ~_BV(PB0);
delay(100); // Issue reset
PORTB |= _BV(PB0);
wdt_count = 0; // Reset the dog
}
}
void setup() {
DDRB = 0; // Ensure PB2 and PB3 inputs
PORTB = 0; // Set them low
DDRB |= _BV(PB0); // PB0 is RESET output
PUEB |= _BV(PB2); // Set pull-up on watchdog reset input
PORTB |= _BV(PB0); // Set RESET high
// Use internal watchdog as external watchdog timer @1Hz
WDTCSR = _BV(WDIE) | _BV(WDP2) | _BV(WDP1);
PCMSK = _BV(PCINT2); // Mask PCINT2
PCICR = _BV(PCIE0); // Enable pin change interrupts
sei(); // Enable global interrupts
}
void loop() {
// Go to sleep and wait for internal watchdog or external pin change wakeup
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
// Rearm internal watchdog interrupt after ISR execution
WDTCSR = _BV(WDIE) | _BV(WDP2) | _BV(WDP1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment