From 73a5a6974a98aa73ab392272b4d69d285c85dee5 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Sat, 19 Aug 2017 17:20:46 -0600
Subject: Completely reorganized SpaghettiMonster code into smaller logical
pieces: fsm-*.c and fsm-*.h.
---
spaghetti-monster/fsm-events.c | 137 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 137 insertions(+)
create mode 100644 spaghetti-monster/fsm-events.c
(limited to 'spaghetti-monster/fsm-events.c')
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
new file mode 100644
index 0000000..6dda236
--- /dev/null
+++ b/spaghetti-monster/fsm-events.c
@@ -0,0 +1,137 @@
+/*
+ * fsm-events.c: Event-handling functions for SpaghettiMonster.
+ *
+ * Copyright (C) 2017 Selene ToyKeeper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FSM_EVENTS_C
+#define FSM_EVENTS_C
+
+// TODO: maybe compare events by number instead of pointer?
+// (number = index in event types array)
+// (comparison would use full event content, but send off index to callbacks)
+// (saves space by using uint8_t instead of a pointer)
+// (also eliminates the need to duplicate single-entry events like for voltage or timer tick)
+
+// return 1 if (a == b), 0 otherwise
+uint8_t compare_event_sequences(uint8_t *a, const uint8_t *b) {
+ for(uint8_t i=0; (i= offset) return current_event[i-offset];
+ return 0;
+}
+*/
+
+inline uint8_t last_event_num() {
+ uint8_t i;
+ for(i=0; current_event[i] && (i=0; i--) {
+ uint8_t err = state_stack[i](event, arg);
+ if (! err) return 0;
+ }
+ return 1; // event not handled
+}
+
+void emit(EventPtr event, uint16_t arg) {
+ // add this event to the queue for later,
+ // so we won't use too much time during an interrupt
+ append_emission(event, arg);
+}
+
+// Search the pre-defined event list for one matching what the user just did,
+// and emit it if one was found.
+void emit_current_event(uint16_t arg) {
+ //uint8_t err = 1;
+ for (uint8_t i=0; i<(sizeof(event_sequences)/sizeof(EventPtr)); i++) {
+ if (events_match(current_event, event_sequences[i])) {
+ //DEBUG_FLASH;
+ //err = emit(event_sequences[i], arg);
+ //return err;
+ emit(event_sequences[i], arg);
+ return;
+ }
+ }
+ //return err;
+}
+
+// TODO? add events to a queue when inside an interrupt
+// instead of calling the event functions directly?
+// (then empty the queue in main loop?)
+
+#endif
--
cgit v1.2.3
From 32eaeddee34c76dda5456ed960be6278ed68e48d Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Thu, 24 Aug 2017 16:21:45 -0600
Subject: 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.
---
spaghetti-monster/fsm-events.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
(limited to 'spaghetti-monster/fsm-events.c')
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--) {
--
cgit v1.2.3
From 39b30b41f92978a3e05a8de0a416279fb35b35b1 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Fri, 25 Aug 2017 02:14:31 -0600
Subject: Added battcheck mode to ramping-ui. It's bigger than I had hoped.
:( Added fsm-misc.*, which currently only has interruptible blink functions
in it. (for blinking out numbers and such)
---
spaghetti-monster/fsm-events.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
(limited to 'spaghetti-monster/fsm-events.c')
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index 4831df6..29ef415 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -122,6 +122,18 @@ uint8_t nice_delay_ms(uint16_t ms) {
return 1;
}
+/*
+uint8_t nice_delay_4ms(uint8_t ms) {
+ return nice_delay_ms((uint16_t)ms << 2);
+}
+*/
+
+/*
+uint8_t nice_delay_s() {
+ return nice_delay_4ms(250);
+}
+*/
+
// 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--) {
--
cgit v1.2.3
From 674259407ace91bef354059c842b4114e95eb23c Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Sat, 26 Aug 2017 03:06:12 -0600
Subject: Added beacons/strobes to DarkHorse. Added a way to explicitly cancel
the current "nice" delay without changing state.
---
spaghetti-monster/fsm-events.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
(limited to 'spaghetti-monster/fsm-events.c')
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index 29ef415..90d0ffa 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -106,6 +106,10 @@ void process_emissions() {
}
}
+// explicitly interrupt these "nice" delays
+volatile uint8_t nice_delay_interrupt = 0;
+inline void interrupt_nice_delays() { nice_delay_interrupt = 1; }
+
// like delay_ms, except it aborts on state change
// return value:
// 0: state changed
@@ -115,7 +119,8 @@ uint8_t nice_delay_ms(uint16_t ms) {
while(ms-- > 0) {
_delay_loop_2(BOGOMIPS*98/100);
process_emissions();
- if (old_state != current_state) {
+ if ((nice_delay_interrupt) || (old_state != current_state)) {
+ nice_delay_interrupt = 0;
return 0; // state changed; abort
}
}
--
cgit v1.2.3
From 4a96d3e40ee667fa819c8c95b5e360245a12865a Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 28 Aug 2017 02:13:35 -0600
Subject: Fixed a crash when user presses the button more times than the UI
supports. (need to leave room for a trailing 0 in the array, oops)
---
spaghetti-monster/fsm-events.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'spaghetti-monster/fsm-events.c')
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index 90d0ffa..99a6a72 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -47,7 +47,7 @@ uint8_t push_event(uint8_t ev_type) {
uint8_t prev_event = 0; // never push the same event twice in a row
for(i=0; current_event[i] && (i 0) {
+ #ifdef USE_DYNAMIC_UNDERCLOCKING
+ // underclock MCU to save power
+ CLKPR = 1< 0) {
+ // underclock MCU to save power
+ CLKPR = 1< 0) {
#ifdef USE_DYNAMIC_UNDERCLOCKING
+ #ifdef USE_RAMPING
+ uint8_t level = actual_level; // volatile, avoid repeat access
+ if (level < QUARTERSPEED_LEVEL) {
+ CLKPR = 1<