aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2019-11-20 15:33:43 -0700
committerSelene ToyKeeper2019-11-20 15:33:43 -0700
commit10bd9162c3033f993b98e3c5b96cb95b9205d20e (patch)
treeeded168b91976d43e4f4c15355767646aa2c8653 /spaghetti-monster
parentmerged fsm updates / irq-refactor branch, to get more stable voltage readings (diff)
parentmerged tiny fix from irq-refactor branch (fixed spurious wakeup) (diff)
downloadanduril-10bd9162c3033f993b98e3c5b96cb95b9205d20e.tar.gz
anduril-10bd9162c3033f993b98e3c5b96cb95b9205d20e.tar.bz2
anduril-10bd9162c3033f993b98e3c5b96cb95b9205d20e.zip
merged more updates from fsm / irq-refactor branches, finishing up previous changes
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/anduril/anduril.c48
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern.h3
-rw-r--r--spaghetti-monster/anduril/cfg-blf-q8.h6
-rw-r--r--spaghetti-monster/anduril/cfg-mateminco-mf01s.h6
-rw-r--r--spaghetti-monster/fsm-adc.c18
-rw-r--r--spaghetti-monster/fsm-main.c16
-rw-r--r--spaghetti-monster/fsm-pcint.c3
-rw-r--r--spaghetti-monster/fsm-standby.c6
-rw-r--r--spaghetti-monster/fsm-wdt.c51
9 files changed, 98 insertions, 59 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index e006292..a86af16 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -90,6 +90,8 @@
// so don't enable them at the same time as any of the above strobes)
//#define USE_POLICE_STROBE_MODE
//#define USE_SOS_MODE
+//#define USE_SOS_MODE_IN_FF_GROUP // put SOS in the "boring strobes" mode
+//#define USE_SOS_MODE_IN_BLINKY_GROUP // put SOS in the blinkies mode group
// cut clock speed at very low modes for better efficiency
// (defined here so config files can override it)
@@ -149,7 +151,7 @@
#define USE_STROBE_STATE
#endif
-#if defined(USE_POLICE_STROBE_MODE) || defined(USE_SOS_MODE)
+#if defined(USE_POLICE_STROBE_MODE) || defined(USE_SOS_MODE_IN_FF_GROUP)
#define USE_BORING_STROBE_STATE
#endif
@@ -285,6 +287,10 @@ uint8_t goodnight_state(Event event, uint16_t arg);
uint8_t beacon_state(Event event, uint16_t arg);
uint8_t beacon_config_state(Event event, uint16_t arg);
#endif
+#ifdef USE_SOS_MODE_IN_BLINKY_GROUP
+// automatic SOS emergency signal
+uint8_t sos_state(Event event, uint16_t arg);
+#endif
// soft lockout
#define MOON_DURING_LOCKOUT_MODE
// if enabled, 2nd lockout click goes to the other ramp's floor level
@@ -1527,8 +1533,29 @@ inline void police_strobe_iter() {
}
}
#endif
+#endif // #ifdef USE_BORING_STROBE_STATE
#ifdef USE_SOS_MODE
+#ifdef USE_SOS_MODE_IN_BLINKY_GROUP
+uint8_t sos_state(Event event, uint16_t arg) {
+ // 1 click: off
+ if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: next mode
+ else if (event == EV_2clicks) {
+ #ifdef USE_THERMAL_REGULATION
+ set_state(tempcheck_state, 0);
+ #else
+ set_state(battcheck_state, 0);
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+#endif
+
void sos_blink(uint8_t num, uint8_t dah) {
#define DIT_LENGTH 200
for (; num > 0; num--) {
@@ -1547,14 +1574,13 @@ void sos_blink(uint8_t num, uint8_t dah) {
inline void sos_mode_iter() {
// one iteration of main loop()
- nice_delay_ms(1000);
+ //nice_delay_ms(1000);
sos_blink(3, 0); // S
sos_blink(3, 1); // O
sos_blink(3, 0); // S
- nice_delay_ms(1000);
+ nice_delay_ms(2000);
}
#endif // #ifdef USE_SOS_MODE
-#endif // #ifdef USE_BORING_STROBE_STATE
#ifdef USE_BATTCHECK
@@ -1605,9 +1631,11 @@ uint8_t beacon_state(Event event, uint16_t arg) {
}
// TODO: use sleep ticks to measure time between pulses,
// to save power
- // 2 clicks: tempcheck mode
+ // 2 clicks: next mode
else if (event == EV_2clicks) {
- #ifdef USE_THERMAL_REGULATION
+ #ifdef USE_SOS_MODE_IN_BLINKY_GROUP
+ set_state(sos_state, 0);
+ #elif defined(USE_THERMAL_REGULATION)
set_state(tempcheck_state, 0);
#else
set_state(battcheck_state, 0);
@@ -2697,7 +2725,7 @@ void loop() {
break;
#endif
- #ifdef USE_SOS_MODE
+ #ifdef USE_SOS_MODE_IN_FF_GROUP
default: // SOS
sos_mode_iter();
break;
@@ -2718,6 +2746,12 @@ void loop() {
}
#endif
+ #ifdef USE_SOS_MODE_IN_BLINKY_GROUP
+ else if (state == sos_state) {
+ sos_mode_iter();
+ }
+ #endif
+
#ifdef USE_THERMAL_REGULATION
// TODO: blink out therm_ceil during thermal_config_state?
else if (state == tempcheck_state) {
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h
index bf183eb..bdcd893 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern.h
@@ -54,6 +54,9 @@
#define MUGGLE_FLOOR 15 // about 20 lm
#define MUGGLE_CEILING 115 // about 350 lm
+#define USE_SOS_MODE
+#define USE_SOS_MODE_IN_BLINKY_GROUP
+
// the sensor (attiny85) is nowhere near the emitters
// so thermal regulation can't work
#ifdef USE_THERMAL_REGULATION
diff --git a/spaghetti-monster/anduril/cfg-blf-q8.h b/spaghetti-monster/anduril/cfg-blf-q8.h
index 166b10e..31c22ff 100644
--- a/spaghetti-monster/anduril/cfg-blf-q8.h
+++ b/spaghetti-monster/anduril/cfg-blf-q8.h
@@ -14,9 +14,9 @@
#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2)
// doesn't quite fit
-#ifdef USE_MUGGLE_MODE
-#undef USE_MUGGLE_MODE
-#endif
+//#ifdef USE_MUGGLE_MODE
+//#undef USE_MUGGLE_MODE
+//#endif
// copied from Emisar D4 ramp
// ../../bin/level_calc.py 1 65 7135 1 0.8 150
diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
index 2af1305..22b497b 100644
--- a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
+++ b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
@@ -15,9 +15,9 @@
// doesn't quite fit
-#ifdef USE_MUGGLE_MODE
-#undef USE_MUGGLE_MODE
-#endif
+//#ifdef USE_MUGGLE_MODE
+//#undef USE_MUGGLE_MODE
+//#endif
// don't blink during ramp, it's irrelevant and annoying on this light
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index 30f8460..9e52ab6 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -21,7 +21,7 @@
#define FSM_ADC_C
-inline void set_admux_therm() {
+static inline void set_admux_therm() {
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634)
ADMUX = ADMUX_THERM;
#elif (ATTINY == 841)
@@ -108,12 +108,12 @@ static inline uint8_t calc_voltage_divider(uint16_t value) {
}
#endif
-// Each full cycle runs 7.8X per second with just voltage enabled,
-// or 3.9X per second with voltage and temperature.
+// Each full cycle runs 15.6X per second with just voltage enabled,
+// or 7.8X per second with voltage and temperature.
#if defined(USE_LVP) && defined(USE_THERMAL_REGULATION)
-#define ADC_CYCLES_PER_SECOND 4
-#else
#define ADC_CYCLES_PER_SECOND 8
+#else
+#define ADC_CYCLES_PER_SECOND 16
#endif
#ifdef USE_THERMAL_REGULATION
@@ -322,13 +322,13 @@ static inline void ADC_temperature_handler() {
// if it's time to rotate the thermal history, do it
history_step ++;
#if (THERMAL_UPDATE_SPEED == 4) // new value every 4s
- #define THERM_HISTORY_STEP_MAX 15
+ #define THERM_HISTORY_STEP_MAX ((2*ADC_CYCLES_PER_SECOND)-1)
#elif (THERMAL_UPDATE_SPEED == 2) // new value every 2s
- #define THERM_HISTORY_STEP_MAX 7
+ #define THERM_HISTORY_STEP_MAX (ADC_CYCLES_PER_SECOND-1)
#elif (THERMAL_UPDATE_SPEED == 1) // new value every 1s
- #define THERM_HISTORY_STEP_MAX 3
+ #define THERM_HISTORY_STEP_MAX ((ADC_CYCLES_PER_SECOND/2)-1)
#elif (THERMAL_UPDATE_SPEED == 0) // new value every 0.5s
- #define THERM_HISTORY_STEP_MAX 1
+ #define THERM_HISTORY_STEP_MAX ((ADC_CYCLES_PER_SECOND/4)-1)
#endif
if (0 == (history_step & THERM_HISTORY_STEP_MAX)) {
// rotate measurements and add a new one
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index c9ab69b..4ad1e16 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -37,7 +37,7 @@ ISR(TIMER1_COMPA_vect) {
#endif
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
-inline void hw_setup() {
+static inline void hw_setup() {
// configure PWM channels
#if PWM_CHANNELS >= 1
DDRB |= (1 << PWM1_PIN);
@@ -69,7 +69,7 @@ inline void hw_setup() {
PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
}
#elif (ATTINY == 1634)
-inline void hw_setup() {
+static inline void hw_setup() {
// this gets tricky with so many pins...
// ... so punt it to the hwdef file
hwdef_setup();
@@ -79,22 +79,24 @@ inline void hw_setup() {
#endif
-#ifdef USE_REBOOT
-void prevent_reboot_loop() {
+//#ifdef USE_REBOOT
+static inline void prevent_reboot_loop() {
// prevent WDT from rebooting MCU again
MCUSR &= ~(1<<WDRF); // reset status flag
wdt_disable();
}
-#endif
+//#endif
int main() {
// Don't allow interrupts while booting
cli();
- #ifdef USE_REBOOT
+ //#ifdef USE_REBOOT
+ // prevents cycling after a crash,
+ // whether intentional (like factory reset) or not (bugs)
prevent_reboot_loop();
- #endif
+ //#endif
hw_setup();
diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c
index a4a496a..1ba1c15 100644
--- a/spaghetti-monster/fsm-pcint.c
+++ b/spaghetti-monster/fsm-pcint.c
@@ -97,8 +97,7 @@ void PCINT_inner(uint8_t pressed) {
pushed = push_event(B_RELEASE);
}
- // check if sequence matches any defined sequences
- // if so, send event to current state callback
+ // send event to the current state callback
if (pushed) {
button_last_state = pressed;
emit_current_event(0);
diff --git a/spaghetti-monster/fsm-standby.c b/spaghetti-monster/fsm-standby.c
index 4124d92..9398f52 100644
--- a/spaghetti-monster/fsm-standby.c
+++ b/spaghetti-monster/fsm-standby.c
@@ -54,6 +54,7 @@ void sleep_until_eswitch_pressed()
#else
go_to_standby = 0;
#endif
+
// configure sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
@@ -89,7 +90,10 @@ void sleep_until_eswitch_pressed()
#endif
// go back to normal running mode
- //PCINT_on(); // should be on already
+ // PCINT not needed any more, and can cause problems if on
+ // (occasional reboots on wakeup-by-button-press)
+ PCINT_off();
+ // restore normal awake-mode interrupts
ADC_on();
WDT_on();
}
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index beab1a2..0c49a75 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -90,6 +90,14 @@ void WDT_inner() {
static uint8_t adc_trigger = 0;
+ // cache this here to reduce ROM size, because it's volatile
+ uint16_t ticks_since_last = ticks_since_last_event;
+ // increment, but loop from max back to half
+ ticks_since_last = (ticks_since_last + 1) \
+ | (ticks_since_last & 0x8000);
+ // copy back to the original
+ ticks_since_last_event = ticks_since_last;
+
// detect and emit button change events (even during standby)
uint8_t was_pressed = button_last_state;
uint8_t pressed = button_is_pressed();
@@ -97,38 +105,29 @@ void WDT_inner() {
go_to_standby = 0;
PCINT_inner(pressed);
}
+ // cache again, in case the value changed
+ ticks_since_last = ticks_since_last_event;
#ifdef TICK_DURING_STANDBY
- static uint16_t sleep_counter = 0;
// handle standby mode specially
if (go_to_standby) {
// emit a halfsleep tick, and process it
- emit(EV_sleep_tick, sleep_counter);
- // wrap around from 65535 to 32768, not 0
- sleep_counter = (sleep_counter + 1) | (sleep_counter & 0x8000);
+ emit(EV_sleep_tick, ticks_since_last);
process_emissions();
- #if defined(USE_SLEEP_LVP)
+ #ifndef USE_SLEEP_LVP
+ return; // no sleep LVP needed if nothing drains power while off
+ #else
// stop here, usually... but proceed often enough for sleep LVP to work
- if (0 != (sleep_counter & 0x7f)) return;
+ if (0 != (ticks_since_last & 0x7f)) return;
+
adc_trigger = 255; // make sure a measurement will happen
- #else
- return; // no sleep LVP needed if nothing drains power while off
+ ADC_on(); // enable ADC voltage measurement functions temporarily
#endif
}
- else { sleep_counter = 0; }
+ else { // button handling should only happen while awake
#endif
- // cache this here to reduce ROM size, because it's volatile
- uint16_t ticks_since_last = ticks_since_last_event;
-
- // increment, but loop from max back to half
- //if (ticks_since_last < 0xff) ticks_since_last ++;
- ticks_since_last = (ticks_since_last + 1) \
- | (ticks_since_last & 0x8000);
- // copy back to the original
- ticks_since_last_event = ticks_since_last;
-
// if time since last event exceeds timeout,
// append timeout to current event sequence, then
// send event to current state callback
@@ -148,9 +147,9 @@ void WDT_inner() {
emit_current_event(ticks_since_last);
}
// has button been down long enough to become a "hold"?
+ // (first frame of a "hold" event)
else {
if (ticks_since_last >= HOLD_TIMEOUT) {
- //ticks_since_last_event = 0;
current_event |= B_HOLD;
emit_current_event(0);
}
@@ -163,27 +162,25 @@ void WDT_inner() {
// no timeout required when releasing a long-press
// TODO? move this logic to PCINT() and simplify things here?
if (current_event & B_HOLD) {
- //emit_current_event(0); // should have been emitted by PCINT
+ //emit_current_event(0); // should have been emitted by PCINT_inner()
empty_event_sequence();
}
// end and clear event after release timeout
else if (ticks_since_last >= RELEASE_TIMEOUT) {
current_event |= B_TIMEOUT;
- //ticks_since_last_event = 0;
emit_current_event(0);
empty_event_sequence();
}
}
+ #ifdef TICK_DURING_STANDBY
+ }
+ #endif
+
#if defined(USE_LVP) || defined(USE_THERMAL_REGULATION)
// start a new ADC measurement every 4 ticks
adc_trigger ++;
if (0 == (adc_trigger & 3)) {
- #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP)
- // we shouldn't be here unless it woke up for a LVP check...
- // so enable ADC voltage measurement functions temporarily
- if (go_to_standby) ADC_on();
- #endif
ADC_start_measurement();
irq_adc_stable = 0;
adcint_enable = 1;
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.