aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster/darkhorse.c
diff options
context:
space:
mode:
authorSelene ToyKeeper2017-08-26 13:52:52 -0600
committerSelene ToyKeeper2017-08-26 13:52:52 -0600
commitd32ae87d50e92cb59fdc28cf58622b32aede2f3e (patch)
tree0f0596ba7af37004bf1156d2b74e449990cfc89f /spaghetti-monster/darkhorse.c
parentFixed bug: strobes could interfere with hold-from-off next time light was used. (diff)
downloadanduril-d32ae87d50e92cb59fdc28cf58622b32aede2f3e.tar.gz
anduril-d32ae87d50e92cb59fdc28cf58622b32aede2f3e.tar.bz2
anduril-d32ae87d50e92cb59fdc28cf58622b32aede2f3e.zip
Avoid suspending at weird times by deferring the call to standby mode.
Turned strobe into a function to avoid repeating code, and made it tolerate interruption better. Got rid of delay after battcheck, since it caused problems if the user didn't wait long enough before trying to turn the light back on.
Diffstat (limited to '')
-rw-r--r--spaghetti-monster/darkhorse.c52
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