aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/anduril/anduril.c3
-rw-r--r--spaghetti-monster/anduril/version-check-mode.c2
-rw-r--r--spaghetti-monster/fsm-events.c8
-rw-r--r--spaghetti-monster/fsm-main.c13
-rw-r--r--spaghetti-monster/fsm-misc.c34
-rw-r--r--spaghetti-monster/fsm-states.c8
-rw-r--r--spaghetti-monster/fsm-states.h7
7 files changed, 38 insertions, 37 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index b497eb9..f5bf1ee 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -297,7 +297,8 @@ void loop() {
// in simple mode, turn off after one readout
// FIXME: can eat the next button press
// (state changes in loop() act weird)
- if (simple_ui_active) set_state(off_state, 0);
+ if (simple_ui_active) set_state_deferred(off_state, 0);
+ else nice_delay_ms(1000);
#endif
}
#endif
diff --git a/spaghetti-monster/anduril/version-check-mode.c b/spaghetti-monster/anduril/version-check-mode.c
index 76efde3..edb1723 100644
--- a/spaghetti-monster/anduril/version-check-mode.c
+++ b/spaghetti-monster/anduril/version-check-mode.c
@@ -39,7 +39,7 @@ inline void version_check_iter() {
//while (button_is_pressed()) {}
//empty_event_sequence();
- set_state(off_state, 0);
+ set_state_deferred(off_state, 0);
}
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index b4cb671..3279c14 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -126,7 +126,6 @@ inline void interrupt_nice_delays() { nice_delay_interrupt = 1; }
// 0: state changed
// 1: normal completion
uint8_t nice_delay_ms(uint16_t ms) {
- StatePtr old_state = current_state;
/* // delay_zero() implementation
if (ms == 0) {
CLKPR = 1<<CLKPCE; CLKPR = 0; // full speed
@@ -135,6 +134,10 @@ uint8_t nice_delay_ms(uint16_t ms) {
}
*/
while(ms-- > 0) {
+ if (nice_delay_interrupt) {
+ return 0;
+ }
+
#ifdef USE_DYNAMIC_UNDERCLOCKING
#ifdef USE_RAMPING
uint8_t level = actual_level; // volatile, avoid repeat access
@@ -168,9 +171,6 @@ uint8_t nice_delay_ms(uint16_t ms) {
// run pending system processes while we wait
handle_deferred_interrupts();
- if ((nice_delay_interrupt) || (old_state != current_state)) {
- return 0; // state changed; abort
- }
// handle events only afterward, so that any collapsed delays will
// finish running the UI's loop() code before taking any further actions
// (this helps make sure code runs in the correct order)
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index 790cc68..0457d75 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -139,6 +139,14 @@ int main() {
// if event queue not empty, empty it
process_emissions();
+ // if loop() tried to change state, process that now
+ StatePtr df = deferred_state;
+ if (df) {
+ set_state(df, deferred_state_arg);
+ deferred_state = NULL;
+ //deferred_state_arg = 0; // unnecessary
+ }
+
// enter standby mode if requested
// (works better if deferred like this)
if (go_to_standby) {
@@ -164,11 +172,12 @@ int main() {
// catch up on interrupts
handle_deferred_interrupts();
+ // turn delays back on, if they were off
+ nice_delay_interrupt = 0;
+
// give the recipe some time slices
loop();
- // in case we fell through, turn delays back on
- nice_delay_interrupt = 0;
}
}
diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c
index 82be745..15cb659 100644
--- a/spaghetti-monster/fsm-misc.c
+++ b/spaghetti-monster/fsm-misc.c
@@ -83,13 +83,12 @@ uint8_t blink_big_num(uint16_t num) {
#endif
#ifdef USE_BLINK_NUM
uint8_t blink_num(uint8_t num) {
- //StatePtr old_state = current_state;
- #if 0
+ #if 1
uint8_t hundreds = num / 100;
num = num % 100;
uint8_t tens = num / 10;
num = num % 10;
- #else // 8 bytes smaller
+ #else // can be smaller or larger, depending on whether divmod is used elsewhere
uint8_t hundreds = 0;
uint8_t tens = 0;
for(; num >= 100; hundreds ++, num -= 100);
@@ -102,32 +101,9 @@ uint8_t blink_num(uint8_t num) {
nice_delay_ms(200);
#endif
- #if 0
- if (hundreds) {
- if (! blink_digit(hundreds)) return 0;
- if (! blink_digit(tens)) return 0;
- }
- else if (tens) {
- if (! blink_digit(tens)) return 0;
- }
- if (! blink_digit(num)) return 0;
- return nice_delay_ms(1000);
- #else // same size :(
- if (hundreds) if (! blink_digit(hundreds)) return 0;
- if (hundreds || tens) if (! blink_digit(tens)) return 0;
- if (! blink_digit(num)) return 0;
- return nice_delay_ms(1000);
- #endif
-
- /*
- uint8_t volts, tenths;
- volts = voltage / 10;
- tenths = voltage % 10;
- if (! blink(volts)) return;
- nice_delay_ms(200);
- if (! blink(tenths)) return;
- nice_delay_ms(200);
- */
+ if (hundreds) blink_digit(hundreds);
+ if (hundreds || tens) blink_digit(tens);
+ return blink_digit(num);
}
#endif
diff --git a/spaghetti-monster/fsm-states.c b/spaghetti-monster/fsm-states.c
index f91dc4b..4d9ac08 100644
--- a/spaghetti-monster/fsm-states.c
+++ b/spaghetti-monster/fsm-states.c
@@ -39,6 +39,9 @@ void _set_state(StatePtr new_state, uint16_t arg,
current_state = new_state;
// call new state-enter hook (don't use stack)
if (new_state != NULL) current_state(enter_event, arg);
+
+ // since state changed, stop any animation in progress
+ interrupt_nice_delays();
}
int8_t push_state(StatePtr new_state, uint16_t arg) {
@@ -79,6 +82,11 @@ uint8_t set_state(StatePtr new_state, uint16_t arg) {
return push_state(new_state, arg);
}
+void set_state_deferred(StatePtr new_state, uint16_t arg) {
+ deferred_state = new_state;
+ deferred_state_arg = arg;
+}
+
#ifndef DONT_USE_DEFAULT_STATE
// bottom state on stack
// handles default actions for LVP, thermal regulation, etc
diff --git a/spaghetti-monster/fsm-states.h b/spaghetti-monster/fsm-states.h
index 7d9361b..9964bc1 100644
--- a/spaghetti-monster/fsm-states.h
+++ b/spaghetti-monster/fsm-states.h
@@ -40,6 +40,13 @@ void _set_state(StatePtr new_state, uint16_t arg,
int8_t push_state(StatePtr new_state, uint16_t arg);
StatePtr pop_state();
uint8_t set_state(StatePtr new_state, uint16_t arg);
+
+// if loop() needs to change state, use this instead of set_state()
+// (because this avoids race conditions)
+volatile StatePtr deferred_state;
+volatile uint16_t deferred_state_arg;
+void set_state_deferred(StatePtr new_state, uint16_t arg);
+
#ifndef DONT_USE_DEFAULT_STATE
uint8_t default_state(Event event, uint16_t arg);
#endif
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.