aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MODELS3
-rw-r--r--docs/anduril-manual.md34
-rw-r--r--hw/hank/emisar-d3aa/hwdef.c22
-rw-r--r--hw/hank/emisar-d3aa/readme.md18
-rw-r--r--hw/hank/kr1aa/anduril.h65
-rw-r--r--hw/hank/kr1aa/arch1
-rw-r--r--hw/hank/kr1aa/model1
-rw-r--r--hw/hank/kr1aa/readme.md12
-rw-r--r--hw/hank/lume-x1/anduril.h13
9 files changed, 157 insertions, 12 deletions
diff --git a/MODELS b/MODELS
index a15ce0c..e5fda73 100644
--- a/MODELS
+++ b/MODELS
@@ -1,3 +1,5 @@
+Models: 82
+
Model MCU Name
----- --- ----
0111 attiny85 hank-emisar-d4
@@ -22,6 +24,7 @@ Model MCU Name
0143 attiny1634 hank-noctigon-m44
0151 attiny1634 hank-emisar-d4k-3ch
0161 avr32dd20 hank-emisar-d3aa
+0162 avr32dd20 hank-kr1aa
0211 attiny1634 hank-noctigon-kr4
0212 attiny1634 hank-noctigon-kr4-nofet
0213 attiny1634 hank-noctigon-kr4-219
diff --git a/docs/anduril-manual.md b/docs/anduril-manual.md
index 4e28803..f432afb 100644
--- a/docs/anduril-manual.md
+++ b/docs/anduril-manual.md
@@ -909,6 +909,40 @@ When a light has a single-color aux LED and no RGB, it fast-blinks the
aux LED in "off" modes when voltage is low.
+Post-Off Voltage Display (POVD)
+-------------------------------
+
+Many lights with RGB aux LEDs will display the battery voltage by color for
+a few seconds after going to "Off" mode. This provides a quick, easy way to
+keep track of the battery status without any extra button clicks.
+
+The typical and intended use pattern is: Turn the light off, then the color
+indicates battery status for a few seconds, and then the aux LEDs go to their
+configured standby pattern (usually low brightness, in voltage mode, by
+default). This makes it easier to see the color, since the colors are
+balanced in hardware according to how they look in high mode, and may be
+harder to discern in low mode. It lasts only a few seconds though, because
+leaving them bright all the time would drain the battery much, much faster.
+
+POVD brightness is determined by your config settings and previous main LED
+ramp level. It uses the *first* matching condition:
+
+- If the standby aux brightness is high, POVD uses high aux too.
+- If the main LEDs were above the "aux high ramp level", POVD uses high aux.
+- If the main LEDs were above the "aux low ramp level", POVD uses low aux.
+- If the main LEDs were below the "aux low ramp level", POVD is black.
+
+The aux high/low ramp levels are configurable on most lights with RGB, using
+the Voltage Config Menu in Batt Check mode.
+
+Note: Voltage is monitored and updated continuously during POVD, so the color
+may change. This happens particularly when turning off from a high or turbo
+mode, because the high load causes a lot of battery sag... and the battery
+recovers quickly during the first few seconds after load is removed. It is
+normal for battery voltage to measure low during and immediately after turbo,
+but it should recover soon afterward.
+
+
Misc Config Menu
----------------
diff --git a/hw/hank/emisar-d3aa/hwdef.c b/hw/hank/emisar-d3aa/hwdef.c
index 0ac0ddc..e6caf46 100644
--- a/hw/hank/emisar-d3aa/hwdef.c
+++ b/hw/hank/emisar-d3aa/hwdef.c
@@ -64,17 +64,17 @@ void set_level_main(uint8_t level) {
PWM1_DATATYPE dac_lvl = PWM1_GET(level) << 6;
PWM2_DATATYPE dac_vref = PWM2_GET(level);
+ // set these in successive clock cycles to avoid getting out of sync
+ // (minimizes ramp bumps when changing gears)
+ DAC_LVL = dac_lvl;
+ DAC_VREF = dac_vref;
+
// enable HDR on top half of ramp
if (level >= (HDR_ENABLE_LEVEL_MIN-1))
HDR_ENABLE_PORT |= (1 << HDR_ENABLE_PIN);
else
HDR_ENABLE_PORT &= ~(1 << HDR_ENABLE_PIN);
- // set these in successive clock cycles to avoid getting out of sync
- // (minimizes ramp bumps when changing gears)
- DAC_LVL = dac_lvl;
- DAC_VREF = dac_vref;
-
// if turning on from off, let things stabilize before enabling power
if (noflash) { nfet_delay(); }
@@ -146,9 +146,17 @@ void detect_weak_battery() {
uint16_t resting, loaded;
- // baseline unloaded measurement
set_level(0);
- for (uint8_t i=0; i<32; i++) { delay_zero(); } // wait about 10ms
+
+ // wait a moment so user can tighten the tailcap
+ #ifdef WEAK_BATTERY_TEST_DELAY
+ for (uint16_t i=0; i<(WEAK_BATTERY_TEST_DELAY * 2 / 3); i++)
+ delay_zero();
+ #else
+ for (uint8_t i=0; i<32; i++) delay_zero(); // wait about 10ms
+ #endif
+
+ // baseline unloaded measurement
//resting = voltage_raw2cooked(adc_smooth[0]); // probably not settled yet
resting = quick_volt_measurement();
diff --git a/hw/hank/emisar-d3aa/readme.md b/hw/hank/emisar-d3aa/readme.md
new file mode 100644
index 0000000..f234dad
--- /dev/null
+++ b/hw/hank/emisar-d3aa/readme.md
@@ -0,0 +1,18 @@
+# Emisar D3AA
+
+This driver measures battery strength when power is connected, and uses that
+info to set a hard limit on brightness when the battery is too weak to handle
+full power.
+
+The number of blinks at power-connect indicates the battery type and strength:
+
+- 1 blink: Strong Li-ion cell, full power enabled
+
+- 2 blinks: Strong AA cell, max AA power enabled
+ (not used, strong AA uses mode 1 with full power enabled)
+
+- 3 blinks: Weak battery, power severely limited
+
+The 2-blink mode is not actually used. So it should blink 1 time or 3 times,
+depending on the cell strength.
+
diff --git a/hw/hank/kr1aa/anduril.h b/hw/hank/kr1aa/anduril.h
new file mode 100644
index 0000000..f3ed9ad
--- /dev/null
+++ b/hw/hank/kr1aa/anduril.h
@@ -0,0 +1,65 @@
+// Emisar / Noctigon KR1AA config options for Anduril
+// Copyright (C) 2026 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+#define HWDEF_H hank/emisar-d3aa/hwdef.h
+#include "hank/anduril.h"
+#include "hank/emisar-d3aa/anduril.h"
+
+// wait this many ms at boot before testing the battery
+// (or doing anything else)
+// (to give the user more time to make a solid electrical connection)
+#define WEAK_BATTERY_TEST_DELAY 500
+
+#undef RAMP_SIZE
+#define RAMP_SIZE 150
+
+// 4 ramp segments:
+// - low 1.024V
+// - low 2.5 V
+// - high 1.024V
+// - high 2.5 V
+// 2nd gear starts at 23:
+// ./bin/dac-scale.py $( ./bin/level_calc.py 3.906 1 150 7135 3 0.01 1400 --pwm 285400 | grep PWM1 | cut -d : -f 2- )
+// top level for each "gear": 30 40 118 150
+// 2nd gear starts at 24:
+// ./bin/dac-scale.py $( ./bin/level_calc.py 3.856 1 150 7135 3 0.01 1400 --pwm 273200 | grep PWM1 | cut -d : -f 2- )
+// top level for each "gear": 30 40 117 150
+#undef PWM1_LEVELS
+#define PWM1_LEVELS \
+ 3, 5, 6, 9, 12, 16, 21, 28, 36, 46, 57, 71, 86, 105, 126, 150, 177, 208, 243, 282, 326, 374, 428, 487, 552, 623, 700, 785, 877, 977, \
+ 444, 491, 543, 598, 658, 722, 790, 862, 940,1023, \
+ 24, 26, 29, 31, 33, 36, 39, 42, 45, 48, 52, 55, 59, 63, 67, 71, 76, 81, 86, 91, 96, 102, 108, 114, 120, 127, 134, 141, 149, 157, 165, 173, 182, 191, 200, 210, 220, 230, 241, 252, 264, 276, 288, 301, 314, 327, 341, 355, 370, 385, 401, 417, 434, 451, 469, 487, 505, 525, 544, 564, 585, 607, 628, 651, 674, 698, 722, 747, 773, 799, 826, 853, 881, 910, 940, 970,1001, \
+ 423, 436, 450, 463, 478, 492, 507, 522, 538, 554, 570, 586, 603, 621, 638, 656, 675, 693, 712, 732, 752, 772, 793, 814, 836, 858, 880, 903, 926, 950, 974, 998,1023
+#undef PWM2_LEVELS
+#define PWM2_LEVELS \
+ V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, \
+ V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, \
+ V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, V10, \
+ V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25, V25
+#define MAX_1x7135 40
+#undef MAX_1x7135
+#define HDR_ENABLE_LEVEL_MIN 41
+#define MAX_1x7135 40
+
+#undef DEFAULT_LEVEL
+#define DEFAULT_LEVEL 50
+
+// no PWM, so MCU clock speed can be slow
+#undef HALFSPEED_LEVEL
+#define HALFSPEED_LEVEL 41
+#undef QUARTERSPEED_LEVEL
+#define QUARTERSPEED_LEVEL 40 // seems to run fine at 10kHz/4, try reducing more?
+
+
+// AUX
+
+// there is no lighted button
+// (but it doesn't hurt to leave this enabled,
+// and then this firmware can be used on D3AA too)
+//#ifdef USE_BUTTON_LED
+//#undef USE_BUTTON_LED
+//#endif
+
+
diff --git a/hw/hank/kr1aa/arch b/hw/hank/kr1aa/arch
new file mode 100644
index 0000000..bcf4552
--- /dev/null
+++ b/hw/hank/kr1aa/arch
@@ -0,0 +1 @@
+avr32dd20
diff --git a/hw/hank/kr1aa/model b/hw/hank/kr1aa/model
new file mode 100644
index 0000000..cdc9591
--- /dev/null
+++ b/hw/hank/kr1aa/model
@@ -0,0 +1 @@
+0162
diff --git a/hw/hank/kr1aa/readme.md b/hw/hank/kr1aa/readme.md
new file mode 100644
index 0000000..247080b
--- /dev/null
+++ b/hw/hank/kr1aa/readme.md
@@ -0,0 +1,12 @@
+# Emisar / Noctigon KR1AA
+
+This is the same as the [D3AA](../emisar-d3aa) driver, but with the following
+changes:
+
+- Increased the time before measuring battery strength, to give the user more
+ time to tighten the tailcap first. The host has a reputation for being
+ difficult to tighten quickly enough to get a strong connection.
+
+- Tweaked the ramp shape slightly to eliminate a "gear change" zig-zag which
+ seems to occur on KR1AA but not D3AA.
+
diff --git a/hw/hank/lume-x1/anduril.h b/hw/hank/lume-x1/anduril.h
index c409e43..af56a3e 100644
--- a/hw/hank/lume-x1/anduril.h
+++ b/hw/hank/lume-x1/anduril.h
@@ -81,7 +81,15 @@
#define USE_BUTTON_LED
// this light has three aux LED channels: R, G, B
+// (and some builds tie these also to a RGB side button)
#define USE_AUX_RGB_LEDS
+#define USE_AUX_RGB_LEDS_WHILE_ON 25
+#define USE_INDICATOR_LED_WHILE_RAMPING
+// the aux LEDs are front-facing, so turn them off while main LEDs are on
+//#ifdef USE_INDICATOR_LED_WHILE_RAMPING
+//#undef USE_INDICATOR_LED_WHILE_RAMPING
+//#endif
+
// show each channel while it scroll by in the menu
#define USE_CONFIG_COLORS
@@ -95,11 +103,6 @@
#define POLICE_COLOR_STROBE_CH1 CM_AUXRED
#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU
-// the aux LEDs are front-facing, so turn them off while main LEDs are on
-#ifdef USE_INDICATOR_LED_WHILE_RAMPING
-#undef USE_INDICATOR_LED_WHILE_RAMPING
-#endif
-
#define PARTY_STROBE_ONTIME 1 // slow down party strobe
#define STROBE_OFF_LEVEL 1 // keep the regulator chips on between pulses