aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSelene ToyKeeper2024-03-25 04:25:43 -0600
committerSelene ToyKeeper2024-03-25 04:25:43 -0600
commita87812f436e08b14a7cede83e30306d779774872 (patch)
tree42ea09d981ade4d582a01f9c03dc996dc0d3f57b
parentd3aa fine-tuning: (diff)
downloadanduril-a87812f436e08b14a7cede83e30306d779774872.tar.gz
anduril-a87812f436e08b14a7cede83e30306d779774872.tar.bz2
anduril-a87812f436e08b14a7cede83e30306d779774872.zip
dammit, got alkaline detection half working and then my flashing adapter died
(saving progress here so I can work on a different branch)
Diffstat (limited to '')
-rw-r--r--fsm/ramping.c5
-rw-r--r--fsm/ramping.h3
-rw-r--r--hw/hank/emisar-d3aa/hwdef.c64
-rw-r--r--hw/hank/emisar-d3aa/hwdef.h9
-rw-r--r--ui/anduril/anduril.c12
5 files changed, 91 insertions, 2 deletions
diff --git a/fsm/ramping.c b/fsm/ramping.c
index adc8acb..63ab399 100644
--- a/fsm/ramping.c
+++ b/fsm/ramping.c
@@ -57,6 +57,11 @@ inline void set_level_aux_rgb_leds(uint8_t level) {
void set_level(uint8_t level) {
+ #ifdef USE_RAMP_LEVEL_HARD_LIMIT
+ if (level > ramp_level_hard_limit)
+ level = ramp_level_hard_limit;
+ #endif
+
#ifdef USE_JUMP_START
// maybe "jump start" the engine, if it's prone to slow starts
// (pulse the output high for a moment to wake up the power regulator)
diff --git a/fsm/ramping.h b/fsm/ramping.h
index c4b7d48..6fe87fe 100644
--- a/fsm/ramping.h
+++ b/fsm/ramping.h
@@ -10,6 +10,9 @@
uint8_t actual_level = 0;
// the level used before actual
uint8_t prev_level = 0;
+#ifdef USE_RAMP_LEVEL_HARD_LIMIT
+uint8_t ramp_level_hard_limit = RAMP_SIZE;
+#endif
void set_level(uint8_t level);
//void set_level_smooth(uint8_t level);
diff --git a/hw/hank/emisar-d3aa/hwdef.c b/hw/hank/emisar-d3aa/hwdef.c
index e2fd315..f6cf94e 100644
--- a/hw/hank/emisar-d3aa/hwdef.c
+++ b/hw/hank/emisar-d3aa/hwdef.c
@@ -4,6 +4,8 @@
#pragma once
#include "fsm/chan-rgbaux.c"
+#include "fsm/ramping.h"
+#include "ui/anduril/misc.h"
void set_level_zero();
@@ -110,3 +112,65 @@ uint8_t voltage_raw2cooked(uint16_t measurement) {
}
#endif
+#ifdef USE_WEAK_BATTERY_PROTECTION
+uint8_t quick_volt_measurement() {
+ // take the average of a few samples
+ // (assumes the ADC is in voltage mode and running continuously)
+ uint16_t total = 0;
+ for (uint8_t i=0; i<8; i++) {
+ uint16_t m = adc_raw[0];
+ total += voltage_raw2cooked(m);
+ delay_zero();
+ }
+ uint8_t v = total / 8;
+ return v;
+}
+
+void detect_weak_battery() {
+ // guess at the cell strength with a load test...
+ // - measure voltage while LEDs off
+ // - measure again with LEDs on
+ // - determine how much to limit power
+ // - blink to indicate weak battery mode, if active
+
+ uint16_t resting, loaded;
+
+ set_level(0);
+ resting = quick_volt_measurement();
+
+ set_level(WEAK_BATTERY_CHECK_LEVEL);
+ loaded = quick_volt_measurement();
+ set_level(0);
+
+ int16_t diff = resting - loaded;
+ uint8_t extra_blinks = 0;
+
+ if (loaded <= DUAL_VOLTAGE_LOW_LOW) {
+ // weak or empty AA battery has a low limit
+ ramp_level_hard_limit = WEAK_BATTERY_LOWEST_LIMIT;
+ extra_blinks = 2;
+ } else if (loaded >= VOLTAGE_RED) {
+ // reasonably strong li-ion battery
+ ramp_level_hard_limit = WEAK_BATTERY_HIGHEST_LIMIT;
+ } else if (diff <= (-5 * 4)) {
+ // marginal battery, dropped a lot under mild load
+ ramp_level_hard_limit = WEAK_BATTERY_MEDIUM_LIMIT;
+ extra_blinks = 1;
+ }
+
+ for (uint8_t i=0; i<extra_blinks; i++) {
+ delay_4ms(300/4);
+ blink_once();
+ }
+
+ voltage = resting;
+ battcheck();
+
+ voltage = loaded;
+ battcheck();
+
+ //if (diff < 0)
+ // blink_num(-diff);
+}
+#endif
+
diff --git a/hw/hank/emisar-d3aa/hwdef.h b/hw/hank/emisar-d3aa/hwdef.h
index 56dd061..1e677b6 100644
--- a/hw/hank/emisar-d3aa/hwdef.h
+++ b/hw/hank/emisar-d3aa/hwdef.h
@@ -114,6 +114,15 @@ enum CHANNEL_MODES {
#define USE_VOLTAGE_VDDIO2
#endif
+// Alkaline AA can't handle the power this light wants,
+// so try to detect it and limit the maximum power
+#define USE_RAMP_LEVEL_HARD_LIMIT
+#define USE_WEAK_BATTERY_PROTECTION
+#define WEAK_BATTERY_HIGHEST_LIMIT RAMP_SIZE
+#define WEAK_BATTERY_MEDIUM_LIMIT (RAMP_SIZE*2/3)
+#define WEAK_BATTERY_LOWEST_LIMIT (RAMP_SIZE*1/3)
+#define WEAK_BATTERY_CHECK_LEVEL (RAMP_SIZE*2/3)
+
// average drop across diode on this hardware
#ifndef VOLTAGE_FUDGE_FACTOR
#define VOLTAGE_FUDGE_FACTOR 0 // using a PFET so no appreciable drop
diff --git a/ui/anduril/anduril.c b/ui/anduril/anduril.c
index 1cdb8d0..f50f8d2 100644
--- a/ui/anduril/anduril.c
+++ b/ui/anduril/anduril.c
@@ -225,8 +225,16 @@ void setup() {
// regular e-switch light, no hard clicky power button
- // blink at power-on to let user know power is connected
- blink_once();
+ #ifdef USE_WEAK_BATTERY_PROTECTION
+ // try to measure the battery strength
+ // (must be done *before* factory reset,
+ // because reset tries to use full power,
+ // and a weak battery can't do that)
+ detect_weak_battery();
+ #else
+ // blink at power-on to let user know power is connected
+ blink_once();
+ #endif
#ifdef USE_FACTORY_RESET
if (button_is_pressed())