reform

MNT Reform: Open Source Portable Computer
Log (Feed) | Files | Refs (Tags) | README

commit 058a6e066f89e460be32c3a09289c1799a6aa0ed
parent 1a9c21f6cddeb5d7b00cca9f801ce1c3349252c2
Author: minute <lukas@mntre.com>
Date:   Mon,  4 Jul 2022 09:27:37 +0000

Merge branch 'keyboard-powersave-fix' into 'master'

Keyboard powersave fix

See merge request reform/reform!26
Diffstat:
Mreform2-keyboard-fw/keyboard.c | 2+-
Mreform2-keyboard-fw/powersave.c | 15+++++++++++++--
2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/reform2-keyboard-fw/keyboard.c b/reform2-keyboard-fw/keyboard.c @@ -342,7 +342,7 @@ void setup_hardware(void) ISR(WDT_vect) { // WDT interrupt enable and flag cleared on entry - wdt_disable(); // Disable watchdog for now + Delay_MS(1); } /** Event handler for the library USB Connection event. */ diff --git a/reform2-keyboard-fw/powersave.c b/reform2-keyboard-fw/powersave.c @@ -49,9 +49,19 @@ void keyboard_power_off(void) // We can use the Watchdog timer to do this. do { + // Setting WDT parameters must be done within 4 cycles of setting WDCE, so interrupts + // must be disabled. + cli(); + wdt_reset(); - WDTCSR = (1<<WDCE) | (1<<WDE); // Enable writes to watchdog - WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0); // Interrupt mode, 1s timeout + + // Enable writes to watchdog, then set interrupt-only mode, 1s timeout. + // (Interrupt-only mode is preferred to interrupt-and-reset mode, because + // the latter has the risk of WDT-induced bootloops if the bootloader doesn't + // correctly handle WDT resets. Whereas we have a physical reset button, if + // a hard reset is actually needed.) + WDTCSR = (1<<WDCE) | (1<<WDE); + WDTCSR = (1<<WDIE) | (0<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0); // Enter Power-save mode set_sleep_mode(SLEEP_MODE_PWR_DOWN); @@ -60,6 +70,7 @@ void keyboard_power_off(void) sleep_cpu(); // Actually go to sleep // Zzzzzz sleep_disable(); // We've woken up + wdt_disable(); // Disable watchdog for now sei(); // Check if circle key has been pressed (active-low) // If not reset the watchdog and try again