aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2018-06-26 19:49:12 -0600
committerSelene ToyKeeper2018-06-26 19:49:12 -0600
commita59a93326bffc24725f44499415e96c16ea6b541 (patch)
tree8a77f4b9783bf8baf862773fef2f5a8754e23962 /spaghetti-monster
parentStarted removing features to match Emisar UI. (diff)
downloadanduril-a59a93326bffc24725f44499415e96c16ea6b541.tar.gz
anduril-a59a93326bffc24725f44499415e96c16ea6b541.tar.bz2
anduril-a59a93326bffc24725f44499415e96c16ea6b541.zip
Mostly got Emisar UI working... I think. Not yet tested.
Diffstat (limited to 'spaghetti-monster')
-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
// ...
};