aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2020-09-27 03:26:01 -0600
committerSelene ToyKeeper2020-09-27 03:26:01 -0600
commit2173d1e3641ca2396a4460e5736823013e1c9357 (patch)
treed344b0d8d4fa253ef940d563a4c233e26744412f /spaghetti-monster
parentfixed bug: momentary bike mode could sometimes get stuck on for a few seconds... (diff)
downloadanduril-2173d1e3641ca2396a4460e5736823013e1c9357.tar.gz
anduril-2173d1e3641ca2396a4460e5736823013e1c9357.tar.bz2
anduril-2173d1e3641ca2396a4460e5736823013e1c9357.zip
reworked nice_delay interrupt system and fixed some old issues:
- added set_state_deferred(), to avoid timing issues when changing state in loop() (fixes bug where first button press after version check was sometimes ignored, and similar issue after battcheck in simple UI) - reduced chance of eating first button press after simple UI's battcheck, because it spent an extra second waiting after finishing the readout, and it wasn't intuitive for a single click to go from "post-battcheck darkness" to "off" during that period - made interrupt_nice_delays() happen every time the state changes, instead of having nice_delay() explicitly check for state changes while it waits... (because the explicit check was buggy and used more ROM) - made nice_delay_ms() abort immediately when interrupt is set, instead of waiting 1ms before it even checks for the interrupt condition... this makes aborted animations end a lot faster, with less visible flickering - made blink_num() smaller and simpler, because changes listed above make it possible - slightly changed order of events in main(), to accommodate for changes above - fixed issue where battcheck would keep trying to blink out numbers while the user was holding 10H for voltage config mode - ... and reduced ROM size by about 38 bytes
Diffstat (limited to 'spaghetti-monster')
-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.