diff options
Diffstat (limited to 'spaghetti-monster/darkhorse.c')
| -rw-r--r-- | spaghetti-monster/darkhorse.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/spaghetti-monster/darkhorse.c b/spaghetti-monster/darkhorse.c index 6a17943..a7937e6 100644 --- a/spaghetti-monster/darkhorse.c +++ b/spaghetti-monster/darkhorse.c @@ -26,6 +26,7 @@ #define RAMP_LENGTH 150 #define USE_BATTCHECK #define BATTCHECK_4bars +#define DONT_DELAY_AFTER_BATTCHECK #include "spaghetti-monster.h" // FSM states @@ -59,6 +60,9 @@ uint8_t hi_modes[] = {MAX_LEVEL, 81, 96, 113}; // 1500 lm, 678 lm, 430 lm, 270 // 3: 19 Hz strobe at H1 uint8_t strobe_beacon_mode = 0; +// deferred "off" so we won't suspend in a weird state +volatile uint8_t go_to_standby = 0; + #ifdef USE_THERMAL_REGULATION // brightness before thermal step-down uint8_t target_level = 0; @@ -87,9 +91,8 @@ uint8_t off_state(EventPtr event, uint16_t arg) { // turn emitter off when entering state if (event == EV_enter_state) { set_level(0); - empty_event_sequence(); // sleep while off (lower power use) - standby_mode(); + go_to_standby = 1; return EVENT_HANDLED; } // hold (initially): go to lowest level, but allow abort for regular click @@ -107,7 +110,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) { set_state(hi_mode_state, 0); return EVENT_HANDLED; } - // click, hold (initially): go to medium mode, but allow abort + // click, press (initially): go to medium mode, but allow abort else if (event == EV_click2_press) { set_med_mode(); return EVENT_HANDLED; @@ -117,7 +120,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) { set_state(med_mode_state, 0); return EVENT_HANDLED; } - // click, click, hold (initially): light off, prep for blinkies + // click, click, press (initially): light off, prep for blinkies else if (event == EV_click3_press) { set_level(0); return EVENT_HANDLED; @@ -249,14 +252,12 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg) { uint8_t strobe_beacon_state(EventPtr event, uint16_t arg) { // 1 click: off if (event == EV_1click) { - interrupt_nice_delays(); set_state(off_state, 0); return MISCHIEF_MANAGED; } // 1 click (initially): cancel current blink if (event == EV_click1_release) { - // only cancel if the light is actually on - if (actual_level) interrupt_nice_delays(); + interrupt_nice_delays(); return MISCHIEF_MANAGED; } // 2 clicks: rotate through blinky modes @@ -285,6 +286,13 @@ void low_voltage() { } } +void strobe(uint8_t level, uint16_t ontime, uint16_t offtime) { + set_level(level); + if (! nice_delay_ms(ontime)) return; + set_level(0); + nice_delay_ms(offtime); +} + void setup() { set_level(RAMP_SIZE/8); delay_4ms(3); @@ -294,43 +302,39 @@ void setup() { } void loop() { + // deferred "off" so we won't suspend in a weird state + // (like... during the middle of a strobe pulse) + if (go_to_standby) { + go_to_standby = 0; + set_level(0); + standby_mode(); + } + if (current_state == strobe_beacon_state) { switch(strobe_beacon_mode) { // 0.2 Hz beacon at L1 case 0: - set_level(low_modes[0]); - nice_delay_ms(500); - set_level(0); - nice_delay_ms(4500); + strobe(low_modes[0], 500, 4500); break; // 0.2 Hz beacon at H1 case 1: - set_level(hi_modes[0]); - nice_delay_ms(500); - set_level(0); - nice_delay_ms(4500); + strobe(hi_modes[0], 500, 4500); break; // 4 Hz tactical strobe at H1 case 2: - set_level(hi_modes[0]); - nice_delay_ms(83); - set_level(0); - nice_delay_ms(167); + strobe(hi_modes[0], 83, 167); break; // 19 Hz tactical strobe at H1 case 3: - set_level(hi_modes[0]); - nice_delay_ms(17); - set_level(0); - nice_delay_ms(35); + strobe(hi_modes[0], 17, 35); break; } } + #ifdef USE_BATTCHECK else if (current_state == battcheck_state) { nice_delay_ms(500); // wait a moment to measure voltage battcheck(); - empty_event_sequence(); set_state(off_state, 0); } #endif |
