Skip to content

Commit b025f30

Browse files
committed
Add NoPowerLossProtection option and binary
1 parent 1730ffc commit b025f30

File tree

4 files changed

+78
-46
lines changed

4 files changed

+78
-46
lines changed
361 KB
Binary file not shown.

Firmware/OpenLog_Artemis/OpenLog_Artemis.ino

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ const int FIRMWARE_VERSION_MINOR = 3;
152152
// the minor firmware version
153153
#define OLA_IDENTIFIER 0x123 // Stored as 291 decimal in OLA_settings.txt
154154

155+
//#define noPowerLossProtection // Uncomment this line to disable the sleep-on-power-loss functionality
156+
155157
#include "settings.h"
156158

157159
//Define the pin functions
@@ -357,15 +359,53 @@ Stream *ZSERIAL;
357359
// Serial output for debugging info for Zmodem
358360
Stream *DSERIAL;
359361

362+
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
363+
#include "WDT.h" // WDT support
364+
365+
volatile static bool petTheDog = true; // Flag to control whether the WDT ISR pets (resets) the timer.
366+
367+
// Interrupt handler for the watchdog.
368+
extern "C" void am_watchdog_isr(void)
369+
{
370+
// Clear the watchdog interrupt.
371+
wdt.clear();
372+
373+
// Restart the watchdog if petTheDog is true
374+
if (petTheDog)
375+
wdt.restart(); // "Pet" the dog.
376+
}
377+
378+
void startWatchdog()
379+
{
380+
// Set watchdog timer clock to 16 Hz
381+
// Set watchdog interrupt to 1 seconds (16 ticks / 16 Hz = 1 second)
382+
// Set watchdog reset to 1.25 seconds (20 ticks / 16 Hz = 1.25 seconds)
383+
// Note: Ticks are limited to 255 (8-bit)
384+
wdt.configure(WDT_16HZ, 16, 20);
385+
wdt.start(); // Start the watchdog
386+
}
387+
388+
void stopWatchdog()
389+
{
390+
wdt.stop();
391+
}
392+
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
393+
360394
void setup() {
361395
//If 3.3V rail drops below 3V, system will power down and maintain RTC
362396
pinMode(PIN_POWER_LOSS, INPUT); // BD49K30G-TL has CMOS output and does not need a pull-up
363397

364398
delay(1); // Let PIN_POWER_LOSS stabilize
365399

400+
#ifndef noPowerLossProtection
366401
if (digitalRead(PIN_POWER_LOSS) == LOW) powerDownOLA(); //Check PIN_POWER_LOSS just in case we missed the falling edge
367402
//attachInterrupt(PIN_POWER_LOSS, powerDownOLA, FALLING); // We can't do this with v2.1.0 as attachInterrupt causes a spontaneous interrupt
368403
attachInterrupt(PIN_POWER_LOSS, powerLossISR, FALLING);
404+
#else
405+
// No Power Loss Protection
406+
// Set up the WDT to generate a reset just in case the code crashes during a brown-out
407+
startWatchdog();
408+
#endif
369409
powerLossSeen = false; // Make sure the flag is clear
370410

371411
powerLEDOn(); // Turn the power LED on - if the hardware supports it

Firmware/OpenLog_Artemis/lowerPower.ino

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ void checkBattery(void)
3535

3636
SerialFlush(); //Finish any prints
3737

38+
#ifdef noPowerLossProtection
39+
// Leave the WDT running so it will reset the Artemis is required
40+
// Don't go into deep sleep. Just keep running. Draining the battery...
41+
// User can prevent this by disabling settings.enableLowBatteryDetection
42+
while (1)
43+
;
44+
#else
3845
powerDownOLA(); // power down and wait for reset
46+
#endif
3947
}
4048
}
4149
else
@@ -45,8 +53,10 @@ void checkBattery(void)
4553
}
4654
#endif
4755

56+
#ifndef noPowerLossProtection // Redundant - since the interrupt is not attached if noPowerLossProtection is defined... But you never know...
4857
if (powerLossSeen)
4958
powerDownOLA(); // power down and wait for reset
59+
#endif
5060
}
5161

5262
//Power down the entire system but maintain running of RTC
@@ -55,8 +65,10 @@ void checkBattery(void)
5565
//With leakage across the 3.3V protection diode, it's approx 3.00uA.
5666
void powerDownOLA(void)
5767
{
68+
#ifndef noPowerLossProtection // Probably redundant - included just in case detachInterrupt causes badness when it has not been attached
5869
//Prevent voltage supervisor from waking us from sleep
5970
detachInterrupt(PIN_POWER_LOSS);
71+
#endif
6072

6173
//Prevent stop logging button from waking us from sleep
6274
if (settings.useGPIO32ForStopLogging == true)
@@ -140,6 +152,10 @@ void powerDownOLA(void)
140152
qwiicPowerOff();
141153
#endif
142154

155+
#ifdef noPowerLossProtection // If noPowerLossProtection is defined, then the WDT will already be running
156+
stopWatchdog();
157+
#endif
158+
143159
//Power down cache, flash, SRAM
144160
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Power down all flash and cache
145161
am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_384K); // Retain all SRAM
@@ -222,7 +238,10 @@ void resetArtemis(void)
222238
powerLEDOff();
223239

