]> git.earman.xyz Git - sensor-watch.git/commitdiff
add method for detecting low battery
authorJoey Castillo <jose.castillo@gmail.com>
Tue, 31 Aug 2021 22:47:35 +0000 (18:47 -0400)
committerJoey Castillo <jose.castillo@gmail.com>
Tue, 31 Aug 2021 23:02:44 +0000 (19:02 -0400)
watch-library/watch/watch.c
watch-library/watch/watch.h
watch-library/watch/watch_private.c

index 059c2a937fcfe31b4229ea0a4ba152babb53f88c..6196b1f3d88df7a815fe2ade3cf9dbd7f04f7eda 100644 (file)
 #include "watch_uart.c"
 #include "watch_deepsleep.c"
 #include "watch_private.c"
+
+bool battery_is_low = false;
+
+// receives interrupts from MCLK, OSC32KCTRL, OSCCTRL, PAC, PM, SUPC and TAL, whatever that is.
+void SYSTEM_Handler(void) {
+    if (SUPC->INTFLAG.bit.BOD33DET) {
+        battery_is_low = true;
+        SUPC->INTENCLR.bit.BOD33DET = 1;
+        SUPC->INTFLAG.reg &= ~SUPC_INTFLAG_BOD33DET;
+    }
+}
+
+bool watch_is_battery_low() {
+    return battery_is_low;
+}
index 8c207ddb645ba6d06830b15d8b97c7e0585c07dc..5cd45a6c1f088e3d216828da360b4e901f709695 100644 (file)
 
 #include "watch_private.h"
 
+/** @brief Returns true when the battery voltage dips below 2.5V.
+  * @details A CR2016 battery will have a nominal voltage between 2.9 and 3 volts for most of its lifespan. Once the battery
+  *          discharges to about 60%, the voltage will drift slightly lower; this may manifest as a dimmer LED. By the time
+  *          the battery voltage has fallen to 2.5 volts, it will have probably less than 10% of its capacity remaining, and
+  *          you can expect the voltage to drop relatively quickly as the battery dies.
+  */
+bool watch_is_battery_low();
+
 #endif /* WATCH_H_ */
\ No newline at end of file
index 88d80be939454125017a2ff01f5c1c84b6302b73..8dfd10f98b97b89f223e72a8a3f9812408ec5b1b 100644 (file)
@@ -32,6 +32,27 @@ void _watch_init() {
     SUPC->VREG.bit.SEL = 1;
     while(!SUPC->STATUS.bit.VREGRDY);
 
+    // set up the brownout detector (low battery warning)
+    NVIC_DisableIRQ(SYSTEM_IRQn);
+    NVIC_ClearPendingIRQ(SYSTEM_IRQn);
+    NVIC_EnableIRQ(SYSTEM_IRQn);
+    SUPC->BOD33.bit.ENABLE = 0;     // BOD33 must be disabled to change its configuration
+    SUPC->BOD33.bit.VMON = 0;       // Monitor VDD in active and standby mode
+    SUPC->BOD33.bit.ACTCFG = 1;     // Enable sampling mode when active
+    SUPC->BOD33.bit.RUNSTDBY = 1;   // Enable sampling mode in standby
+    SUPC->BOD33.bit.STDBYCFG = 1;   // Run in standby
+    SUPC->BOD33.bit.RUNBKUP = 1;    // Also run in backup mode
+    SUPC->BOD33.bit.PSEL = 0xB;     // Check battery level every 4 seconds
+    SUPC->BOD33.bit.LEVEL = 31;     // Detect brownout at 2.5V (1.445V + level * 34mV)
+    SUPC->BOD33.bit.BKUPLEVEL = 31; // Detect same level in backup mode
+    SUPC->BOD33.bit.ACTION = 0x2;   // Generate an interrupt when BOD33 is triggered
+    SUPC->BOD33.bit.HYST = 0;       // Disable hysteresis
+    while(!SUPC->STATUS.bit.B33SRDY);
+
+    // Enable interrupt on BOD33 detect
+    SUPC->INTENSET.bit.BOD33DET = 1;
+    SUPC->BOD33.bit.ENABLE = 1;
+
     // External wake depends on RTC; calendar is a required module.
     CALENDAR_0_init();
     calendar_enable(&CALENDAR_0);