aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2017-08-24 16:21:45 -0600
committerSelene ToyKeeper2017-08-24 16:21:45 -0600
commit32eaeddee34c76dda5456ed960be6278ed68e48d (patch)
tree44cbbcfb3e1b47c777eacd1a707bba653bb4b49e /spaghetti-monster
parentFixed repeating blinks at ends of ramp -- only blinks once now. (diff)
downloadanduril-32eaeddee34c76dda5456ed960be6278ed68e48d.tar.gz
anduril-32eaeddee34c76dda5456ed960be6278ed68e48d.tar.bz2
anduril-32eaeddee34c76dda5456ed960be6278ed68e48d.zip
Added loop() to API, executes constantly.
Added nice_delay_ms() to process events while waiting, and abort on state change. Converted ramping-ui strobe to smoothly variable with party and tactical modes.
Diffstat (limited to '')
-rw-r--r--spaghetti-monster/baton.c2
-rw-r--r--spaghetti-monster/fsm-events.c23
-rw-r--r--spaghetti-monster/fsm-events.h3
-rw-r--r--spaghetti-monster/fsm-main.c7
-rw-r--r--spaghetti-monster/momentary.c3
-rw-r--r--spaghetti-monster/ramping-ui.c77
-rw-r--r--spaghetti-monster/spaghetti-monster.h4
7 files changed, 84 insertions, 35 deletions
diff --git a/spaghetti-monster/baton.c b/spaghetti-monster/baton.c
index 6b694e4..2489f4e 100644
--- a/spaghetti-monster/baton.c
+++ b/spaghetti-monster/baton.c
@@ -226,3 +226,5 @@ void setup() {
push_state(off_state, 0);
}
+
+void loop() { }
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index 6dda236..4831df6 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -99,6 +99,29 @@ void delete_first_emission() {
emissions[i].arg = 0;
}
+void process_emissions() {
+ while (emissions[0].event != NULL) {
+ emit_now(emissions[0].event, emissions[0].arg);
+ delete_first_emission();
+ }
+}
+
+// like delay_ms, except it aborts on state change
+// return value:
+// 0: state changed
+// 1: normal completion
+uint8_t nice_delay_ms(uint16_t ms) {
+ StatePtr old_state = current_state;
+ while(ms-- > 0) {
+ _delay_loop_2(BOGOMIPS*98/100);
+ process_emissions();
+ if (old_state != current_state) {
+ return 0; // state changed; abort
+ }
+ }
+ return 1;
+}
+
// Call stacked callbacks for the given event until one handles it.
uint8_t emit_now(EventPtr event, uint16_t arg) {
for(int8_t i=state_stack_len-1; i>=0; i--) {
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h
index 246a4ee..a14d7aa 100644
--- a/spaghetti-monster/fsm-events.h
+++ b/spaghetti-monster/fsm-events.h
@@ -209,9 +209,12 @@ volatile Emission emissions[EMISSION_QUEUE_LEN];
void append_emission(EventPtr event, uint16_t arg);
void delete_first_emission();
+void process_emissions();
//#define emit_now emit
uint8_t emit_now(EventPtr event, uint16_t arg);
void emit(EventPtr event, uint16_t arg);
void emit_current_event(uint16_t arg);
+uint8_t nice_delay_ms(uint16_t ms);
+
#endif
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index 2faaeda..1a0c425 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -97,10 +97,9 @@ int main() {
// TODO: check voltage?
// TODO: check temperature?
// if event queue not empty, process and pop first item in queue?
- if (emissions[0].event != NULL) {
- emit_now(emissions[0].event, emissions[0].arg);
- delete_first_emission();
- }
+ process_emissions();
+
+ loop();
}
}
diff --git a/spaghetti-monster/momentary.c b/spaghetti-monster/momentary.c
index 23cc359..fc26db3 100644
--- a/spaghetti-monster/momentary.c
+++ b/spaghetti-monster/momentary.c
@@ -75,3 +75,6 @@ void setup() {
debug_blink(2);
push_state(momentary_state, 0);
}
+
+void loop() { }
+
diff --git a/spaghetti-monster/ramping-ui.c b/spaghetti-monster/ramping-ui.c
index 6eeb3b0..256c4cf 100644
--- a/spaghetti-monster/ramping-ui.c
+++ b/spaghetti-monster/ramping-ui.c
@@ -31,7 +31,7 @@
// FSM states
uint8_t off_state(EventPtr event, uint16_t arg);
uint8_t steady_state(EventPtr event, uint16_t arg);
-uint8_t party_strobe_state(EventPtr event, uint16_t arg);
+uint8_t strobe_state(EventPtr event, uint16_t arg);
// brightness control
uint8_t memorized_level = MAX_1x7135;
@@ -43,6 +43,11 @@ uint8_t ramp_step_size = 1;
uint8_t target_level = 0;
#endif
+// strobe timing
+volatile uint8_t strobe_delay = 67;
+volatile uint8_t strobe_type = 0; // 0 == party strobe, 1 == tactical strobe
+
+
uint8_t off_state(EventPtr event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
@@ -74,7 +79,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
// 3 clicks: strobe mode
else if (event == EV_3clicks) {
- set_state(party_strobe_state, 255);
+ set_state(strobe_state, 0);
return 0;
}
// hold: go to lowest level
@@ -90,7 +95,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
set_state(steady_state, 1);
return 0;
}
- // click-release-hold: go to highest level (for ramping down)
+ // click, hold: go to highest level (for ramping down)
else if (event == EV_click2_hold) {
set_state(steady_state, MAX_LEVEL);
return 0;
@@ -98,6 +103,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
return 1;
}
+
uint8_t steady_state(EventPtr event, uint16_t arg) {
// turn LED on when we first enter the mode
if (event == EV_enter_state) {
@@ -135,7 +141,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
}
// 3 clicks: go to strobe modes
else if (event == EV_3clicks) {
- set_state(party_strobe_state, 0xff);
+ set_state(strobe_state, 0);
return 0;
}
// 4 clicks: toggle smooth vs discrete ramping
@@ -170,7 +176,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
set_level(memorized_level);
return 0;
}
- // click-release-hold: change brightness (dimmer)
+ // click, hold: change brightness (dimmer)
else if (event == EV_click2_hold) {
// ramp slower in discrete mode
if (arg % ramp_step_size != 0) {
@@ -219,26 +225,9 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
return 1;
}
-uint8_t party_strobe_state(EventPtr event, uint16_t arg) {
- static volatile uint8_t frames = 0;
- static volatile uint8_t between = 2;
+
+uint8_t strobe_state(EventPtr event, uint16_t arg) {
if (event == EV_enter_state) {
- if (arg < 64) between = arg;
- frames = 0;
- return 0;
- }
- // tick: strobe the emitter
- else if (event == EV_tick) {
- if (frames == 0) {
- PWM1_LVL = 0;
- PWM2_LVL = 255;
- if (between < 3) delay_zero();
- else delay_ms(1);
- PWM2_LVL = 0;
- }
- //frames = (frames + 1) % between;
- frames++;
- if (frames > between) frames = 0;
return 0;
}
// 1 click: off
@@ -246,25 +235,37 @@ uint8_t party_strobe_state(EventPtr event, uint16_t arg) {
set_state(off_state, 0);
return 0;
}
- // 2 clicks: go back to regular modes
+ // 2 clicks: toggle party strobe vs tactical strobe
else if (event == EV_2clicks) {
+ strobe_type ^= 1;
+ return 0;
+ }
+ // 3 clicks: go back to regular modes
+ else if (event == EV_3clicks) {
set_state(steady_state, memorized_level);
return 0;
}
- // hold: change speed
+ // hold: change speed (go faster)
else if (event == EV_click1_hold) {
- if ((arg % HOLD_TIMEOUT) == 0) {
- between = (between+1)%6;
- frames = 0;
+ if ((arg & 1) == 0) {
+ if (strobe_delay > 8) strobe_delay --;
+ }
+ return 0;
+ }
+ // click, hold: change speed (go slower)
+ else if (event == EV_click2_hold) {
+ if ((arg & 1) == 0) {
+ if (strobe_delay < 255) strobe_delay ++;
}
return 0;
}
return 1;
}
+
void low_voltage() {
// "step down" from strobe to something low
- if (current_state == party_strobe_state) {
+ if (current_state == strobe_state) {
set_state(steady_state, RAMP_SIZE/6);
}
// in normal mode, step down by half or turn off
@@ -278,6 +279,7 @@ void low_voltage() {
}
}
+
void setup() {
set_level(RAMP_SIZE/8);
delay_4ms(3);
@@ -285,3 +287,18 @@ void setup() {
push_state(off_state, 0);
}
+
+
+void loop() {
+ if (current_state == strobe_state) {
+ set_level(MAX_LEVEL);
+ if (strobe_type == 0) { // party strobe
+ if (strobe_delay < 30) delay_zero();
+ else delay_ms(1);
+ } else { //tactical strobe
+ nice_delay_ms(strobe_delay >> 1);
+ }
+ set_level(0);
+ nice_delay_ms(strobe_delay);
+ }
+}
diff --git a/spaghetti-monster/spaghetti-monster.h b/spaghetti-monster/spaghetti-monster.h
index 2ba3208..7d26390 100644
--- a/spaghetti-monster/spaghetti-monster.h
+++ b/spaghetti-monster/spaghetti-monster.h
@@ -54,9 +54,11 @@ void debug_blink(uint8_t num) {
// TODO? new delay() functions which handle queue consumption?
// TODO? new interruptible delay() functions?
+// Define these in your SpaghettiMonster recipe
// boot-time tasks
-// Define this in your SpaghettiMonster recipe
void setup();
+// single loop iteration, runs continuously
+void loop();
// include executable functions too, for easier compiling
#include "fsm-states.c"