]> git.earman.xyz Git - sensor-watch.git/commitdiff
enable high-efficiency low power regulator
authorJoey Castillo <joeycastillo@utexas.edu>
Sun, 13 Feb 2022 19:15:00 +0000 (14:15 -0500)
committerJoey Castillo <joeycastillo@utexas.edu>
Sun, 13 Feb 2022 19:15:00 +0000 (14:15 -0500)
watch-library/hardware/watch/watch.c
watch-library/hardware/watch/watch_deepsleep.c
watch-library/hardware/watch/watch_private.c

index 934d562391126595ead319e9877fc2a4c698dc7d..32bbccbbb99cbe42bd8cce2a8ce3e846c02781e6 100644 (file)
 // receives interrupts from MCLK, OSC32KCTRL, OSCCTRL, PAC, PM, SUPC and TAL, whatever that is.
 void SYSTEM_Handler(void) {
     if (SUPC->INTFLAG.bit.BOD33DET) {
+        // Our system voltage has dipped below 2.6V!
+        // Set the voltage regulator to work at low system voltage before we hit 2.5 V
+        // This voltage regulator can carry us down to 1.62 volts as the battery drains.
+        SUPC->VREG.bit.LPEFF = 0;
+        // clear the interrupt condition
         SUPC->INTENCLR.bit.BOD33DET = 1;
+        // and disable the brownout detector (TODO: add a second, "power critical" brownout condition?)
         SUPC->INTFLAG.reg &= ~SUPC_INTFLAG_BOD33DET;
     }
 }
index e3f654f216cc5c41d067674fd678927c81785761..3238a9536ae50974a32bd3235bf4788e5cdc78d6 100644 (file)
@@ -155,8 +155,10 @@ void watch_enter_sleep_mode(void) {
     // disable tick interrupt
     watch_rtc_disable_all_periodic_callbacks();
 
-    // disable brownout detector interrupt, which could inadvertently wake us up.
-    SUPC->INTENCLR.bit.BOD33DET = 1;
+    // set brownout detector to check voltage once an hour (64 minutes).
+    // in sleep, we're not worried about the LED causing a voltage drop and a brownout.
+    // changes to voltage will take place slowly over months, not quickly over seconds.
+    SUPC->BOD33.bit.PSEL = 0xF;
 
     // disable all pins
     _watch_disable_all_pins_except_rtc();
@@ -164,8 +166,8 @@ void watch_enter_sleep_mode(void) {
     // enter standby (4); we basically hang out here until an interrupt wakes us.
     sleep(4);
 
-    // and we awake! re-enable the brownout detector
-    SUPC->INTENSET.bit.BOD33DET = 1;
+    // and we awake! speed the brownout detector back up to 1 check per second.
+    SUPC->BOD33.bit.PSEL = 0x9;
 
     // call app_setup so the app can re-enable everything we disabled.
     app_setup();
index e4fa4b9a1e09902204174f140928a0524b4b680d..241ff40a21e4ff75fbc4259f72f225ab532098a8 100644 (file)
@@ -37,6 +37,18 @@ void _watch_init(void) {
     SUPC->VREG.bit.SEL = 1;
     while(!SUPC->STATUS.bit.VREGRDY);
 
+    // check the battery voltage...
+    watch_enable_adc();
+    uint16_t battery_voltage = watch_get_vcc_voltage();
+    watch_disable_adc();
+    // ...because we can enable the more efficient low power regulator if the system voltage is > 2.5V
+    // still, enable LPEFF only if the battery voltage is comfortably above this threshold.
+    if (battery_voltage >= 2700) {
+        SUPC->VREG.bit.LPEFF = 1;
+    } else {
+        SUPC->VREG.bit.LPEFF = 0;
+    }
+
     // set up the brownout detector (low battery warning)
     NVIC_DisableIRQ(SYSTEM_IRQn);
     NVIC_ClearPendingIRQ(SYSTEM_IRQn);
@@ -47,8 +59,8 @@ void _watch_init(void) {
     SUPC->BOD33.bit.RUNSTDBY = 1;   // Enable sampling mode in standby
     SUPC->BOD33.bit.STDBYCFG = 1;   // Run in standby
     SUPC->BOD33.bit.RUNBKUP = 0;    // Don't 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.PSEL = 0x9;     // Check battery level every second (we'll change this before entering sleep)
+    SUPC->BOD33.bit.LEVEL = 34;     // Detect brownout at 2.6V (1.445V + level * 34mV)
     SUPC->BOD33.bit.ACTION = 0x2;   // Generate an interrupt when BOD33 is triggered
     SUPC->BOD33.bit.HYST = 0;       // Disable hysteresis
     while(!SUPC->STATUS.bit.B33SRDY);