aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/anduril/anduril.c651
-rw-r--r--spaghetti-monster/anduril/cfg-blf-gt.h6
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern.h12
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d18.h4
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4.h4
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4sv2.h8
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h2
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4v2.5-nofet.h.THIS48
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4v2.5.h.THIS70
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4v2.h4
-rw-r--r--spaghetti-monster/anduril/cfg-ff-e01.h4
-rw-r--r--spaghetti-monster/anduril/cfg-ff-pl47.h12
-rw-r--r--spaghetti-monster/anduril/cfg-ff-pl47g2.h8
-rw-r--r--spaghetti-monster/anduril/cfg-ff-rot66.h2
-rw-r--r--spaghetti-monster/anduril/cfg-ff-rot66g2.h4
-rw-r--r--spaghetti-monster/anduril/cfg-fw3a-nofet.h4
-rw-r--r--spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h6
-rw-r--r--spaghetti-monster/anduril/cfg-mateminco-mf01s.h6
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k1-12v.h8
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h8
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k1.h8
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h12
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-kr4.h8
-rw-r--r--spaghetti-monster/anduril/cfg-sofirn-sp36.h4
-rw-r--r--spaghetti-monster/fsm-pcint.c19
25 files changed, 487 insertions, 435 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 085f4a3..7ab7aee 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -45,7 +45,7 @@
// short blips while ramping
#define BLINK_AT_RAMP_MIDDLE
//#define BLINK_AT_RAMP_FLOOR
-#define BLINK_AT_RAMP_CEILING
+#define BLINK_AT_RAMP_CEIL
//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode
// ramp down via regular button hold if a ramp-up ended <1s ago
@@ -82,8 +82,8 @@
// enable momentary mode
#define USE_MOMENTARY_MODE
-//Muggle mode for easy UI
-#define USE_MUGGLE_MODE
+// Include a simplified UI for non-enthusiasts?
+#define USE_SIMPLE_UI
// make the ramps configurable by the user
#define USE_RAMP_CONFIG
@@ -135,14 +135,22 @@
#define MAX_BIKING_LEVEL 120 // should be 127 or less
#define USE_BATTCHECK
-#if defined(USE_MUGGLE_MODE)
-#ifndef MUGGLE_FLOOR
-#define MUGGLE_FLOOR 22
+#if defined(USE_SIMPLE_UI)
+// start in the simple UI after each factory reset?
+#ifndef DEFAULT_SIMPLE_UI_ACTIVE
+#define DEFAULT_SIMPLE_UI_ACTIVE 1
#endif
-#ifndef MUGGLE_CEILING
-#define MUGGLE_CEILING (MAX_1x7135+20)
+#ifndef DEFAULT_SIMPLE_UI_FLOOR
+#define DEFAULT_SIMPLE_UI_FLOOR 22
#endif
+#ifndef DEFAULT_SIMPLE_UI_CEIL
+#define DEFAULT_SIMPLE_UI_CEIL (MAX_1x7135+20)
#endif
+#ifndef DEFAULT_SIMPLE_UI_STEPS
+#define DEFAULT_SIMPLE_UI_STEPS 3
+#endif
+#endif
+
#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending
// full FET strobe can be a bit much... use max regulated level instead,
@@ -193,8 +201,11 @@ typedef enum {
#ifdef USE_BEACON_MODE
beacon_seconds_e,
#endif
- #ifdef USE_MUGGLE_MODE
- muggle_mode_active_e,
+ #ifdef USE_SIMPLE_UI
+ simple_ui_active_e,
+ simple_ui_floor_e,
+ simple_ui_ceil_e,
+ simple_ui_steps_e,
#endif
#ifdef USE_THERMAL_REGULATION
therm_ceil_e,
@@ -294,7 +305,6 @@ uint8_t goodnight_state(Event event, uint16_t arg);
#ifdef USE_BEACON_MODE
// beacon mode and its related config mode
uint8_t beacon_state(Event event, uint16_t arg);
-uint8_t beacon_config_state(Event event, uint16_t arg);
#endif
#ifdef USE_SOS_MODE_IN_BLINKY_GROUP
// automatic SOS emergency signal
@@ -311,11 +321,6 @@ uint8_t momentary_state(Event event, uint16_t arg);
uint8_t momentary_mode = 0; // 0 = ramping, 1 = strobe
uint8_t momentary_active = 0; // boolean, true if active *right now*
#endif
-#ifdef USE_MUGGLE_MODE
-// muggle mode, super-simple, hard to exit
-uint8_t muggle_state(Event event, uint16_t arg);
-uint8_t muggle_mode_active = 0;
-#endif
// general helper function for config modes
uint8_t number_entry_state(Event event, uint16_t arg);
@@ -424,13 +429,37 @@ uint8_t memorized_level = DEFAULT_LEVEL;
#ifdef USE_MANUAL_MEMORY
uint8_t manual_memory = 0;
#endif
+#ifdef USE_SIMPLE_UI
+// whether to enable the simplified interface or not
+uint8_t simple_ui_active = DEFAULT_SIMPLE_UI_ACTIVE;
+#endif
// smooth vs discrete ramping
-volatile uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete
-volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
-volatile uint8_t ramp_smooth_ceil = RAMP_SMOOTH_CEIL;
-volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR;
-volatile uint8_t ramp_discrete_ceil = RAMP_DISCRETE_CEIL;
-volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS;
+uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete
+// current values, regardless of style
+uint8_t ramp_floor = RAMP_SMOOTH_FLOOR;
+uint8_t ramp_ceil = RAMP_SMOOTH_CEIL;
+// per style
+uint8_t ramp_floors[] = {
+ RAMP_SMOOTH_FLOOR,
+ RAMP_DISCRETE_FLOOR,
+ #ifdef USE_SIMPLE_UI
+ DEFAULT_SIMPLE_UI_FLOOR,
+ #endif
+ };
+uint8_t ramp_ceils[] = {
+ RAMP_SMOOTH_CEIL,
+ RAMP_DISCRETE_CEIL,
+ #ifdef USE_SIMPLE_UI
+ DEFAULT_SIMPLE_UI_CEIL,
+ #endif
+ };
+uint8_t ramp_stepss[] = {
+ 0,
+ RAMP_DISCRETE_STEPS,
+ #ifdef USE_SIMPLE_UI
+ DEFAULT_SIMPLE_UI_STEPS,
+ #endif
+ };
uint8_t ramp_discrete_step_size; // don't set this
#ifdef USE_INDICATOR_LED
@@ -453,6 +482,8 @@ uint8_t ramp_discrete_step_size; // don't set this
// (is a no-op for smooth ramp, but limits discrete ramp to only the
// correct levels for the user's config)
uint8_t nearest_level(int16_t target);
+// ensure ramp globals are correct
+void ramp_update_config();
#ifdef USE_THERMAL_REGULATION
// brightness before thermal step-down
@@ -638,6 +669,47 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
+ // 4 clicks: soft lockout
+ else if (event == EV_4clicks) {
+ blink_confirm(2);
+ set_state(lockout_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #if defined(USE_FACTORY_RESET) && defined(USE_SOFT_FACTORY_RESET)
+ // 13 clicks and hold the last click: invoke factory reset (reboot)
+ else if (event == EV_click13_hold) {
+ reboot();
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #ifdef USE_VERSION_CHECK
+ // 15+ clicks: show the version number
+ else if (event == EV_15clicks) {
+ set_state(version_check_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+
+ #ifdef USE_SIMPLE_UI
+ // 8 clicks, but hold last click: turn simple UI off
+ else if ((event == EV_click8_hold) && (!arg)) {
+ blink_confirm(1);
+ simple_ui_active = 0;
+ return MISCHIEF_MANAGED;
+ }
+
+ ////////// Every action below here is blocked in the simple UI //////////
+ if (simple_ui_active) {
+ return EVENT_NOT_HANDLED;
+ }
+ // 8 clicks: enable simple UI
+ else if (event == EV_8clicks) {
+ blink_confirm(1);
+ simple_ui_active = 1;
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+
// click, click, long-click: strobe mode
#ifdef USE_STROBE_STATE
else if (event == EV_click3_hold) {
@@ -650,12 +722,6 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- // 4 clicks: soft lockout
- else if (event == EV_4clicks) {
- blink_confirm(2);
- set_state(lockout_state, 0);
- return MISCHIEF_MANAGED;
- }
#ifdef USE_MOMENTARY_MODE
// 5 clicks: momentary mode
else if (event == EV_5clicks) {
@@ -664,14 +730,6 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- #ifdef USE_MUGGLE_MODE
- // 6 clicks: muggle mode
- else if (event == EV_6clicks) {
- blink_confirm(1);
- set_state(muggle_state, 0);
- return MISCHIEF_MANAGED;
- }
- #endif
#ifdef USE_INDICATOR_LED
// 7 clicks: change indicator LED mode
else if (event == EV_7clicks) {
@@ -725,28 +783,11 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- #ifdef USE_VERSION_CHECK
- // 15+ clicks: show the version number
- else if (event == EV_15clicks) {
- set_state(version_check_state, 0);
- return MISCHIEF_MANAGED;
- }
- #endif
- #if defined(USE_FACTORY_RESET) && defined(USE_SOFT_FACTORY_RESET)
- // 13 clicks and hold the last click: invoke factory reset (reboot)
- else if (event == EV_click13_hold) {
- reboot();
- return MISCHIEF_MANAGED;
- }
- #endif
return EVENT_NOT_HANDLED;
}
uint8_t steady_state(Event event, uint16_t arg) {
- uint8_t mode_min = ramp_smooth_floor;
- uint8_t mode_max = ramp_smooth_ceil;
- uint8_t ramp_step_size = 1;
#ifdef USE_REVERSING
static int8_t ramp_direction = 1;
#endif
@@ -755,11 +796,17 @@ uint8_t steady_state(Event event, uint16_t arg) {
// and this stores the level to return to
static uint8_t level_before_off = 0;
#endif
- if (ramp_style) {
- mode_min = ramp_discrete_floor;
- mode_max = ramp_discrete_ceil;
- ramp_step_size = ramp_discrete_step_size;
- }
+
+ // make sure ramp globals are correct...
+ // ... but they already are; no need to do it here
+ //ramp_update_config();
+ //nearest_level(1); // same effect, takes less space
+
+ uint8_t mode_min = ramp_floor;
+ uint8_t mode_max = ramp_ceil;
+ uint8_t step_size;
+ if (ramp_style) { step_size = ramp_discrete_step_size; }
+ else { step_size = 1; }
// turn LED on when we first enter the mode
if ((event == EV_enter_state) || (event == EV_reenter_state)) {
@@ -801,34 +848,22 @@ uint8_t steady_state(Event event, uint16_t arg) {
}
// 2 clicks: go to/from highest level
else if (event == EV_2clicks) {
- if (actual_level < MAX_LEVEL) {
+ uint8_t turbo_level;
+ #ifdef USE_SIMPLE_UI
+ if (simple_ui_active) { turbo_level = mode_max; }
+ else
+ #endif
+ turbo_level = MAX_LEVEL;
+
+ if (actual_level < turbo_level) {
// true turbo, not the mode-specific ceiling
- set_level_and_therm_target(MAX_LEVEL);
+ set_level_and_therm_target(turbo_level);
}
else {
set_level_and_therm_target(memorized_level);
}
return MISCHIEF_MANAGED;
}
- // 3 clicks: toggle smooth vs discrete ramping
- else if (event == EV_3clicks) {
- ramp_style = !ramp_style;
- save_config();
- #ifdef START_AT_MEMORIZED_LEVEL
- save_config_wl();
- #endif
- blip();
- memorized_level = nearest_level(actual_level);
- set_level_and_therm_target(memorized_level);
- return MISCHIEF_MANAGED;
- }
- #ifdef USE_RAMP_CONFIG
- // 4 clicks: configure this ramp mode
- else if (event == EV_4clicks) {
- push_state(ramp_config_state, 0);
- return MISCHIEF_MANAGED;
- }
- #endif
// hold: change brightness (brighter)
else if (event == EV_click1_hold) {
// ramp slower in discrete mode
@@ -854,11 +889,11 @@ uint8_t steady_state(Event event, uint16_t arg) {
set_state(lockout_state, 0);
}
memorized_level = nearest_level((int16_t)actual_level \
- + (ramp_step_size * ramp_direction));
+ + (step_size * ramp_direction));
#else
- memorized_level = nearest_level((int16_t)actual_level + ramp_step_size);
+ memorized_level = nearest_level((int16_t)actual_level + step_size);
#endif
- #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE)
+ #if defined(BLINK_AT_RAMP_CEIL) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
@@ -868,7 +903,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef BLINK_AT_RAMP_MIDDLE_2
|| (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
- #ifdef BLINK_AT_RAMP_CEILING
+ #ifdef BLINK_AT_RAMP_CEIL
|| (memorized_level == mode_max)
#endif
#if defined(USE_REVERSING) && defined(BLINK_AT_RAMP_FLOOR)
@@ -917,7 +952,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
// TODO? make it ramp up instead, if already at min?
- memorized_level = nearest_level((int16_t)actual_level - ramp_step_size);
+ memorized_level = nearest_level((int16_t)actual_level - step_size);
#if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
@@ -959,20 +994,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- #ifdef USE_MANUAL_MEMORY
- else if (event == EV_5clicks) {
- manual_memory = actual_level;
- save_config();
- blip();
- }
- else if (event == EV_click5_hold) {
- if (0 == arg) {
- manual_memory = 0;
- save_config();
- blip();
- }
- }
- #endif
+
#if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING)
else if (event == EV_tick) {
#ifdef USE_REVERSING
@@ -1073,6 +1095,51 @@ uint8_t steady_state(Event event, uint16_t arg) {
}
#endif // ifdef USE_SET_LEVEL_GRADUALLY
#endif // ifdef USE_THERMAL_REGULATION
+
+ ////////// Every action below here is blocked in the simple UI //////////
+ #ifdef USE_SIMPLE_UI
+ if (simple_ui_active) {
+ return EVENT_NOT_HANDLED;
+ }
+ #endif
+
+ // 3 clicks: toggle smooth vs discrete ramping
+ else if (event == EV_3clicks) {
+ ramp_style = !ramp_style;
+ save_config();
+ #ifdef START_AT_MEMORIZED_LEVEL
+ save_config_wl();
+ #endif
+ blip();
+ memorized_level = nearest_level(actual_level);
+ set_level_and_therm_target(memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+
+ #ifdef USE_MANUAL_MEMORY
+ else if (event == EV_5clicks) {
+ manual_memory = actual_level;
+ save_config();
+ blip();
+ return MISCHIEF_MANAGED;
+ }
+ else if (event == EV_click5_hold) {
+ if (0 == arg) {
+ manual_memory = 0;
+ save_config();
+ blip();
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+
+ #ifdef USE_RAMP_CONFIG
+ // 7 clicks: configure this ramp mode
+ else if (event == EV_7clicks) {
+ push_state(ramp_config_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
return EVENT_NOT_HANDLED;
}
@@ -1260,6 +1327,14 @@ uint8_t strobe_state(Event event, uint16_t arg) {
save_config();
return MISCHIEF_MANAGED;
}
+ #ifdef USE_MOMENTARY_MODE
+ // 5 clicks: go to momentary mode (momentary strobe)
+ else if (event == EV_5clicks) {
+ set_state(momentary_state, 0);
+ set_level(0);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
// clock tick: bump the random seed
else if (event == EV_tick) {
@@ -1273,6 +1348,20 @@ uint8_t strobe_state(Event event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
+
+#ifdef USE_BEACON_MODE
+inline void beacon_mode_iter() {
+ // one iteration of main loop()
+ if (! button_last_state) {
+ set_level(memorized_level);
+ nice_delay_ms(100);
+ set_level(0);
+ nice_delay_ms(((beacon_seconds) * 1000) - 100);
+ }
+}
+#endif // #ifdef USE_BEACON_MODE
+
+
#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
inline void party_tactical_strobe_mode_iter(uint8_t st) {
// one iteration of main loop()
@@ -1591,6 +1680,13 @@ inline void sos_mode_iter() {
#ifdef USE_BATTCHECK
uint8_t battcheck_state(Event event, uint16_t arg) {
+ ////////// Every action below here is blocked in the simple UI //////////
+ #ifdef USE_SIMPLE_UI
+ if (simple_ui_active) {
+ return EVENT_NOT_HANDLED;
+ }
+ #endif
+
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -1634,8 +1730,8 @@ uint8_t tempcheck_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- // 4 clicks: thermal config mode
- else if (event == EV_4clicks) {
+ // 7 clicks: thermal config mode
+ else if (event == EV_7clicks) {
push_state(thermal_config_state, 0);
return MISCHIEF_MANAGED;
}
@@ -1664,9 +1760,17 @@ uint8_t beacon_state(Event event, uint16_t arg) {
#endif
return MISCHIEF_MANAGED;
}
- // 4 clicks: beacon config mode
- else if (event == EV_4clicks) {
- push_state(beacon_config_state, 0);
+ // hold: configure beacon timing
+ else if (event == EV_click1_hold) {
+ if (0 == (arg % TICKS_PER_SECOND)) {
+ blink_confirm(1);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // release hold: save new timing
+ else if (event == EV_click1_hold_release) {
+ beacon_seconds = 1 + (arg / TICKS_PER_SECOND);
+ save_config();
return MISCHIEF_MANAGED;
}
return EVENT_NOT_HANDLED;
@@ -1733,15 +1837,14 @@ uint8_t lockout_state(Event event, uint16_t arg) {
if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
#ifdef LOCKOUT_MOON_LOWEST
// Use lowest moon configured
- uint8_t lvl = ramp_smooth_floor;
- if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
+ uint8_t lvl = ramp_floors[0];
+ if (ramp_floors[1] < lvl) lvl = ramp_floors[1];
set_level(lvl);
#elif defined(LOCKOUT_MOON_FANCY)
- uint8_t levels[] = { ramp_smooth_floor, ramp_discrete_floor };
if ((event & 0x0f) == 2) {
- set_level(levels[ramp_style^1]);
+ set_level(ramp_floors[ramp_style^1]);
} else {
- set_level(levels[ramp_style]);
+ set_level(ramp_floors[ramp_style]);
}
#else
// Use moon from current ramp
@@ -1791,9 +1894,29 @@ uint8_t lockout_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
+ // 4 clicks: exit and turn on
+ else if (event == EV_4clicks) {
+ blink_confirm(1);
+ set_state(steady_state, memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ // 4 clicks, but hold last: exit and start at floor
+ else if (event == EV_click4_hold) {
+ blink_confirm(1);
+ set_state(steady_state, 1);
+ return MISCHIEF_MANAGED;
+ }
+
+ ////////// Every action below here is blocked in the simple UI //////////
+ #ifdef USE_SIMPLE_UI
+ if (simple_ui_active) {
+ return EVENT_NOT_HANDLED;
+ }
+ #endif
+
#if defined(USE_INDICATOR_LED)
- // 3 clicks: rotate through indicator LED modes (lockout mode)
- else if (event == EV_3clicks) {
+ // 7 clicks: rotate through indicator LED modes (lockout mode)
+ else if (event == EV_7clicks) {
#if defined(USE_INDICATOR_LED)
uint8_t mode = indicator_led_mode >> 2;
#ifdef TICK_DURING_STANDBY
@@ -1812,8 +1935,8 @@ uint8_t lockout_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#elif defined(USE_AUX_RGB_LEDS)
- // 3 clicks: change RGB aux LED pattern
- else if (event == EV_3clicks) {
+ // 7 clicks: change RGB aux LED pattern
+ else if (event == EV_7clicks) {
uint8_t mode = (rgb_led_lockout_mode >> 4) + 1;
mode = mode % RGB_LED_NUM_PATTERNS;
rgb_led_lockout_mode = (mode << 4) | (rgb_led_lockout_mode & 0x0f);
@@ -1822,8 +1945,8 @@ uint8_t lockout_state(Event event, uint16_t arg) {
blink_confirm(1);
return MISCHIEF_MANAGED;
}
- // click, click, hold: change RGB aux LED color
- else if (event == EV_click3_hold) {
+ // 7H: change RGB aux LED color
+ else if (event == EV_click7_hold) {
setting_rgb_mode_now = 1;
if (0 == (arg & 0x3f)) {
uint8_t mode = (rgb_led_lockout_mode & 0x0f) + 1;
@@ -1834,19 +1957,13 @@ uint8_t lockout_state(Event event, uint16_t arg) {
rgb_led_update(rgb_led_lockout_mode, arg);
return MISCHIEF_MANAGED;
}
- // click, click, hold, release: save new color
- else if (event == EV_click3_hold_release) {
+ // 7H, release: save new color
+ else if (event == EV_click7_hold_release) {
setting_rgb_mode_now = 0;
save_config();
return MISCHIEF_MANAGED;
}
#endif
- // 4 clicks: exit
- else if (event == EV_4clicks) {
- blink_confirm(1);
- set_state(off_state, 0);
- return MISCHIEF_MANAGED;
- }
return EVENT_NOT_HANDLED;
}
@@ -1916,165 +2033,6 @@ uint8_t momentary_state(Event event, uint16_t arg) {
#endif
-#ifdef USE_MUGGLE_MODE
-uint8_t muggle_state(Event event, uint16_t arg) {
- static int8_t ramp_direction;
- static int8_t muggle_off_mode;
-
- // turn LED off when we first enter the mode
- if (event == EV_enter_state) {
- ramp_direction = 1;
-
- #ifdef START_AT_MEMORIZED_LEVEL
- memorized_level = arg;
- muggle_off_mode = 0;
- set_level(memorized_level);
-
- if (! muggle_mode_active) { // don't write eeprom at every boot
- muggle_mode_active = 1;
- save_config();
- }
- #else
- muggle_mode_active = 1;
- save_config();
-
- muggle_off_mode = 1;
- //memorized_level = MAX_1x7135;
- memorized_level = (MUGGLE_FLOOR + MUGGLE_CEILING) / 2;
- #endif
- return MISCHIEF_MANAGED;
- }
- // initial press: moon hint
- else if (event == EV_click1_press) {
- if (muggle_off_mode)
- set_level(MUGGLE_FLOOR);
- }
- // initial release: direct to memorized level
- else if (event == EV_click1_release) {
- if (muggle_off_mode)
- set_level(memorized_level);
- }
- // if the user keeps pressing, turn off
- else if (event == EV_click2_press) {
- muggle_off_mode = 1;
- set_level(0);
- }
- // 1 click: on/off
- else if (event == EV_1click) {
- muggle_off_mode ^= 1;
- if (muggle_off_mode) {
- set_level(0);
- }
- /*
- else {
- set_level(memorized_level);
- }
- */
- return MISCHIEF_MANAGED;
- }
- // hold: change brightness
- else if (event == EV_click1_hold) {
- // ramp at half speed
- if (arg & 1) return MISCHIEF_MANAGED;
-
- // if off, start at bottom
- if (muggle_off_mode) {
- muggle_off_mode = 0;
- ramp_direction = 1;
- set_level(MUGGLE_FLOOR);
- }
- else {
- uint8_t m;
- m = actual_level;
- // ramp down if already at ceiling
- if ((arg <= 1) && (m >= MUGGLE_CEILING)) ramp_direction = -1;
- // ramp
- m += ramp_direction;
- if (m < MUGGLE_FLOOR)
- m = MUGGLE_FLOOR;
- if (m > MUGGLE_CEILING)
- m = MUGGLE_CEILING;
- memorized_level = m;
- set_level(m);
- }
- return MISCHIEF_MANAGED;
- }
- // reverse ramp direction on hold release
- else if (event == EV_click1_hold_release) {
- ramp_direction = -ramp_direction;
- #ifdef START_AT_MEMORIZED_LEVEL
- save_config_wl(); // momentary use should retain brightness level
- #endif
- return MISCHIEF_MANAGED;
- }
- /*
- // click, hold: change brightness (dimmer)
- else if (event == EV_click2_hold) {
- ramp_direction = 1;
- if (memorized_level > MUGGLE_FLOOR)
- memorized_level = actual_level - 1;
- set_level(memorized_level);
- return MISCHIEF_MANAGED;
- }
- */
- // 6 clicks: exit muggle mode
- else if (event == EV_6clicks) {
- blink_confirm(1);
- muggle_mode_active = 0;
- save_config();
- set_state(off_state, 0);
- return MISCHIEF_MANAGED;
- }
- // tick: housekeeping
- else if (event == EV_tick) {
- // un-reverse after 1 second
- if (arg == TICKS_PER_SECOND) ramp_direction = 1;
-
- // turn off, but don't go to the main "off" state
- if (muggle_off_mode) {
- if (arg > TICKS_PER_SECOND*1) { // sleep after 1 second
- #ifdef USE_AUX_RGB_LEDS_WHILE_ON
- rgb_led_set(0);
- #endif
- go_to_standby = 1; // sleep while light is off
- }
- }
- return MISCHIEF_MANAGED;
- }
- #ifdef USE_THERMAL_REGULATION
- // overheating is handled specially in muggle mode
- else if(event == EV_temperature_high) {
- #if 0
- blip();
- #endif
- // ignore warnings while off
- if (! muggle_off_mode) {
- // step down proportional to the amount of overheating
- int16_t new = actual_level - arg;
- if (new < MUGGLE_FLOOR) { new = MUGGLE_FLOOR; }
- set_level(new);
- }
- return MISCHIEF_MANAGED;
- }
- #endif
- #ifdef USE_LVP
- // low voltage is handled specially in muggle mode
- else if(event == EV_voltage_low) {
- uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
- if (lvl >= MUGGLE_FLOOR) {
- set_level(lvl);
- } else {
- muggle_off_mode = 1;
- }
- return MISCHIEF_MANAGED;
- }
- #endif
-
- return EVENT_NOT_HANDLED;
-}
-#endif
-
-
#ifdef USE_VERSION_CHECK
uint8_t version_check_state(Event event, uint16_t arg) {
return EVENT_NOT_HANDLED;
@@ -2121,25 +2079,18 @@ uint8_t config_state_base(Event event, uint16_t arg,
void ramp_config_save() {
// parse values
uint8_t val;
- if (ramp_style) { // discrete / stepped ramp
+ uint8_t style = ramp_style;
+ // TODO: detect if we're configuring the simple UI
- val = config_state_values[0];
- if (val) { ramp_discrete_floor = val; }
+ val = config_state_values[0];
+ if (val) { ramp_floors[style] = val; }
- val = config_state_values[1];
- if (val) { ramp_discrete_ceil = MAX_LEVEL + 1 - val; }
+ val = config_state_values[1];
+ if (val) { ramp_ceils[style] = MAX_LEVEL + 1 - val; }
+ if (ramp_style) { // discrete / stepped ramp
val = config_state_values[2];
- if (val) ramp_discrete_steps = val;
-
- } else { // smooth ramp
-
- val = config_state_values[0];
- if (val) { ramp_smooth_floor = val; }
-
- val = config_state_values[1];
- if (val) { ramp_smooth_ceil = MAX_LEVEL + 1 - val; }
-
+ if (val) ramp_stepss[style] = val;
}
}
@@ -2180,30 +2131,6 @@ uint8_t thermal_config_state(Event event, uint16_t arg) {
#endif // #ifdef USE_THERMAL_REGULATION
-#ifdef USE_BEACON_MODE
-void beacon_config_save() {
- // parse values
- uint8_t val = config_state_values[0];
- if (val) {
- beacon_seconds = val;
- }
-}
-
-uint8_t beacon_config_state(Event event, uint16_t arg) {
- return config_state_base(event, arg,
- 1, beacon_config_save);
-}
-
-inline void beacon_mode_iter() {
- // one iteration of main loop()
- set_level(memorized_level);
- nice_delay_ms(100);
- set_level(0);
- nice_delay_ms(((beacon_seconds) * 1000) - 100);
-}
-#endif // #ifdef USE_BEACON_MODE
-
-
uint8_t number_entry_state(Event event, uint16_t arg) {
static uint8_t value;
static uint8_t blinks_left;
@@ -2293,26 +2220,25 @@ uint8_t number_entry_state(Event event, uint16_t arg) {
// find the ramp level closest to the target,
// using only the levels which are allowed in the current state
uint8_t nearest_level(int16_t target) {
+ ramp_update_config();
+
// bounds check
// using int16_t here saves us a bunch of logic elsewhere,
// by allowing us to correct for numbers < 0 or > 255 in one central place
- uint8_t mode_min = ramp_smooth_floor;
- uint8_t mode_max = ramp_smooth_ceil;
- if (ramp_style) {
- mode_min = ramp_discrete_floor;
- mode_max = ramp_discrete_ceil;
- }
+ uint8_t mode_min = ramp_floor;
+ uint8_t mode_max = ramp_ceil;
if (target < mode_min) return mode_min;
if (target > mode_max) return mode_max;
// the rest isn't relevant for smooth ramping
if (! ramp_style) return target;
- uint8_t ramp_range = ramp_discrete_ceil - ramp_discrete_floor;
- ramp_discrete_step_size = ramp_range / (ramp_discrete_steps-1);
- uint8_t this_level = ramp_discrete_floor;
+ uint8_t ramp_range = mode_max - mode_min;
+ uint8_t num_steps = ramp_stepss[1 + simple_ui_active];
+ ramp_discrete_step_size = ramp_range / (num_steps-1);
+ uint8_t this_level = mode_min;
- for(uint8_t i=0; i<ramp_discrete_steps; i++) {
- this_level = ramp_discrete_floor + (i * (uint16_t)ramp_range / (ramp_discrete_steps-1));
+ for(uint8_t i=0; i<num_steps; i++) {
+ this_level = mode_min + (i * (uint16_t)ramp_range / (num_steps-1));
int16_t diff = target - this_level;
if (diff < 0) diff = -diff;
if (diff <= (ramp_discrete_step_size>>1))
@@ -2321,6 +2247,15 @@ uint8_t nearest_level(int16_t target) {
return this_level;
}
+// ensure ramp globals are correct
+void ramp_update_config() {
+ uint8_t which = ramp_style;
+ if (simple_ui_active) { which = 2; }
+
+ ramp_floor = ramp_floors[which];
+ ramp_ceil = ramp_ceils[which];
+}
+
#ifdef USE_THERMAL_REGULATION
void set_level_and_therm_target(uint8_t level) {
target_level = level;
@@ -2333,6 +2268,7 @@ void blink_confirm(uint8_t num) {
set_level(MAX_LEVEL/4);
delay_4ms(10/4);
set_level(0);
+ // TODO: only do this delay if num > 1
delay_4ms(100/4);
}
}
@@ -2546,11 +2482,11 @@ void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[ramp_style_e];
#ifdef USE_RAMP_CONFIG
- ramp_smooth_floor = eeprom[ramp_smooth_floor_e];
- ramp_smooth_ceil = eeprom[ramp_smooth_ceil_e];
- ramp_discrete_floor = eeprom[ramp_discrete_floor_e];
- ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e];
- ramp_discrete_steps = eeprom[ramp_discrete_steps_e];
+ ramp_floors[0] = eeprom[ramp_smooth_floor_e];
+ ramp_ceils[0] = eeprom[ramp_smooth_ceil_e];
+ ramp_floors[1] = eeprom[ramp_discrete_floor_e];
+ ramp_ceils[1] = eeprom[ramp_discrete_ceil_e];
+ ramp_stepss[1] = eeprom[ramp_discrete_steps_e];
#endif
#ifdef USE_MANUAL_MEMORY
manual_memory = eeprom[manual_memory_e];
@@ -2569,8 +2505,11 @@ void load_config() {
#ifdef USE_BEACON_MODE
beacon_seconds = eeprom[beacon_seconds_e];
#endif
- #ifdef USE_MUGGLE_MODE
- muggle_mode_active = eeprom[muggle_mode_active_e];
+ #ifdef USE_SIMPLE_UI
+ simple_ui_active = eeprom[simple_ui_active_e];
+ ramp_floors[2] = eeprom[simple_ui_floor_e];
+ ramp_ceils[2] = eeprom[simple_ui_ceil_e];
+ ramp_stepss[2] = eeprom[simple_ui_steps_e];
#endif
#ifdef USE_THERMAL_REGULATION
therm_ceil = eeprom[therm_ceil_e];
@@ -2594,11 +2533,11 @@ void load_config() {
void save_config() {
eeprom[ramp_style_e] = ramp_style;
#ifdef USE_RAMP_CONFIG
- eeprom[ramp_smooth_floor_e] = ramp_smooth_floor;
- eeprom[ramp_smooth_ceil_e] = ramp_smooth_ceil;
- eeprom[ramp_discrete_floor_e] = ramp_discrete_floor;
- eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil;
- eeprom[ramp_discrete_steps_e] = ramp_discrete_steps;
+ eeprom[ramp_smooth_floor_e] = ramp_floors[0];
+ eeprom[ramp_smooth_ceil_e] = ramp_ceils[0];
+ eeprom[ramp_discrete_floor_e] = ramp_floors[1];
+ eeprom[ramp_discrete_ceil_e] = ramp_ceils[1];
+ eeprom[ramp_discrete_steps_e] = ramp_stepss[1];
#endif
#ifdef USE_MANUAL_MEMORY
eeprom[manual_memory_e] = manual_memory;
@@ -2617,8 +2556,11 @@ void save_config() {
#ifdef USE_BEACON_MODE
eeprom[beacon_seconds_e] = beacon_seconds;
#endif
- #ifdef USE_MUGGLE_MODE
- eeprom[muggle_mode_active_e] = muggle_mode_active;
+ #ifdef USE_SIMPLE_UI
+ eeprom[simple_ui_active_e] = simple_ui_active;
+ eeprom[simple_ui_floor_e] = ramp_floors[2];
+ eeprom[simple_ui_ceil_e] = ramp_ceils[2];
+ eeprom[simple_ui_steps_e] = ramp_stepss[2];
#endif
#ifdef USE_THERMAL_REGULATION
eeprom[therm_ceil_e] = therm_ceil;
@@ -2657,8 +2599,7 @@ void low_voltage() {
}
#endif
- // in normal or muggle mode, step down or turn off
- //else if ((state == steady_state) || (state == muggle_state)) {
+ // in normal mode, step down or turn off
else if (state == steady_state) {
if (actual_level > 1) {
uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
@@ -2681,11 +2622,6 @@ void setup() {
// power clicky acts as a momentary mode
load_config();
- #ifdef USE_MUGGLE_MODE
- if (muggle_mode_active)
- push_state(muggle_state, memorized_level);
- else
- #endif
if (button_is_pressed())
// hold button to go to moon
push_state(steady_state, 1);
@@ -2712,12 +2648,7 @@ void setup() {
push_state(tint_ramping_state, 0);
#endif // ifdef USE_TINT_RAMPING
- #ifdef USE_MUGGLE_MODE
- if (muggle_mode_active)
- push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2);
- else
- #endif
- push_state(off_state, 1);
+ push_state(off_state, 1);
#endif // ifdef START_AT_MEMORIZED_LEVEL
}
@@ -2807,6 +2738,10 @@ void loop() {
#ifdef USE_BATTCHECK
else if (state == battcheck_state) {
battcheck();
+ #ifdef USE_SIMPLE_UI
+ // in simple mode, turn off after one readout
+ if (simple_ui_active) set_state(off_state, 0);
+ #endif
}
#endif
diff --git a/spaghetti-monster/anduril/cfg-blf-gt.h b/spaghetti-monster/anduril/cfg-blf-gt.h
index 6a74bbc..2ba6455 100644
--- a/spaghetti-monster/anduril/cfg-blf-gt.h
+++ b/spaghetti-monster/anduril/cfg-blf-gt.h
@@ -9,7 +9,7 @@
#define TICK_DURING_STANDBY
// don't blink during ramp, it's irrelevant and annoying on this light
-#undef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_CEIL
#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_FLOOR
@@ -32,9 +32,9 @@
// use 2.0 A as the ceiling, 2.5 A only for turbo
// start both ramps at the bottom; even moon throws a long way on the GT
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL POWER_80PX
+#define RAMP_SMOOTH_CEIL POWER_80PX
#define RAMP_DISCRETE_FLOOR 1
-#define RAMP_DISCRETE_CEIL POWER_80PX
+#define RAMP_DISCRETE_CEIL POWER_80PX
#define RAMP_DISCRETE_STEPS 7
// stop panicking at 80% power, this light has plenty of thermal mass
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h
index e12a453..39ae7b8 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern.h
@@ -50,13 +50,13 @@
// because this lantern isn't overpowered
#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 150
+#define RAMP_SMOOTH_CEIL 150
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 5
-#define MUGGLE_FLOOR 15 // about 20 lm
-#define MUGGLE_CEILING 115 // about 350 lm
+#define SIMPLE_UI_FLOOR 15 // about 20 lm
+#define SIMPLE_UI_CEIL 115 // about 350 lm
#define USE_SOS_MODE
#define USE_SOS_MODE_IN_BLINKY_GROUP
@@ -83,6 +83,6 @@
#undef BLINK_AT_RAMP_FLOOR
#endif
// except the top... blink at the top
-#ifndef BLINK_AT_RAMP_CEILING
-#define BLINK_AT_RAMP_CEILING
+#ifndef BLINK_AT_RAMP_CEIL
+#define BLINK_AT_RAMP_CEIL
#endif
diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h
index 72f0589..ea02f8c 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d18.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d18.h
@@ -32,13 +32,13 @@
// higher floor than default, and stop at highest regulated level
#define RAMP_DISCRETE_FLOOR 25
-#define RAMP_DISCRETE_CEIL MAX_Nx7135
+#define RAMP_DISCRETE_CEIL MAX_Nx7135
#define RAMP_DISCRETE_STEPS 7
// only blink at max regulated level and ceiling
#define BLINK_AT_RAMP_MIDDLE
#define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135
-#define BLINK_AT_RAMP_CEILING
+#define BLINK_AT_RAMP_CEIL
// stop panicking at about ~40% power or ~5000 lm
#define THERM_FASTER_LEVEL 125
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4.h b/spaghetti-monster/anduril/cfg-emisar-d4.h
index 7700d88..818e55e 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4.h
@@ -12,10 +12,10 @@
#define QUARTERSPEED_LEVEL 6
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 120
+#define RAMP_SMOOTH_CEIL 120
// 10, 28, 46, [65], 83, 101, 120
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
// stop panicking at ~30% power or ~1200 lm
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4sv2.h b/spaghetti-monster/anduril/cfg-emisar-d4sv2.h
index 0f3a217..7652bf5 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4sv2.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4sv2.h
@@ -27,17 +27,17 @@
#define QUARTERSPEED_LEVEL 8
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 130
+#define RAMP_SMOOTH_CEIL 130
// 20, 38, 56, 75, [93], 111, 130
#define RAMP_DISCRETE_FLOOR 20
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
//#define DEFAULT_LEVEL MAX_Nx7135
#define STROBE_BRIGHTNESS MAX_LEVEL
-#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
-#define MUGGLE_CEILING MAX_Nx7135
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL MAX_Nx7135
// stop panicking at ~50% power or ~2000 lm
#define THERM_FASTER_LEVEL 130
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h b/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h
index cbb5891..d620213 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h
@@ -23,7 +23,7 @@
#undef RAMP_DISCRETE_CEIL
#undef RAMP_DISCRETE_STEPS
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL 150
+#define RAMP_DISCRETE_CEIL 150
#define RAMP_DISCRETE_STEPS 5
#define CANDLE_AMPLITUDE 60
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.5-nofet.h.THIS b/spaghetti-monster/anduril/cfg-emisar-d4v2.5-nofet.h.THIS
new file mode 100644
index 0000000..92c4252
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4v2.5-nofet.h.THIS
@@ -0,0 +1,48 @@
+// Emisar D4v2.5 (fetless) config options for Anduril
+// (adapted from cfg-noctigon-kr4-nofet.h)
+#include "cfg-emisar-d4v2.5.h"
+// ATTINY: 1634
+
+// brightness w/ SST-20 4000K LEDs:
+// 0/1023: 0.35 lm
+// 1/1023: 2.56 lm
+// max regulated: 1740 lm
+// level_calc.py 3.0 1 150 7135 0 5 1740
+#undef PWM_CHANNELS
+#define PWM_CHANNELS 1
+#define RAMP_LENGTH 150
+#undef PWM1_LEVELS
+#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023
+#undef PWM2_LEVELS
+#undef DEFAULT_LEVEL
+#define DEFAULT_LEVEL 50
+#undef MAX_1x7135
+#define MAX_1x7135 150
+
+#undef RAMP_SMOOTH_FLOOR
+#undef RAMP_SMOOTH_CEIL
+#undef RAMP_DISCRETE_FLOOR
+#undef RAMP_DISCRETE_CEIL
+#undef RAMP_DISCRETE_STEPS
+
+#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable
+#define RAMP_SMOOTH_CEIL 130
+// 10, 30, [50], 70, 90, 110, 130 (plus [150] on turbo)
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+#undef SIMPLE_UI_FLOOR
+#undef SIMPLE_UI_CEIL
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 70
+
+// make candle mode wobble more
+#define CANDLE_AMPLITUDE 32
+
+// stop panicking at ~90% power or ~1600 lm
+#undef THERM_FASTER_LEVEL
+#define THERM_FASTER_LEVEL 143
+#undef MIN_THERM_STEPDOWN
+#define MIN_THERM_STEPDOWN DEFAULT_LEVEL
+
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.5.h.THIS b/spaghetti-monster/anduril/cfg-emisar-d4v2.5.h.THIS
new file mode 100644
index 0000000..83f2c3a
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4v2.5.h.THIS
@@ -0,0 +1,70 @@
+// Emisar D4v2.5 config options for Anduril
+// (uses KR4 driver, plus a button LED)
+#include "hwdef-Noctigon_KR4.h"
+// ATTINY: 1634
+
+// this light has three aux LED channels: R, G, B
+#define USE_AUX_RGB_LEDS
+// it also has an independent LED in the button
+#define USE_BUTTON_LED
+// the aux LEDs are front-facing, so turn them off while main LEDs are on
+// TODO: the whole "indicator LED" thing needs to be refactored into
+// "aux LED(s)" and "button LED(s)" since they work a bit differently
+//#define USE_AUX_RGB_LEDS_WHILE_ON
+#ifdef USE_INDICATOR_LED_WHILE_RAMPING
+#undef USE_INDICATOR_LED_WHILE_RAMPING
+#endif
+#define RGB_LED_OFF_DEFAULT 0x17 // low, rainbow
+#define RGB_LED_LOCKOUT_DEFAULT 0x37 // blinking, rainbow
+#define RGB_RAINBOW_SPEED 0x03 // half a second per color
+
+// enable blinking aux LEDs
+#define TICK_DURING_STANDBY
+#define STANDBY_TICK_SPEED 3 // every 0.128 s
+//#define STANDBY_TICK_SPEED 4 // every 0.256 s
+//#define STANDBY_TICK_SPEED 5 // every 0.512 s
+
+
+// copied from Noctigon KR4
+// brightness w/ SST-20 4000K LEDs:
+// 0/1023: 0.35 lm
+// 1/1023: 2.56 lm
+// max regulated: 1740 lm
+// FET: ~3700 lm
+// maxreg at 130: level_calc.py cube 2 150 7135 0 2.5 1740 FET 1 10 2565
+// maxreg at 120: level_calc.py cube 2 150 7135 0 2.5 1740 FET 1 10 3190
+#define RAMP_LENGTH 150
+#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,4,5,6,7,8,9,10,11,13,14,15,17,19,20,22,24,26,28,30,33,35,38,40,43,46,49,52,55,59,62,66,70,74,78,82,86,91,96,100,105,111,116,121,127,133,139,145,151,158,165,172,179,186,193,201,209,217,225,234,243,251,261,270,280,289,299,310,320,331,342,353,364,376,388,400,412,425,438,451,464,478,492,506,521,536,551,566,582,597,614,630,647,664,681,699,717,735,754,772,792,811,831,851,871,892,913,935,956,978,1001,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,0
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,51,79,109,138,168,198,229,260,292,324,357,390,423,457,492,527,562,598,634,671,708,746,784,822,861,901,941,982,1023
+#define DEFAULT_LEVEL 46
+#define MAX_1x7135 120
+#define HALFSPEED_LEVEL 10
+#define QUARTERSPEED_LEVEL 2
+
+#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable
+#define RAMP_SMOOTH_CEIL 120
+// 10, 28, [46], 65, 83, 101, [120]
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 65
+
+// stop panicking at ~25% power or ~1000 lm
+#define THERM_FASTER_LEVEL 100
+#define MIN_THERM_STEPDOWN DEFAULT_LEVEL
+#define THERM_NEXT_WARNING_THRESHOLD 16 // accumulate less error before adjusting
+#define THERM_RESPONSE_MAGNITUDE 128 // bigger adjustments
+
+// easier access to thermal config mode
+#define USE_TENCLICK_THERMAL_CONFIG
+
+// slow down party strobe; this driver can't pulse for 1ms or less
+// (only needed on no-FET build)
+//#define PARTY_STROBE_ONTIME 2
+
+#define THERM_CAL_OFFSET 5
+
+// allow 13H reset for consistency with KR4
+#define USE_SOFT_FACTORY_RESET
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.h b/spaghetti-monster/anduril/cfg-emisar-d4v2.h
index 241ca7e..dc96c47 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4v2.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4v2.h
@@ -31,10 +31,10 @@
#define QUARTERSPEED_LEVEL 6
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 120
+#define RAMP_SMOOTH_CEIL 120
// 10, 28, 46, [65], 83, 101, 120
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
// stop panicking at ~30% power or ~1200 lm
diff --git a/spaghetti-monster/anduril/cfg-ff-e01.h b/spaghetti-monster/anduril/cfg-ff-e01.h
index 3b47165..7b3578a 100644
--- a/spaghetti-monster/anduril/cfg-ff-e01.h
+++ b/spaghetti-monster/anduril/cfg-ff-e01.h
@@ -2,8 +2,8 @@
// most of the good stuff is in the FFUI config; just copy it
#include "../fireflies-ui/cfg-ff-e01.h"
-#ifndef BLINK_AT_RAMP_CEILING
-#define BLINK_AT_RAMP_CEILING
+#ifndef BLINK_AT_RAMP_CEIL
+#define BLINK_AT_RAMP_CEIL
#endif
// 20, 38, 56, 75, [93], 111, 130 (93 is highest regulated)
diff --git a/spaghetti-monster/anduril/cfg-ff-pl47.h b/spaghetti-monster/anduril/cfg-ff-pl47.h
index e6907c1..20d0306 100644
--- a/spaghetti-monster/anduril/cfg-ff-pl47.h
+++ b/spaghetti-monster/anduril/cfg-ff-pl47.h
@@ -48,20 +48,20 @@
// 10, 28, 46, 65, 83, 101, 120 (83 is highest regulated)
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL 120
+#define RAMP_DISCRETE_CEIL 120
#define RAMP_DISCRETE_STEPS 7
// ~25 lm to ~300 lm
-#define MUGGLE_FLOOR 30
-#define MUGGLE_CEILING MAX_1x7135
+#define SIMPLE_UI_FLOOR 30
+#define SIMPLE_UI_CEIL MAX_1x7135
// ~50 lm to ~500 lm
-//#define MUGGLE_FLOOR 40
-//#define MUGGLE_CEILING 90
+//#define SIMPLE_UI_FLOOR 40
+//#define SIMPLE_UI_CEIL 90
// regulate down faster when the FET is active, slower otherwise
#define THERM_FASTER_LEVEL 135 // throttle back faster when high
// don't do this
#undef BLINK_AT_RAMP_MIDDLE
-#undef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_CEIL
diff --git a/spaghetti-monster/anduril/cfg-ff-pl47g2.h b/spaghetti-monster/anduril/cfg-ff-pl47g2.h
index cab008c..8ccd6d6 100644
--- a/spaghetti-monster/anduril/cfg-ff-pl47g2.h
+++ b/spaghetti-monster/anduril/cfg-ff-pl47g2.h
@@ -39,17 +39,17 @@
// 10, 28, 46, 65, [83], 101, 120
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL 120
+#define RAMP_DISCRETE_CEIL 120
#define RAMP_DISCRETE_STEPS 7
// ~25 lm to ~300 lm
-#define MUGGLE_FLOOR 30
-#define MUGGLE_CEILING MAX_1x7135
+#define SIMPLE_UI_FLOOR 30
+#define SIMPLE_UI_CEIL MAX_1x7135
// regulate down faster when the FET is active, slower otherwise
#define THERM_FASTER_LEVEL 135 // throttle back faster when high
// don't do this
#undef BLINK_AT_RAMP_MIDDLE
-#undef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_CEIL
diff --git a/spaghetti-monster/anduril/cfg-ff-rot66.h b/spaghetti-monster/anduril/cfg-ff-rot66.h
index a87b66d..cefe48d 100644
--- a/spaghetti-monster/anduril/cfg-ff-rot66.h
+++ b/spaghetti-monster/anduril/cfg-ff-rot66.h
@@ -40,5 +40,5 @@
// don't do this
#undef BLINK_AT_RAMP_MIDDLE
-#undef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_CEIL
diff --git a/spaghetti-monster/anduril/cfg-ff-rot66g2.h b/spaghetti-monster/anduril/cfg-ff-rot66g2.h
index 4e353a8..d4c8ccf 100644
--- a/spaghetti-monster/anduril/cfg-ff-rot66g2.h
+++ b/spaghetti-monster/anduril/cfg-ff-rot66g2.h
@@ -40,10 +40,10 @@
// higher floor than default, and stop at highest regulated level
#define RAMP_SMOOTH_FLOOR 1 // ~0.3 lm
-#define RAMP_SMOOTH_CEIL MAX_Nx7135 // ~1200 lm
+#define RAMP_SMOOTH_CEIL MAX_Nx7135 // ~1200 lm
// 10, 28, 46, [65], 83, 101, [120]
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL MAX_Nx7135
+#define RAMP_DISCRETE_CEIL MAX_Nx7135
#define RAMP_DISCRETE_STEPS 7
diff --git a/spaghetti-monster/anduril/cfg-fw3a-nofet.h b/spaghetti-monster/anduril/cfg-fw3a-nofet.h
index a6be10d..3c6f461 100644
--- a/spaghetti-monster/anduril/cfg-fw3a-nofet.h
+++ b/spaghetti-monster/anduril/cfg-fw3a-nofet.h
@@ -28,9 +28,9 @@
#undef RAMP_DISCRETE_STEPS
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 150
+#define RAMP_SMOOTH_CEIL 150
// 10, 33, 56, 80, 103, 126, 150
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h b/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h
index 28c77c2..6dce2eb 100644
--- a/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h
+++ b/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h
@@ -16,7 +16,7 @@
// don't blink during ramp, it's irrelevant and annoying on this light
-#define BLINK_AT_RAMP_CEILING
+#define BLINK_AT_RAMP_CEIL
#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_FLOOR
@@ -37,12 +37,12 @@
#define QUARTERSPEED_LEVEL 8
#define RAMP_SMOOTH_FLOOR 1 // ~0.3 lm
-#define RAMP_SMOOTH_CEIL 130 // ~??? lm
+#define RAMP_SMOOTH_CEIL 130 // ~??? lm
// 14/135/6 = 14, 38, 62, 86, [110], 135
// 20/110/7 = 20, 35, 50, [65], 80, 95, [110]
// 15/130/7 = 15, 34, 53, 72, 91, [110], 130 <--
#define RAMP_DISCRETE_FLOOR 15 // ~?? lm
-#define RAMP_DISCRETE_CEIL 130 // ~??? lm
+#define RAMP_DISCRETE_CEIL 130 // ~??? lm
#define RAMP_DISCRETE_STEPS 7 // ??, ??, ... lm
diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
index 0585b38..ea28900 100644
--- a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
+++ b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
@@ -15,7 +15,7 @@
// don't blink during ramp, it's irrelevant and annoying on this light
-#define BLINK_AT_RAMP_CEILING
+#define BLINK_AT_RAMP_CEIL
#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_FLOOR
@@ -33,10 +33,10 @@
#define QUARTERSPEED_LEVEL 6
#define RAMP_SMOOTH_FLOOR 1 // ~2.5 lm
-#define RAMP_SMOOTH_CEIL 120 // ~5400 lm
+#define RAMP_SMOOTH_CEIL 120 // ~5400 lm
// 20, 36, 53, [70], 86, 103, 120
#define RAMP_DISCRETE_FLOOR 20 // 35 lm
-#define RAMP_DISCRETE_CEIL 120 // ~5400 lm
+#define RAMP_DISCRETE_CEIL 120 // ~5400 lm
#define RAMP_DISCRETE_STEPS 7 // 35, 108, 280, 626, 1500, 2930, 5400 lm
#define USE_TENCLICK_THERMAL_CONFIG // by request
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1-12v.h b/spaghetti-monster/anduril/cfg-noctigon-k1-12v.h
index 617801f..c45fea6 100644
--- a/spaghetti-monster/anduril/cfg-noctigon-k1-12v.h
+++ b/spaghetti-monster/anduril/cfg-noctigon-k1-12v.h
@@ -37,14 +37,14 @@
#endif
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 130
+#define RAMP_SMOOTH_CEIL 130
// 10, 30, [50], 70, 90, 110, 130
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
-#define MUGGLE_CEILING 70
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 70
// make candle mode wobble more
#define CANDLE_AMPLITUDE 32
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h b/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h
index fd98979..a95c918 100644
--- a/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h
+++ b/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h
@@ -36,14 +36,14 @@
#define QUARTERSPEED_LEVEL 2
#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable
-#define RAMP_SMOOTH_CEIL 120
+#define RAMP_SMOOTH_CEIL 120
// 10, 28, [46], 65, 83, 101, [120]
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
-#define MUGGLE_CEILING 65
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 65
// stop panicking at ~25% power or ~1000 lm
#define THERM_FASTER_LEVEL 120
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1.h b/spaghetti-monster/anduril/cfg-noctigon-k1.h
index 4f2c2cc..d844961 100644
--- a/spaghetti-monster/anduril/cfg-noctigon-k1.h
+++ b/spaghetti-monster/anduril/cfg-noctigon-k1.h
@@ -38,14 +38,14 @@
#endif
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 130
+#define RAMP_SMOOTH_CEIL 130
// 10, 30, [50], 70, 90, 110, 130
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
-#define MUGGLE_CEILING 70
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 70
// make candle mode wobble more
#define CANDLE_AMPLITUDE 32
diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h
index 9f5f57f..9f7616b 100644
--- a/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h
+++ b/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h
@@ -27,16 +27,16 @@
#undef RAMP_DISCRETE_STEPS
#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable
-#define RAMP_SMOOTH_CEIL 130
+#define RAMP_SMOOTH_CEIL 130
// 10, 30, [50], 70, 90, 110, 130 (plus [150] on turbo)
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-#undef MUGGLE_FLOOR
-#undef MUGGLE_CEILING
-#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
-#define MUGGLE_CEILING 70
+#undef SIMPLE_UI_FLOOR
+#undef SIMPLE_UI_CEIL
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 70
// make candle mode wobble more
#define CANDLE_AMPLITUDE 32
diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4.h b/spaghetti-monster/anduril/cfg-noctigon-kr4.h
index ed15bde..3a56fa8 100644
--- a/spaghetti-monster/anduril/cfg-noctigon-kr4.h
+++ b/spaghetti-monster/anduril/cfg-noctigon-kr4.h
@@ -40,14 +40,14 @@
#define QUARTERSPEED_LEVEL 2
#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable
-#define RAMP_SMOOTH_CEIL 120
+#define RAMP_SMOOTH_CEIL 120
// 10, 28, [46], 65, 83, 101, [120]
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
-#define MUGGLE_CEILING 65
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL 65
// stop panicking at ~25% power or ~1000 lm
#define THERM_FASTER_LEVEL 100
diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp36.h b/spaghetti-monster/anduril/cfg-sofirn-sp36.h
index d808e2a..0bd5a5f 100644
--- a/spaghetti-monster/anduril/cfg-sofirn-sp36.h
+++ b/spaghetti-monster/anduril/cfg-sofirn-sp36.h
@@ -19,8 +19,8 @@
#ifdef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_MIDDLE
#endif
-#ifdef BLINK_AT_RAMP_CEILING
-#undef BLINK_AT_RAMP_CEILING
+#ifdef BLINK_AT_RAMP_CEIL
+#undef BLINK_AT_RAMP_CEIL
#endif
// stop panicking at ~60% power or ~3000 lm
diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c
index d362633..eacc699 100644
--- a/spaghetti-monster/fsm-pcint.c
+++ b/spaghetti-monster/fsm-pcint.c
@@ -93,18 +93,17 @@ ISR(PCINT0_vect) {
// should only be called from PCINT and/or WDT
// (is a separate function to reduce code duplication)
void PCINT_inner(uint8_t pressed) {
- uint8_t pushed;
+ button_last_state = pressed;
- if (pressed) {
- pushed = push_event(B_PRESS);
- } else {
- pushed = push_event(B_RELEASE);
- }
-
- // send event to the current state callback
- if (pushed) {
- button_last_state = pressed;
+ // register the change, and send event to the current state callback
+ if (pressed) { // user pressed button
+ push_event(B_PRESS);
emit_current_event(0);
+ } else { // user released button
+ // how long was the button held?
+ uint16_t ticks_since_last = ticks_since_last_event;
+ push_event(B_RELEASE);
+ emit_current_event(ticks_since_last);
}
}
#endif