224240
//Enable the Watchdog so it can reset the Artemis
225-
startWatchdog();
241+
petTheDog = false; // Make sure the WDT will not restart
242+
#ifndef noPowerLossProtection // If noPowerLossProtection is defined, then the WDT will already be running
243+
startWatchdog(); // Start the WDT to generate a reset
244+
#endif
226245
while (1) // That's all folks! Artemis will reset in 1.25 seconds
227246
;
228247
}
@@ -232,8 +251,10 @@ void goToSleep(uint32_t sysTicksToSleep)
232251
{
233252
printDebug("goToSleep: sysTicksToSleep = " + (String)sysTicksToSleep + "\r\n");
234253

254+
#ifndef noPowerLossProtection // Probably redundant - included just in case detachInterrupt causes badness when it has not been attached
235255
//Prevent voltage supervisor from waking us from sleep
236256
detachInterrupt(PIN_POWER_LOSS);
257+
#endif
237258

238259
//Prevent stop logging button from waking us from sleep
239260
if (settings.useGPIO32ForStopLogging == true)
@@ -351,6 +372,13 @@ void goToSleep(uint32_t sysTicksToSleep)
351372
else
352373
powerLEDOff();
353374

375+
376+
#ifdef noPowerLossProtection
377+
// If noPowerLossProtection is defined, then the WDT will be running
378+
// We need to stop it otherwise it will wake the Artemis
379+
stopWatchdog();
380+
#endif
381+
354382
//Power down cache, flash, SRAM
355383
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Power down all flash and cache
356384
am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_384K); // Retain all SRAM
@@ -420,12 +448,17 @@ void wakeFromSleep()
420448

421449
delay(1); // Let PIN_POWER_LOSS stabilize
422450

451+
#ifndef noPowerLossProtection
423452
if (digitalRead(PIN_POWER_LOSS) == LOW) powerDownOLA(); //Check PIN_POWER_LOSS just in case we missed the falling edge
424-
425453
//attachInterrupt(PIN_POWER_LOSS, powerDownOLA, FALLING); // We can't do this with v2.1.0 as attachInterrupt causes a spontaneous interrupt
426454
attachInterrupt(PIN_POWER_LOSS, powerLossISR, FALLING);
455+
#else
456+
// No Power Loss Protection
457+
// Set up the WDT to generate a reset just in case the code crashes during a brown-out
458+
startWatchdog();
459+
#endif
427460
powerLossSeen = false; // Make sure the flag is clear
428-
461+
429462
if (settings.useGPIO32ForStopLogging == true)
430463
{
431464
pinMode(PIN_STOP_LOGGING, INPUT_PULLUP);
@@ -704,46 +737,3 @@ int calculateDayOfYear(int day, int month, int year)
704737
doy += day;
705738
return doy;
706739
}
707-
708-
//WatchDog Timer code by Adam Garbo:
709-
//https://forum.sparkfun.com/viewtopic.php?f=169&t=52431&p=213296#p213296
710-
711-
// Watchdog timer configuration structure.
712-
am_hal_wdt_config_t g_sWatchdogConfig = {
713-
714-
// Configuration values for generated watchdog timer event.
715-
.ui32Config = AM_HAL_WDT_LFRC_CLK_16HZ | AM_HAL_WDT_ENABLE_RESET | AM_HAL_WDT_ENABLE_INTERRUPT,
716-
717-
// Number of watchdog timer ticks allowed before a watchdog interrupt event is generated.
718-
.ui16InterruptCount = 16, // Set WDT interrupt timeout for 1 second.
719-
720-
// Number of watchdog timer ticks allowed before the watchdog will issue a system reset.
721-
.ui16ResetCount = 20 // Set WDT reset timeout for 1.25 seconds.
722-
};
723-
724-
void startWatchdog()
725-
{
726-
// LFRC must be turned on for this example as the watchdog only runs off of the LFRC.
727-
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_LFRC_START, 0);
728-
729-
// Configure the watchdog.
730-
am_hal_wdt_init(&g_sWatchdogConfig);
731-
732-
// Enable the interrupt for the watchdog in the NVIC.
733-
NVIC_EnableIRQ(WDT_IRQn);
734-
//NVIC_SetPriority(WDT_IRQn, 0); // Set the interrupt priority to 0 = highest (255 = lowest)
735-
//am_hal_interrupt_master_enable(); // ap3_initialization.cpp does this - no need to do it here
736-
737-
// Enable the watchdog.
738-
am_hal_wdt_start();
739-
}
740-
741-
// Interrupt handler for the watchdog.
742-
extern "C++" void am_watchdog_isr(void)
743-
{
744-
// Clear the watchdog interrupt.
745-
am_hal_wdt_int_clear();
746-
747-
// DON'T Restart the watchdog.
748-
//am_hal_wdt_restart(); // "Pet" the dog.
749-
}

Firmware/OpenLog_Artemis/productionTest.ino

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,9 @@ void productionTest()
562562
break;
563563
case 0x55: // Deep sleep
564564
{
565+
#ifndef noPowerLossProtection // Probably redundant - included just in case detachInterrupt causes badness when it has not been attached
565566
detachInterrupt(PIN_POWER_LOSS); // Disable power loss interrupt
567+
#endif
566568
Serial.end(); //Power down UART
567569
//Force the peripherals off
568570
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);

0 commit comments

Comments
 (0)