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
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.