From a59a93326bffc24725f44499415e96c16ea6b541 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 26 Jun 2018 19:49:12 -0600 Subject: Mostly got Emisar UI working... I think. Not yet tested. --- spaghetti-monster/anduril/rampingiosv3.c | 685 +++---------------------------- spaghetti-monster/fsm-events.h | 74 ++++ 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<> 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 // ... }; -- cgit v1.2.3