aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/anduril/rampingiosv3.c685
-rw-r--r--spaghetti-monster/fsm-events.h74
2 files changed, 130 insertions, 629 deletions
diff --git a/spaghetti-monster/anduril/rampingiosv3.c b/spaghetti-monster/anduril/rampingiosv3.c
index ac49444..12550cc 100644
--- a/spaghetti-monster/anduril/rampingiosv3.c
+++ b/spaghetti-monster/anduril/rampingiosv3.c
@@ -54,44 +54,15 @@
//#define BATTCHECK_8bars // FIXME: breaks build
//#define BATTCHECK_4bars // FIXME: breaks build
-// enable/disable various modes
-//#define USE_LIGHTNING_MODE
-//#define USE_CANDLE_MODE
-//#define USE_GOODNIGHT_MODE
-//#define USE_MUGGLE_MODE
-
-#ifdef USE_GOODNIGHT_MODE
-#define GOODNIGHT_TIME 60 // minutes (approximately)
-#define GOODNIGHT_LEVEL 24 // ~11 lm
-#endif
-
-// dual-switch support (second switch is a tail clicky)
-//#define START_AT_MEMORIZED_LEVEL
-
/********* Configure SpaghettiMonster *********/
#define USE_DELAY_ZERO
#define USE_RAMPING
#define RAMP_LENGTH 150
-#define MAX_BIKING_LEVEL 120 // should be 127 or less
#define USE_BATTCHECK
-#ifdef USE_MUGGLE_MODE
-#define MAX_CLICKS 6
-#define MUGGLE_FLOOR 22
-#define MUGGLE_CEILING (MAX_1x7135+20)
-#else
-#define MAX_CLICKS 5
-#endif
+#define MAX_CLICKS 14
#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending
#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency
-// full FET strobe can be a bit much... use max regulated level instead,
-// if there's a bright enough regulated level
-#ifdef MAX_Nx7135
-#define STROBE_BRIGHTNESS MAX_Nx7135
-#else
-#define STROBE_BRIGHTNESS MAX_LEVEL
-#endif
-
// specific settings for known driver types
#if defined(FSM_BLF_GT_DRIVER)
#include "cfg-blf-gt.h"
@@ -120,28 +91,7 @@
#else
#define EEPROM_BYTES 12
#endif
-#ifdef START_AT_MEMORIZED_LEVEL
-#define USE_EEPROM_WL
-#define EEPROM_WL_BYTES 1
-#endif
-// auto-configure other stuff...
-#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
-#define USE_PSEUDO_RAND
-#endif
-// count the strobe modes (seems like there should be an easier way to do this)
-#define NUM_STROBES_BASE 3
-#ifdef USE_LIGHTNING_MODE
-#define ADD_LIGHTNING_STROBE 1
-#else
-#define ADD_LIGHTNING_STROBE 0
-#endif
-#ifdef USE_CANDLE_MODE
-#define ADD_CANDLE_MODE 1
-#else
-#define ADD_CANDLE_MODE 0
-#endif
-#define NUM_STROBES (NUM_STROBES_BASE+ADD_LIGHTNING_STROBE+ADD_CANDLE_MODE)
#include "spaghetti-monster.h"
@@ -157,8 +107,6 @@ uint8_t config_state_values[MAX_CONFIG_VALUES];
// ramping mode and its related config mode
uint8_t steady_state(EventPtr event, uint16_t arg);
uint8_t ramp_config_state(EventPtr event, uint16_t arg);
-// party and tactical strobes
-uint8_t strobe_state(EventPtr event, uint16_t arg);
#ifdef USE_BATTCHECK
uint8_t battcheck_state(EventPtr event, uint16_t arg);
#endif
@@ -166,10 +114,6 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg);
uint8_t tempcheck_state(EventPtr event, uint16_t arg);
uint8_t thermal_config_state(EventPtr event, uint16_t arg);
#endif
-#ifdef USE_GOODNIGHT_MODE
-// 1-hour ramp down from low, then automatic off
-uint8_t goodnight_state(EventPtr event, uint16_t arg);
-#endif
// beacon mode and its related config mode
uint8_t beacon_state(EventPtr event, uint16_t arg);
uint8_t beacon_config_state(EventPtr event, uint16_t arg);
@@ -178,11 +122,6 @@ uint8_t beacon_config_state(EventPtr event, uint16_t arg);
uint8_t lockout_state(EventPtr event, uint16_t arg);
// momentary / signalling mode
uint8_t momentary_state(EventPtr event, uint16_t arg);
-#ifdef USE_MUGGLE_MODE
-// muggle mode, super-simple, hard to exit
-uint8_t muggle_state(EventPtr event, uint16_t arg);
-uint8_t muggle_mode_active = 0;
-#endif
// general helper function for config modes
uint8_t number_entry_state(EventPtr event, uint16_t arg);
@@ -193,13 +132,13 @@ void blink_confirm(uint8_t num);
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
void indicator_blink(uint8_t arg);
#endif
+#ifdef USE_INDICATOR_LED
+uint8_t auxled_next_state(EventPtr event, uint16_t arg);
+#endif
// remember stuff even after battery was changed
void load_config();
void save_config();
-#ifdef START_AT_MEMORIZED_LEVEL
-void save_config_wl();
-#endif
// default ramp options if not overridden earlier per-driver
#ifndef RAMP_SMOOTH_FLOOR
@@ -255,22 +194,6 @@ uint8_t nearest_level(int16_t target);
uint8_t target_level = 0;
#endif
-// strobe timing
-volatile uint8_t strobe_delays[] = { 40, 67 }; // party strobe, tactical strobe
-// 0 == bike flasher
-// 1 == party strobe
-// 2 == tactical strobe
-// 3 == lightning storm
-// 4 == candle mode
-volatile uint8_t strobe_type = 4;
-
-// bike mode config options
-volatile uint8_t bike_flasher_brightness = MAX_1x7135;
-
-#ifdef USE_CANDLE_MODE
-uint8_t triangle_wave(uint8_t phase);
-#endif
-
// beacon timing
volatile uint8_t beacon_seconds = 2;
@@ -356,31 +279,33 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- // click, click, long-click: strobe mode
- else if (event == EV_click3_hold) {
- set_state(strobe_state, 0);
+ // 4 clicks: momentary
+ else if (event == EV_4clicks) {
+ blink_confirm(1);
+ set_state(momentary_state, 0);
return MISCHIEF_MANAGED;
}
- // 4 clicks: soft lockout
- else if (event == EV_4clicks) {
+ // 6 clicks: lockout mode
+ else if (event == EV_6clicks) {
blink_confirm(2);
set_state(lockout_state, 0);
return MISCHIEF_MANAGED;
}
- // 5 clicks: momentary mode
- else if (event == EV_5clicks) {
- blink_confirm(1);
- set_state(momentary_state, 0);
+ // 8 clicks: beacon mode
+ else if (event == EV_8clicks) {
+ set_state(beacon_state, 0);
return MISCHIEF_MANAGED;
}
- #ifdef USE_MUGGLE_MODE
- // 6 clicks: muggle mode
- else if (event == EV_6clicks) {
- blink_confirm(1);
- set_state(muggle_state, 0);
+ // 10 clicks: thermal config mode
+ else if (event == EV_10clicks) {
+ set_state(thermal_config_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 14 clicks: next aux LED mode
+ else if (event == EV_14clicks) {
+ set_state(auxled_next_state, 0);
return MISCHIEF_MANAGED;
}
- #endif
return EVENT_NOT_HANDLED;
}
@@ -450,9 +375,6 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
#endif
#endif
save_config();
- #ifdef START_AT_MEMORIZED_LEVEL
- save_config_wl();
- #endif
set_level(0);
delay_4ms(20/4);
set_level(memorized_level);
@@ -521,15 +443,12 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
set_level(memorized_level);
return MISCHIEF_MANAGED;
}
- #if defined(USE_REVERSING) || defined(START_AT_MEMORIZED_LEVEL)
+ #if defined(USE_REVERSING)
// reverse ramp direction on hold release
else if (event == EV_click1_hold_release) {
#ifdef USE_REVERSING
ramp_direction = -ramp_direction;
#endif
- #ifdef START_AT_MEMORIZED_LEVEL
- save_config_wl();
- #endif
return MISCHIEF_MANAGED;
}
#endif
@@ -583,13 +502,6 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
set_level(memorized_level);
return MISCHIEF_MANAGED;
}
- #ifdef START_AT_MEMORIZED_LEVEL
- // click, release, hold, release: save new ramp level (if necessary)
- else if (event == EV_click2_hold_release) {
- save_config_wl();
- return MISCHIEF_MANAGED;
- }
- #endif
#if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING)
else if (event == EV_tick) {
#ifdef USE_REVERSING
@@ -598,7 +510,10 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
#endif
#ifdef USE_SET_LEVEL_GRADUALLY
// make thermal adjustment speed scale with magnitude
- if (arg & 1) return MISCHIEF_MANAGED; // adjust slower
+ // if we're on a really high mode, drop faster
+ if ((arg & 1) && (actual_level < THERM_DOUBLE_SPEED_LEVEL)) {
+ return MISCHIEF_MANAGED; // adjust slower when not a high mode
+ }
// [int(62*4 / (x**0.8)) for x in (1,2,4,8,16,32,64,128)]
//uint8_t intervals[] = {248, 142, 81, 46, 26, 15, 8, 5};
// [int(62*4 / (x**0.9)) for x in (1,2,4,8,16,32,64,128)]
@@ -611,10 +526,6 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
if (target_level > actual_level) diff = target_level - actual_level;
else {
diff = actual_level - target_level;
- // if we're on a really high mode, drop faster
- if (actual_level >= THERM_DOUBLE_SPEED_LEVEL) {
- diff <<= 1;
- }
}
uint8_t magnitude = 0;
while (diff) {
@@ -680,190 +591,6 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
}
-uint8_t strobe_state(EventPtr event, uint16_t arg) {
- // 'st' reduces ROM size by avoiding access to a volatile var
- // (maybe I should just make it nonvolatile?)
- uint8_t st = strobe_type;
- #ifdef USE_CANDLE_MODE
- // FIXME: make candle variance magnitude a compile-time option,
- // since 20 is sometimes too much or too little,
- // depending on the driver type and ramp shape
- //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4)
- #define MAX_CANDLE_LEVEL (RAMP_SIZE/2)
- static uint8_t candle_wave1 = 0;
- static uint8_t candle_wave2 = 0;
- static uint8_t candle_wave3 = 0;
- static uint8_t candle_wave2_speed = 0;
- static uint8_t candle_wave2_depth = 7;
- static uint8_t candle_wave3_depth = 4;
- static uint8_t candle_mode_brightness = 24;
- static uint8_t candle_mode_timer = 0;
- #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds
- #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish
- #endif
-
- if (event == EV_enter_state) {
- #ifdef USE_CANDLE_MODE
- candle_mode_timer = 0; // in case any time was left over from earlier
- #endif
- return MISCHIEF_MANAGED;
- }
- // 1 click: off
- else if (event == EV_1click) {
- set_state(off_state, 0);
- return MISCHIEF_MANAGED;
- }
- // 2 clicks: rotate through strobe/flasher modes
- else if (event == EV_2clicks) {
- strobe_type = (st + 1) % NUM_STROBES;
- #ifdef USE_CANDLE_MODE
- candle_mode_timer = 0; // in case any time was left over from earlier
- #endif
- interrupt_nice_delays();
- save_config();
- return MISCHIEF_MANAGED;
- }
- // hold: change speed (go faster)
- // or change brightness (brighter)
- else if (event == EV_click1_hold) {
- // biking mode brighter
- if (st == 0) {
- if (bike_flasher_brightness < MAX_BIKING_LEVEL)
- bike_flasher_brightness ++;
- set_level(bike_flasher_brightness);
- }
- // strobe faster
- else if (st < 3) {
- if ((arg & 1) == 0) {
- if (strobe_delays[st-1] > 8) strobe_delays[st-1] --;
- }
- }
- // lightning has no adjustments
- // else if (st == 3) {}
- #ifdef USE_CANDLE_MODE
- // candle mode brighter
- else if (st == 4) {
- if (candle_mode_brightness < MAX_CANDLE_LEVEL)
- candle_mode_brightness ++;
- }
- #endif
- return MISCHIEF_MANAGED;
- }
- // click, hold: change speed (go slower)
- // or change brightness (dimmer)
- else if (event == EV_click2_hold) {
- // biking mode dimmer
- if (st == 0) {
- if (bike_flasher_brightness > 2)
- bike_flasher_brightness --;
- set_level(bike_flasher_brightness);
- }
- // strobe slower
- else if (st < 3) {
- if ((arg & 1) == 0) {
- if (strobe_delays[st-1] < 255) strobe_delays[st-1] ++;
- }
- }
- // lightning has no adjustments
- // else if (st == 3) {}
- #ifdef USE_CANDLE_MODE
- // candle mode dimmer
- else if (st == 4) {
- if (candle_mode_brightness > 1)
- candle_mode_brightness --;
- }
- #endif
- return MISCHIEF_MANAGED;
- }
- // release hold: save new strobe settings
- else if ((event == EV_click1_hold_release)
- || (event == EV_click2_hold_release)) {
- save_config();
- return MISCHIEF_MANAGED;
- }
- #if defined(USE_CANDLE_MODE)
- // 3 clicks: add 30m to candle timer
- else if (event == EV_3clicks) {
- // candle mode only
- if (st == 4) {
- if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) {
- // add 30m to the timer
- candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR;
- // blink to confirm
- set_level(actual_level + 32);
- delay_4ms(2);
- }
- }
- return MISCHIEF_MANAGED;
- }
- #endif
- #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
- // clock tick: bump the random seed
- else if (event == EV_tick) {
- #ifdef USE_LIGHTNING_MODE
- pseudo_rand_seed += arg;
- #endif
- #ifdef USE_CANDLE_MODE
- if (st == 4) {
- // self-timer dims the light during the final minute
- uint8_t subtract = 0;
- if (candle_mode_timer == 1) {
- subtract = ((candle_mode_brightness+20)
- * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4))
- >> 8;
- }
- // we passed a minute mark, decrease timer if it's running
- if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) {
- if (candle_mode_timer > 0) {
- candle_mode_timer --;
- //set_level(0); delay_4ms(2);
- // if the timer ran out, shut off
- if (! candle_mode_timer) {
- set_state(off_state, 0);
- }
- }
- }
- // 3-oscillator synth for a relatively organic pattern
- uint8_t add;
- add = ((triangle_wave(candle_wave1) * 8) >> 8)
- + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8)
- + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8);
- int8_t brightness = candle_mode_brightness + add - subtract;
- if (brightness < 0) { brightness = 0; }
- set_level(brightness);
-
- // wave1: slow random LFO
- if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1;
- // wave2: medium-speed erratic LFO
- candle_wave2 += candle_wave2_speed;
- // wave3: erratic fast wave
- candle_wave3 += pseudo_rand() % 37;
- // S&H on wave2 frequency to make it more erratic
- if ((pseudo_rand() & 0b00111111) == 0)
- candle_wave2_speed = pseudo_rand() % 13;
- // downward sawtooth on wave2 depth to simulate stabilizing
- if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0))
- candle_wave2_depth --;
- // random sawtooth retrigger
- if ((pseudo_rand()) == 0) {
- candle_wave2_depth = 7;
- //candle_wave3_depth = 5;
- candle_wave2 = 0;
- }
- // downward sawtooth on wave3 depth to simulate stabilizing
- if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0))
- candle_wave3_depth --;
- if ((pseudo_rand() & 0b01111111) == 0)
- candle_wave3_depth = 5;
- }
- #endif
- return MISCHIEF_MANAGED;
- }
- #endif
- return EVENT_NOT_HANDLED;
-}
-
-
#ifdef USE_BATTCHECK
uint8_t battcheck_state(EventPtr event, uint16_t arg) {
// 1 click: off
@@ -880,6 +607,7 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg) {
}
#endif
+
#ifdef USE_THERMAL_REGULATION
uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
// 1 click: off
@@ -903,6 +631,8 @@ uint8_t beacon_state(EventPtr event, uint16_t arg) {
set_state(off_state, 0);
return MISCHIEF_MANAGED;
}
+ // TODO: use sleep ticks to measure time between pulses,
+ // to save power
// 4 clicks: beacon config mode
else if (event == EV_4clicks) {
push_state(beacon_config_state, 0);
@@ -912,48 +642,6 @@ uint8_t beacon_state(EventPtr event, uint16_t arg) {
}
-#ifdef USE_GOODNIGHT_MODE
-#define GOODNIGHT_TICKS_PER_STEPDOWN (GOODNIGHT_TIME*TICKS_PER_SECOND*60L/GOODNIGHT_LEVEL)
-uint8_t goodnight_state(EventPtr event, uint16_t arg) {
- static uint16_t ticks_since_stepdown = 0;
- // blink on start
- if (event == EV_enter_state) {
- ticks_since_stepdown = 0;
- blink_confirm(2);
- set_level(GOODNIGHT_LEVEL);
- return MISCHIEF_MANAGED;
- }
- // 1 click: off
- else if (event == EV_1click) {
- set_state(off_state, 0);
- return MISCHIEF_MANAGED;
- }
- // 2 clicks: beacon mode
- else if (event == EV_2clicks) {
- set_state(beacon_state, 0);
- return MISCHIEF_MANAGED;
- }
- // tick: step down (maybe) or off (maybe)
- else if (event == EV_tick) {
- if (++ticks_since_stepdown > GOODNIGHT_TICKS_PER_STEPDOWN) {
- ticks_since_stepdown = 0;
- set_level(actual_level-1);
- if (! actual_level) {
- #if 0 // test blink, to help measure timing
- set_level(MAX_LEVEL>>2);
- delay_4ms(8/2);
- set_level(0);
- #endif
- set_state(off_state, 0);
- }
- }
- return MISCHIEF_MANAGED;
- }
- return EVENT_NOT_HANDLED;
-}
-#endif
-
-
uint8_t lockout_state(EventPtr event, uint16_t arg) {
#ifdef MOON_DURING_LOCKOUT_MODE
// momentary(ish) moon mode during lockout
@@ -1064,6 +752,30 @@ uint8_t lockout_state(EventPtr event, uint16_t arg) {
}
+#ifdef USE_INDICATOR_LED
+uint8_t auxled_next_state(EventPtr event, uint16_t arg) {
+ if (event == EV_enter_state) {
+ uint8_t mode = indicator_led_mode & 3;
+ #ifdef TICK_DURING_STANDBY
+ mode = (mode + 1) & 3;
+ #else
+ mode = (mode + 1) % 3;
+ #endif
+ indicator_led_mode = mode + (indicator_led_mode & 0b00001100);
+ indicator_led(mode);
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ else {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+
+ return EVENT_NOT_HANDLED;
+}
+#endif
+
+
uint8_t momentary_state(EventPtr event, uint16_t arg) {
// TODO: momentary strobe here? (for light painting)
if (event == EV_click1_press) {
@@ -1096,144 +808,6 @@ uint8_t momentary_state(EventPtr event, uint16_t arg) {
}
-#ifdef USE_MUGGLE_MODE
-uint8_t muggle_state(EventPtr 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
- go_to_standby = 1; // sleep while light is off
- }
- }
- return MISCHIEF_MANAGED;
- }
- // 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;
- }
-
- return EVENT_NOT_HANDLED;
-}
-#endif
-
-
// ask the user for a sequence of numbers, then save them and return to caller
uint8_t config_state_base(EventPtr event, uint16_t arg,
uint8_t num_config_steps,
@@ -1483,15 +1057,6 @@ void indicator_blink(uint8_t arg) {
#endif
-#ifdef USE_CANDLE_MODE
-uint8_t triangle_wave(uint8_t phase) {
- uint8_t result = phase << 1;
- if (phase > 127) result = 255 - result;
- return result;
-}
-#endif
-
-
void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[0];
@@ -1500,14 +1065,7 @@ void load_config() {
ramp_discrete_floor = eeprom[3];
ramp_discrete_ceil = eeprom[4];
ramp_discrete_steps = eeprom[5];
- strobe_type = eeprom[6]; // TODO: move this to eeprom_wl?
- strobe_delays[0] = eeprom[7];
- strobe_delays[1] = eeprom[8];
- bike_flasher_brightness = eeprom[9];
beacon_seconds = eeprom[10];
- #ifdef USE_MUGGLE_MODE
- muggle_mode_active = eeprom[11];
- #endif
#ifdef USE_THERMAL_REGULATION
therm_ceil = eeprom[12];
therm_cal_offset = eeprom[13];
@@ -1516,11 +1074,6 @@ void load_config() {
indicator_led_mode = eeprom[14];
#endif
}
- #ifdef START_AT_MEMORIZED_LEVEL
- if (load_eeprom_wl()) {
- memorized_level = eeprom_wl[0];
- }
- #endif
}
void save_config() {
@@ -1530,14 +1083,7 @@ void save_config() {
eeprom[3] = ramp_discrete_floor;
eeprom[4] = ramp_discrete_ceil;
eeprom[5] = ramp_discrete_steps;
- eeprom[6] = strobe_type; // TODO: move this to eeprom_wl?
- eeprom[7] = strobe_delays[0];
- eeprom[8] = strobe_delays[1];
- eeprom[9] = bike_flasher_brightness;
eeprom[10] = beacon_seconds;
- #ifdef USE_MUGGLE_MODE
- eeprom[11] = muggle_mode_active;
- #endif
#ifdef USE_THERMAL_REGULATION
eeprom[12] = therm_ceil;
eeprom[13] = therm_cal_offset;
@@ -1549,23 +1095,11 @@ void save_config() {
save_eeprom();
}
-#ifdef START_AT_MEMORIZED_LEVEL
-void save_config_wl() {
- eeprom_wl[0] = memorized_level;
- save_eeprom_wl();
-}
-#endif
-
void low_voltage() {
StatePtr state = current_state;
- // "step down" from strobe to something low
- if (state == strobe_state) {
- set_state(steady_state, RAMP_SIZE/6);
- }
- // in normal or muggle mode, step down or turn off
- //else if ((state == steady_state) || (state == muggle_state)) {
- else if (state == steady_state) {
+ // in normal mode, step down or turn off
+ if (state == steady_state) {
if (actual_level > 1) {
uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
set_level(lvl);
@@ -1589,25 +1123,6 @@ void low_voltage() {
void setup() {
- #ifdef START_AT_MEMORIZED_LEVEL
- // dual switch: e-switch + power clicky
- // 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);
- else
- // otherwise use memory
- push_state(steady_state, memorized_level);
-
- #else // if not START_AT_MEMORIZED_LEVEL
-
// blink at power-on to let user know power is connected
set_level(RAMP_SIZE/8);
delay_4ms(3);
@@ -1615,14 +1130,7 @@ void setup() {
load_config();
- #ifdef USE_MUGGLE_MODE
- if (muggle_mode_active)
- push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2);
- else
- #endif
- push_state(off_state, 0);
- #endif
-
+ push_state(off_state, 0);
}
@@ -1639,93 +1147,12 @@ void loop() {
else if ( (state == steady_state)
|| (state == off_state)
|| (state == lockout_state)
- #ifdef USE_GOODNIGHT_MODE
- || (state == goodnight_state)
- #endif
) {
// doze until next clock tick
idle_mode();
}
#endif
- if (state == strobe_state) {
- uint8_t st = strobe_type;
- // bike flasher
- if (st == 0) {
- uint8_t burst = bike_flasher_brightness << 1;
- if (burst > MAX_LEVEL) burst = MAX_LEVEL;
- for(uint8_t i=0; i<4; i++) {
- set_level(burst);
- if (! nice_delay_ms(5)) return;
- set_level(bike_flasher_brightness);
- if (! nice_delay_ms(65)) return;
- }
- nice_delay_ms(720); // no return check necessary on final delay
- }
- // party / tactical strobe
- else if (st < 3) {
- uint8_t del = strobe_delays[st-1];
- // TODO: make tac strobe brightness configurable?
- set_level(STROBE_BRIGHTNESS);
- CLKPR = 1<<CLKPCE; CLKPR = 0; // run at full speed
- if (st == 1) { // party strobe
- if (del < 42) delay_zero();
- else nice_delay_ms(1);
- } else { //tactical strobe
- nice_delay_ms(del >> 1);
- }
- set_level(0);
- nice_delay_ms(del); // no return check necessary on final delay
- }
- #ifdef USE_LIGHTNING_MODE
- // lightning storm
- else if (st == 3) {
- int16_t brightness;
- uint16_t rand_time;
-
- // turn the emitter on at a random level,
- // for a random amount of time between 1ms and 32ms
- //rand_time = 1 << (pseudo_rand() % 7);
- rand_time = pseudo_rand() & 63;
- brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
- brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
- brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
- if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
- set_level(brightness);
- if (! nice_delay_ms(rand_time)) return;
-
- // decrease the brightness somewhat more gradually, like lightning
- uint8_t stepdown = brightness >> 3;
- if (stepdown < 1) stepdown = 1;
- while(brightness > 1) {
- if (! nice_delay_ms(rand_time)) return;
- brightness -= stepdown;
- if (brightness < 0) brightness = 0;
- set_level(brightness);
- /*
- if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) {
- brightness <<= 1;
- set_level(brightness);
- }
- */
- if (! (pseudo_rand() & 3)) {
- if (! nice_delay_ms(rand_time)) return;
- set_level(brightness>>1);
- }
- }
-
- // turn the emitter off,
- // for a random amount of time between 1ms and 8192ms
- // (with a low bias)
- rand_time = 1 << (pseudo_rand() % 13);
- rand_time += pseudo_rand() % rand_time;
- set_level(0);
- nice_delay_ms(rand_time); // no return check necessary on final delay
-
- }
- #endif
- }
-
#ifdef USE_BATTCHECK
else if (state == battcheck_state) {
battcheck();
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h
index 4a67347..0212c2c 100644
--- a/spaghetti-monster/fsm-events.h
+++ b/spaghetti-monster/fsm-events.h
@@ -68,6 +68,7 @@ static volatile uint16_t ticks_since_last_event = 0;
#define A_DEBUG 255 // test event for debugging
// Event types
+// TODO: make these progmem-only?
Event EV_debug[] = {
A_DEBUG,
0 } ;
@@ -407,9 +408,76 @@ Event EV_click12_complete[] = {
A_RELEASE_TIMEOUT,
0 };
#endif
+#if MAX_CLICKS >= 13
+#define EV_13clicks EV_click13_complete
+Event EV_click13_complete[] = {
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_RELEASE_TIMEOUT,
+ 0 };
+#endif
+#if MAX_CLICKS >= 14
+#define EV_14clicks EV_click14_complete
+Event EV_click14_complete[] = {
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_RELEASE,
+ A_RELEASE_TIMEOUT,
+ 0 };
+#endif
// ... and so on
// A list of button event types for easy iteration
+// TODO: make this progmem-only?
EventPtr event_sequences[] = {
EV_click1_press,
EV_release,
@@ -458,6 +526,12 @@ EventPtr event_sequences[] = {
#if MAX_CLICKS >= 12
EV_click12_complete,
#endif
+ #if MAX_CLICKS >= 13
+ EV_click13_complete,
+ #endif
+ #if MAX_CLICKS >= 14
+ EV_click14_complete,
+ #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.