aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2018-12-18 07:46:38 -0700
committerSelene ToyKeeper2018-12-18 07:46:38 -0700
commit4ba3d972dd74abf90ad4e64a2ddfee9f04d08829 (patch)
treee24c2c7679f2d148e26be9679722557915e9bb0d /spaghetti-monster
parentmerged upstream changes from fsm branch (diff)
parentUpdated Anduril text file, mostly. (diff)
downloadanduril-4ba3d972dd74abf90ad4e64a2ddfee9f04d08829.tar.gz
anduril-4ba3d972dd74abf90ad4e64a2ddfee9f04d08829.tar.bz2
anduril-4ba3d972dd74abf90ad4e64a2ddfee9f04d08829.zip
merged updates from fsm branch
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/anduril/anduril.c137
-rw-r--r--spaghetti-monster/anduril/anduril.txt57
-rwxr-xr-xspaghetti-monster/anduril/build-all.sh2
-rw-r--r--spaghetti-monster/anduril/cfg-blf-q8.h5
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4s.h2
-rw-r--r--spaghetti-monster/anduril/cfg-ff-pl47-219.h8
-rw-r--r--spaghetti-monster/anduril/cfg-sofirn-sp36.h31
-rw-r--r--spaghetti-monster/baton/baton.c12
-rw-r--r--spaghetti-monster/darkhorse/darkhorse.c28
-rw-r--r--spaghetti-monster/fsm-events.c95
-rw-r--r--spaghetti-monster/fsm-events.h614
-rw-r--r--spaghetti-monster/fsm-pcint.c4
-rw-r--r--spaghetti-monster/fsm-states.c4
-rw-r--r--spaghetti-monster/fsm-states.h6
-rw-r--r--spaghetti-monster/fsm-wdt.c59
-rw-r--r--spaghetti-monster/meteor/meteor.c62
-rw-r--r--spaghetti-monster/momentary/momentary.c2
-rw-r--r--spaghetti-monster/ramping-ui/ramping-ui.c20
-rw-r--r--spaghetti-monster/rampingios/rampingiosv3.c109
-rw-r--r--spaghetti-monster/spaghetti-monster.txt103
-rw-r--r--spaghetti-monster/werner/README56
-rwxr-xr-xspaghetti-monster/werner/build-all.sh2
-rw-r--r--spaghetti-monster/werner/werner.c33
23 files changed, 605 insertions, 846 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index bebef72..3987d92 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -109,6 +109,9 @@
#elif defined(FSM_FF_PL47_DRIVER)
#include "cfg-ff-pl47.h"
+#elif defined(FSM_FF_PL47_219_DRIVER)
+#include "cfg-ff-pl47-219.h"
+
#elif defined(FSM_FF_ROT66_DRIVER)
#include "cfg-ff-rot66.h"
@@ -149,15 +152,6 @@
#define MAX_BIKING_LEVEL 120 // should be 127 or less
#define USE_BATTCHECK
-// determine the highest number of clicks to handle
-#ifdef USE_INDICATOR_LED
-#define MAX_CLICKS 7
-#elif defined(USE_MUGGLE_MODE)
-#define MAX_CLICKS 6
-#else
-#define MAX_CLICKS 5
-#endif
-
#if defined(USE_MUGGLE_MODE)
#ifndef MUGGLE_FLOOR
#define MUGGLE_FLOOR 22
@@ -232,49 +226,49 @@ typedef enum {
// FSM states
-uint8_t off_state(EventPtr event, uint16_t arg);
+uint8_t off_state(Event event, uint16_t arg);
// simple numeric entry config menu
-uint8_t config_state_base(EventPtr event, uint16_t arg,
+uint8_t config_state_base(Event event, uint16_t arg,
uint8_t num_config_steps,
void (*savefunc)());
#define MAX_CONFIG_VALUES 3
uint8_t config_state_values[MAX_CONFIG_VALUES];
// ramping mode and its related config mode
-uint8_t steady_state(EventPtr event, uint16_t arg);
-uint8_t ramp_config_state(EventPtr event, uint16_t arg);
+uint8_t steady_state(Event event, uint16_t arg);
+uint8_t ramp_config_state(Event event, uint16_t arg);
#ifdef USE_TINT_RAMPING
// not actually a mode, more of a fallback under other modes
-uint8_t tint_ramping_state(EventPtr event, uint16_t arg);
+uint8_t tint_ramping_state(Event event, uint16_t arg);
#endif
// party and tactical strobes
#ifdef USE_STROBE_STATE
-uint8_t strobe_state(EventPtr event, uint16_t arg);
+uint8_t strobe_state(Event event, uint16_t arg);
#endif
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg);
+uint8_t battcheck_state(Event event, uint16_t arg);
#endif
#ifdef USE_THERMAL_REGULATION
-uint8_t tempcheck_state(EventPtr event, uint16_t arg);
-uint8_t thermal_config_state(EventPtr event, uint16_t arg);
+uint8_t tempcheck_state(Event event, uint16_t arg);
+uint8_t thermal_config_state(Event event, uint16_t arg);
#endif
// 1-hour ramp down from low, then automatic off
-uint8_t goodnight_state(EventPtr event, uint16_t arg);
+uint8_t goodnight_state(Event event, uint16_t arg);
// beacon mode and its related config mode
-uint8_t beacon_state(EventPtr event, uint16_t arg);
-uint8_t beacon_config_state(EventPtr event, uint16_t arg);
+uint8_t beacon_state(Event event, uint16_t arg);
+uint8_t beacon_config_state(Event event, uint16_t arg);
// soft lockout
#define MOON_DURING_LOCKOUT_MODE
-uint8_t lockout_state(EventPtr event, uint16_t arg);
+uint8_t lockout_state(Event event, uint16_t arg);
// momentary / signalling mode
-uint8_t momentary_state(EventPtr event, uint16_t arg);
+uint8_t momentary_state(Event event, uint16_t arg);
#ifdef USE_MUGGLE_MODE
// muggle mode, super-simple, hard to exit
-uint8_t muggle_state(EventPtr event, uint16_t arg);
+uint8_t muggle_state(Event event, uint16_t arg);
uint8_t muggle_mode_active = 0;
#endif
// general helper function for config modes
-uint8_t number_entry_state(EventPtr event, uint16_t arg);
+uint8_t number_entry_state(Event event, uint16_t arg);
// return value from number_entry_state()
volatile uint8_t number_entry_value;
@@ -397,7 +391,7 @@ uint8_t triangle_wave(uint8_t phase);
volatile uint8_t beacon_seconds = 2;
-uint8_t off_state(EventPtr event, uint16_t arg) {
+uint8_t off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
set_level(0);
@@ -537,7 +531,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
-uint8_t steady_state(EventPtr event, uint16_t arg) {
+uint8_t steady_state(Event event, uint16_t arg) {
uint8_t mode_min = ramp_smooth_floor;
uint8_t mode_max = ramp_smooth_ceil;
uint8_t ramp_step_size = 1;
@@ -856,7 +850,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
#ifdef USE_TINT_RAMPING
-uint8_t tint_ramping_state(EventPtr event, uint16_t arg) {
+uint8_t tint_ramping_state(Event event, uint16_t arg) {
static int8_t tint_ramp_direction = 1;
// click, click, hold: change the tint
@@ -889,7 +883,7 @@ uint8_t tint_ramping_state(EventPtr event, uint16_t arg) {
#ifdef USE_STROBE_STATE
-uint8_t strobe_state(EventPtr event, uint16_t arg) {
+uint8_t strobe_state(Event event, uint16_t arg) {
// 'st' reduces ROM size by avoiding access to a volatile var
// (maybe I should just make it nonvolatile?)
strobe_mode_te st = strobe_type;
@@ -1102,7 +1096,7 @@ uint8_t strobe_state(EventPtr event, uint16_t arg) {
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg) {
+uint8_t battcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -1119,7 +1113,7 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
-uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
+uint8_t tempcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -1140,7 +1134,7 @@ uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
#endif
-uint8_t beacon_state(EventPtr event, uint16_t arg) {
+uint8_t beacon_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -1167,7 +1161,7 @@ uint8_t beacon_state(EventPtr event, uint16_t arg) {
#define GOODNIGHT_TICKS_PER_STEPDOWN (GOODNIGHT_TIME*TICKS_PER_SECOND*60L/GOODNIGHT_LEVEL)
-uint8_t goodnight_state(EventPtr event, uint16_t arg) {
+uint8_t goodnight_state(Event event, uint16_t arg) {
static uint16_t ticks_since_stepdown = 0;
// blink on start
if (event == EV_enter_state) {
@@ -1206,29 +1200,24 @@ uint8_t goodnight_state(EventPtr event, uint16_t arg) {
}
-uint8_t lockout_state(EventPtr event, uint16_t arg) {
+uint8_t lockout_state(Event event, uint16_t arg) {
#ifdef MOON_DURING_LOCKOUT_MODE
// momentary(ish) moon mode during lockout
- // not all presses will be counted;
- // it depends on what is in the master event_sequences table
- uint8_t last = 0;
- for(uint8_t i=0; pgm_read_byte(event + i) && (i<EV_MAX_LEN); i++)
- last = pgm_read_byte(event + i);
- if (arg == 0) { // Only turn on/off when button state changes
- if ((last == A_PRESS) || (last == A_HOLD)) {
- #ifdef LOCKOUT_MOON_LOWEST
- // Use lowest moon configured
- uint8_t lvl = ramp_smooth_floor;
- if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
- set_level(lvl);
- #else
- // Use moon from current ramp
- set_level(nearest_level(1));
- #endif
- }
- else if ((last == A_RELEASE) || (last == A_RELEASE_TIMEOUT)) {
- set_level(0);
- }
+ // button is being held
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
+ #ifdef LOCKOUT_MOON_LOWEST
+ // Use lowest moon configured
+ uint8_t lvl = ramp_smooth_floor;
+ if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
+ set_level(lvl);
+ #else
+ // Use moon from current ramp
+ set_level(nearest_level(1));
+ #endif
+ }
+ // button was released
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ set_level(0);
}
#endif
@@ -1321,19 +1310,19 @@ uint8_t lockout_state(EventPtr event, uint16_t arg) {
}
-uint8_t momentary_state(EventPtr event, uint16_t arg) {
+uint8_t momentary_state(Event event, uint16_t arg) {
// TODO: momentary strobe here? (for light painting)
- if (event == EV_click1_press) {
+
+ // light up when the button is pressed; go dark otherwise
+ // button is being held
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
set_level(memorized_level);
- empty_event_sequence(); // don't attempt to parse multiple clicks
return MISCHIEF_MANAGED;
}
-
- else if (event == EV_release) {
+ // button was released
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
set_level(0);
- empty_event_sequence(); // don't attempt to parse multiple clicks
//go_to_standby = 1; // sleep while light is off
- // TODO: lighted button should use lockout config?
return MISCHIEF_MANAGED;
}
@@ -1345,6 +1334,7 @@ uint8_t momentary_state(EventPtr event, uint16_t arg) {
else if ((event == EV_tick) && (actual_level == 0)) {
if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
go_to_standby = 1; // sleep while light is off
+ // TODO: lighted button should use lockout config?
}
return MISCHIEF_MANAGED;
}
@@ -1354,7 +1344,7 @@ uint8_t momentary_state(EventPtr event, uint16_t arg) {
#ifdef USE_MUGGLE_MODE
-uint8_t muggle_state(EventPtr event, uint16_t arg) {
+uint8_t muggle_state(Event event, uint16_t arg) {
static int8_t ramp_direction;
static int8_t muggle_off_mode;
@@ -1504,7 +1494,7 @@ uint8_t muggle_state(EventPtr event, uint16_t arg) {
// ask the user for a sequence of numbers, then save them and return to caller
-uint8_t config_state_base(EventPtr event, uint16_t arg,
+uint8_t config_state_base(Event event, uint16_t arg,
uint8_t num_config_steps,
void (*savefunc)()) {
static uint8_t config_step;
@@ -1563,7 +1553,7 @@ void ramp_config_save() {
}
}
-uint8_t ramp_config_state(EventPtr event, uint16_t arg) {
+uint8_t ramp_config_state(Event event, uint16_t arg) {
uint8_t num_config_steps;
num_config_steps = 2 + ramp_style;
return config_state_base(event, arg,
@@ -1591,7 +1581,7 @@ void thermal_config_save() {
if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
}
-uint8_t thermal_config_state(EventPtr event, uint16_t arg) {
+uint8_t thermal_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
2, thermal_config_save);
}
@@ -1606,13 +1596,13 @@ void beacon_config_save() {
}
}
-uint8_t beacon_config_state(EventPtr event, uint16_t arg) {
+uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
-uint8_t number_entry_state(EventPtr event, uint16_t arg) {
+uint8_t number_entry_state(Event event, uint16_t arg) {
static uint8_t value;
static uint8_t blinks_left;
static uint8_t entry_step;
@@ -1743,12 +1733,23 @@ void blink_confirm(uint8_t num) {
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
// beacon-like mode for the indicator LED
void indicator_blink(uint8_t arg) {
+ #ifdef USE_FANCIER_BLINKING_INDICATOR
+
+ // fancy blink, set off/low/high levels here:
+ uint8_t seq[] = {0, 1, 2, 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0};
+ indicator_led(seq[arg & 15]);
+
+ #else // basic blink, 1/8th duty cycle
+
if (! (arg & 7)) {
indicator_led(2);
}
else {
indicator_led(0);
}
+
+ #endif
}
#endif
@@ -1843,6 +1844,8 @@ void save_config_wl() {
void low_voltage() {
StatePtr state = current_state;
+ // TODO: turn off aux LED(s) when power is really low
+
if (0) {} // placeholder
#ifdef USE_STROBE_STATE
diff --git a/spaghetti-monster/anduril/anduril.txt b/spaghetti-monster/anduril/anduril.txt
index f0f0b4d..3e0328c 100644
--- a/spaghetti-monster/anduril/anduril.txt
+++ b/spaghetti-monster/anduril/anduril.txt
@@ -21,7 +21,7 @@ From off:
* 7 clicks: Change aux LED mode used in "off" mode.
(the modes are usually off/low/high/blinking)
-In steady mode:
+In steady / ramping mode:
* 1 click: off
* Hold: ramp up
* Click, hold: ramp down
@@ -30,19 +30,17 @@ In steady mode:
* 4 clicks: configure current ramp
Smooth ramp config mode:
- - Setting 1: memory on/off (not implemented yet)
- * Setting 2: low end
+ * Setting 1: low end
(click N times to set ramp floor to level N)
- * Setting 3: high end
+ * Setting 2: high end
(click N times to set ramp ceiling to level "151 - N")
Discrete ramp config mode:
- - Setting 1: memory on/off (not implemented yet)
- * Setting 2: low end
+ * Setting 1: low end
(click N times to set ramp floor to level N)
- * Setting 3: high end
+ * Setting 2: high end
(click N times to set ramp ceiling to level "151 - N")
- * Setting 4: number of levels in discrete ramp
+ * Setting 3: number of levels in discrete ramp
(click N times to make discrete mode have N stair-steps)
(minimum 2, maximum 150)
@@ -96,7 +94,6 @@ Discrete ramp config mode:
* 1 click: off
* 2 clicks: battcheck mode
* 4 clicks: thermal config mode
- - Hold: thermal calibration mode
Thermal config mode:
* Setting 1: calibrate sensor:
@@ -106,10 +103,6 @@ Discrete ramp config mode:
* Setting 2: temperature limit:
At buzz, click N times to set thermal limit to roughly 30 C + N.
- Thermal calibration mode:
- - Hold until hot: set new ceiling value
- - ... don't hold: blink out current ceiling value and exit
-
Lockout mode:
* Hold: momentary moon
* 4 clicks: exit lockout (return to regular "off" mode)
@@ -127,24 +120,33 @@ Muggle mode:
* Hold: Ramp up / down.
* 6 clicks: Exit muggle mode.
-Indicator LED support:
+Indicator LED / aux LED support:
+
+ The indicator LED (button LED), if there is one, tracks the brightness
+ of the main LED(s) during use. It'll be off, low, or high depending
+ on whether the main emitter is off, using only the first power
+ channel, or using a higher level.
- The indicator LED, if there is one, tracks the brightness of the main
- LED(s) during use. It'll be off, low, or high depending on whether
- the main emitter is off, using only the first power channel, or using
- a higher level.
+ If front-facing aux LEDs are present, they stay off while the main
+ light is on. They only turn on when the main emitters are off.
The indicator LED can stay on when the light is in the "off" state or
- lockout state. The user can configure each state to be low, high, or
- off. To configure it:
+ "lockout" state. These modes can have different settings, to make it
+ easier to see which one the light is in. To configure it:
+
+ 1. Go to the standby mode you want to configure. This is either
+ "off" or "lockout".
+ 2. In "off" mode, click 7 times to switch to the next aux LED mode.
+ Or in "lockout" mode, click 3 times.
+ 3. Repeat step 2 until the desired mode is reached.
+
+ The available aux LED / indicator LED modes vary depending on the type
+ of light, but they typically have the following modes:
- 1. Go to lockout mode. (4 clicks)
- 2. Click 3 times, optionally holding the third press, to change the
- value:
- * 3 fast clicks: Change lockout mode button brightness.
- * Hold the third click: Change regular "off" mode button
- brightness. Let go when desired level is reached.
- 3. Exit lockout mode. (4 clicks)
+ - Off
+ - Low
+ - High
+ - Blinking
TODO:
@@ -168,3 +170,4 @@ TODO:
- candle mode: smoother adjustments?
- make sunset mode timer and brightness configurable?
- make beacon mode actually sleep between pulses
+ - add a toggle for memory?
diff --git a/spaghetti-monster/anduril/build-all.sh b/spaghetti-monster/anduril/build-all.sh
index b50744f..ea79347 100755
--- a/spaghetti-monster/anduril/build-all.sh
+++ b/spaghetti-monster/anduril/build-all.sh
@@ -14,12 +14,14 @@ for TARGET in \
EMISAR_D4S \
EMISAR_D4S_219C \
FF_PL47 \
+ FF_PL47_219 \
FF_ROT66 \
FF_ROT66_219 \
FW3A \
SOFIRN_SP36 \
; do
echo "===== $TARGET ====="
+ echo ../../../bin/build.sh 85 "$UI" "-DFSM_${TARGET}_DRIVER"
../../../bin/build.sh 85 "$UI" "-DFSM_${TARGET}_DRIVER"
mv -f "$UI".hex "$UI".$TARGET.hex
done
diff --git a/spaghetti-monster/anduril/cfg-blf-q8.h b/spaghetti-monster/anduril/cfg-blf-q8.h
index 1b9b971..90099c3 100644
--- a/spaghetti-monster/anduril/cfg-blf-q8.h
+++ b/spaghetti-monster/anduril/cfg-blf-q8.h
@@ -6,6 +6,11 @@
#define USE_INDICATOR_LED_WHILE_RAMPING
// enable blinking indicator LED while off
#define TICK_DURING_STANDBY
+#define STANDBY_TICK_SPEED 3 // every 0.128 s
+#define USE_FANCIER_BLINKING_INDICATOR
+// off mode: high (2)
+// lockout: blinking (3)
+#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2)
// copied from Emisar D4 ramp
// ../../bin/level_calc.py 1 65 7135 1 0.8 150
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s.h b/spaghetti-monster/anduril/cfg-emisar-d4s.h
index ef55668..1070ee7 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4s.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4s.h
@@ -8,6 +8,8 @@
#endif
// enable blinking indicator LED while off
#define TICK_DURING_STANDBY
+#define STANDBY_TICK_SPEED 3 // every 0.128 s
+#define USE_FANCIER_BLINKING_INDICATOR
#ifdef RAMP_LENGTH
#undef RAMP_LENGTH
diff --git a/spaghetti-monster/anduril/cfg-ff-pl47-219.h b/spaghetti-monster/anduril/cfg-ff-pl47-219.h
new file mode 100644
index 0000000..ea701bd
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-ff-pl47-219.h
@@ -0,0 +1,8 @@
+// Fireflies PL47-219B config options for Anduril
+// same as PL47 but with FET modes limited to 67% power
+// to avoid destroying the LEDs
+#define FSM_FF_PL47_DRIVER
+#include "cfg-ff-pl47.h"
+
+#undef PWM2_LEVELS
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,19,20,22,23,25,27,28,30,31,33,35,37,39,41,43,45,47,50,52,55,57,60,63,65,68,71,74,77,80,83,87,90,93,97,101,105,108,112,116,121,125,129,134,139,143,148,153,159,164,169
diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp36.h b/spaghetti-monster/anduril/cfg-sofirn-sp36.h
index 11e3735..2d6717f 100644
--- a/spaghetti-monster/anduril/cfg-sofirn-sp36.h
+++ b/spaghetti-monster/anduril/cfg-sofirn-sp36.h
@@ -1,16 +1,37 @@
// Sofirn SP36 (small Q8) config options for Anduril
+// voltage readings were a little high with the Q8 value
+#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V, not 0.35V
+
#define FSM_BLF_Q8_DRIVER
#include "cfg-blf-q8.h"
-// stop panicking at ~50% power or ~2000 lm
+// the high button LED mode on this light uses too much power
+// off mode: low (1)
+// lockout: blinking (3)
+#ifdef INDICATOR_LED_DEFAULT_MODE
+#undef INDICATOR_LED_DEFAULT_MODE
+#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1)
+#endif
+
+// don't blink during the ramp; the button LED brightness is sufficient
+// to indicate which power channel(s) are being used
+#ifdef BLINK_AT_CHANNEL_BOUNDARIES
+#undef BLINK_AT_CHANNEL_BOUNDARIES
+#endif
+#ifdef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_CEILING
+#endif
+
+// stop panicking at ~60% power or ~3000 lm
#ifdef THERM_FASTER_LEVEL
#undef THERM_FASTER_LEVEL
#endif
-#define THERM_FASTER_LEVEL 125
+#define THERM_FASTER_LEVEL 130
// be extra-careful at high levels
-#ifndef THERM_HARD_TURBO_DROP
-#define THERM_HARD_TURBO_DROP
-#endif
+// (or not... this host seems to heat up pretty slowly)
+//#ifndef THERM_HARD_TURBO_DROP
+//#define THERM_HARD_TURBO_DROP
+//#endif
diff --git a/spaghetti-monster/baton/baton.c b/spaghetti-monster/baton/baton.c
index d4725ef..d138297 100644
--- a/spaghetti-monster/baton/baton.c
+++ b/spaghetti-monster/baton/baton.c
@@ -24,9 +24,9 @@
#include "spaghetti-monster.h"
// FSM states
-uint8_t off_state(EventPtr event, uint16_t arg);
-uint8_t steady_state(EventPtr event, uint16_t arg);
-uint8_t lockout_state(EventPtr event, uint16_t arg);
+uint8_t off_state(Event event, uint16_t arg);
+uint8_t steady_state(Event event, uint16_t arg);
+uint8_t lockout_state(Event event, uint16_t arg);
// brightness control
uint8_t memorized_level = 1;
@@ -47,7 +47,7 @@ void set_level(uint8_t lvl) {
PWM2_LVL = pwm2_levels[lvl];
}
-uint8_t off_state(EventPtr event, uint16_t arg) {
+uint8_t off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
go_to_standby = 1; // sleep while off (lower power use)
@@ -86,7 +86,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
-uint8_t steady_state(EventPtr event, uint16_t arg) {
+uint8_t steady_state(Event event, uint16_t arg) {
// turn LED on when we first enter the mode
if (event == EV_enter_state) {
// remember this level, unless it's moon or turbo
@@ -146,7 +146,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
-uint8_t lockout_state(EventPtr event, uint16_t arg) {
+uint8_t lockout_state(Event event, uint16_t arg) {
// stay asleep while locked
if (event == EV_tick) {
PWM1_LVL = 0; PWM2_LVL = 0; // make sure emitters are off
diff --git a/spaghetti-monster/darkhorse/darkhorse.c b/spaghetti-monster/darkhorse/darkhorse.c
index 97053b5..d76afc2 100644
--- a/spaghetti-monster/darkhorse/darkhorse.c
+++ b/spaghetti-monster/darkhorse/darkhorse.c
@@ -32,16 +32,16 @@
#include "spaghetti-monster.h"
// FSM states
-uint8_t off_state(EventPtr event, uint16_t arg);
-uint8_t low_mode_state(EventPtr event, uint16_t arg);
-uint8_t med_mode_state(EventPtr event, uint16_t arg);
-uint8_t hi_mode_state(EventPtr event, uint16_t arg);
-uint8_t strobe_beacon_state(EventPtr event, uint16_t arg);
+uint8_t off_state(Event event, uint16_t arg);
+uint8_t low_mode_state(Event event, uint16_t arg);
+uint8_t med_mode_state(Event event, uint16_t arg);
+uint8_t hi_mode_state(Event event, uint16_t arg);
+uint8_t strobe_beacon_state(Event event, uint16_t arg);
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg);
+uint8_t battcheck_state(Event event, uint16_t arg);
#endif
// Not a FSM state, just handles stuff common to all low/med/hi states
-uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes);
+uint8_t any_mode_state(Event event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes);
void load_config();
void save_config();
@@ -89,7 +89,7 @@ inline void set_med_mode() { set_any_mode(M1, M2, med_modes); }
inline void set_hi_mode() { set_any_mode(H1, H2, hi_modes); }
-uint8_t off_state(EventPtr event, uint16_t arg) {
+uint8_t off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
set_level(0);
@@ -163,7 +163,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
-uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes) {
+uint8_t any_mode_state(Event event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes) {
// turn on LED when entering the mode
if (event == EV_enter_state) {
set_any_mode(*primary, *secondary, modes);
@@ -236,27 +236,27 @@ uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *
return EVENT_NOT_HANDLED;
}
-uint8_t low_mode_state(EventPtr event, uint16_t arg) {
+uint8_t low_mode_state(Event event, uint16_t arg) {
return any_mode_state(event, arg, &L1, &L2, low_modes);
}
-uint8_t med_mode_state(EventPtr event, uint16_t arg) {
+uint8_t med_mode_state(Event event, uint16_t arg) {
return any_mode_state(event, arg, &M1, &M2, med_modes);
}
-uint8_t hi_mode_state(EventPtr event, uint16_t arg) {
+uint8_t hi_mode_state(Event event, uint16_t arg) {
return any_mode_state(event, arg, &H1, &H2, hi_modes);
}
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg) {
+uint8_t battcheck_state(Event event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
#endif
-uint8_t strobe_beacon_state(EventPtr event, uint16_t arg) {
+uint8_t strobe_beacon_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index ee7bc97..72216ae 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -20,25 +20,8 @@
#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<EV_MAX_LEN) && (a[i] == pgm_read_byte(b+i)); i++) {
- // end of zero-terminated sequence
- if (a[i] == 0) return 1;
- }
- // if we ever fall out, that means something was different
- // (or the sequence is too long)
- return 0;
-}
-
void empty_event_sequence() {
- for(uint8_t i=0; i<EV_MAX_LEN; i++) current_event[i] = 0;
+ current_event = EV_none;
// when the user completes an input sequence, interrupt any running timers
// to cancel any delays currently in progress
// This eliminates a whole bunch of extra code:
@@ -49,46 +32,41 @@ void empty_event_sequence() {
uint8_t push_event(uint8_t ev_type) {
ticks_since_last_event = 0; // something happened
- uint8_t i;
- //uint8_t prev_event = 0; // never push the same event twice in a row
- for(i=0; current_event[i] && (i<EV_MAX_LEN); i++) {
- // this doesn't actually seem to be necessary any more...
- //prev_event = current_event[i];
+
+ // only click events are sent to this function
+ current_event |= B_CLICK;
+
+ // handle button presses
+ if (ev_type == B_PRESS) {
+ // set press flag
+ current_event |= B_PRESS;
+ // increase click counter
+ if ((current_event & B_COUNT) < (B_COUNT-1)) {
+ current_event ++;
+ }
+ return 1; // event pushed, even if max clicks already reached
+ // (will just repeat the max over and over)
}
- //if ((i < EV_MAX_LEN) && (prev_event != ev_type)) {
- //if (prev_event != ev_type) {
- if (i < EV_MAX_LEN) {
- current_event[i] = ev_type;
+ // handle button releases
+ else if (ev_type == B_RELEASE) {
+ // clear the press flag
+ current_event &= (~B_PRESS);
+ // if a "hold" event just ended, set the timeout flag
+ // to indicate that the event is done and can be cleared
+ if (current_event & B_HOLD) { current_event |= B_TIMEOUT; }
return 1; // event pushed
- } else {
- // TODO: ... something?
}
- return 0; // no event pushed
-}
-// find and return last action in the current event sequence
-/*
-uint8_t last_event(uint8_t offset) {
- uint8_t i;
- for(i=0; current_event[i] && (i<EV_MAX_LEN); i++);
- if (i == EV_MAX_LEN) return current_event[EV_MAX_LEN-offset];
- else if (i >= offset) return current_event[i-offset];
- return 0;
-}
-*/
+ return 0; // unexpected event type
-inline uint8_t last_event_num() {
- uint8_t i;
- for(i=0; current_event[i] && (i<EV_MAX_LEN); i++);
- return i;
}
-void append_emission(EventPtr event, uint16_t arg) {
+void append_emission(Event event, uint16_t arg) {
uint8_t i;
// find last entry
for(i=0;
- (i<EMISSION_QUEUE_LEN) && (emissions[i].event != NULL);
+ (i<EMISSION_QUEUE_LEN) && (emissions[i].event != EV_none);
i++) { }
// add new entry
if (i < EMISSION_QUEUE_LEN) {
@@ -105,12 +83,12 @@ void delete_first_emission() {
emissions[i].event = emissions[i+1].event;
emissions[i].arg = emissions[i+1].arg;
}
- emissions[i].event = NULL;
+ emissions[i].event = EV_none;
emissions[i].arg = 0;
}
void process_emissions() {
- while (emissions[0].event != NULL) {
+ while (emissions[0].event != EV_none) {
emit_now(emissions[0].event, emissions[0].arg);
delete_first_emission();
}
@@ -202,7 +180,7 @@ uint8_t nice_delay_s() {
*/
// Call stacked callbacks for the given event until one handles it.
-uint8_t emit_now(EventPtr event, uint16_t arg) {
+uint8_t emit_now(Event event, uint16_t arg) {
for(int8_t i=state_stack_len-1; i>=0; i--) {
uint8_t err = state_stack[i](event, arg);
if (! err) return 0;
@@ -210,26 +188,15 @@ uint8_t emit_now(EventPtr event, uint16_t arg) {
return 1; // event not handled
}
-void emit(EventPtr event, uint16_t arg) {
+void emit(Event 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;
+ ticks_since_last_event = arg;
+ emit(current_event, arg);
}
#endif
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h
index 0212c2c..0ebcfd0 100644
--- a/spaghetti-monster/fsm-events.h
+++ b/spaghetti-monster/fsm-events.h
@@ -23,10 +23,9 @@
#include <avr/pgmspace.h>
// typedefs
-typedef PROGMEM const uint8_t Event;
-typedef Event * EventPtr;
+typedef uint8_t Event;
typedef struct Emission {
- EventPtr event;
+ Event event;
uint16_t arg;
} Emission;
@@ -35,12 +34,7 @@ typedef struct Emission {
#define MISCHIEF_MANAGED EVENT_HANDLED
#define MISCHIEF_NOT_MANAGED EVENT_NOT_HANDLED
-#ifndef MAX_CLICKS
-#define MAX_CLICKS 4
-#endif
-
-#define EV_MAX_LEN ((MAX_CLICKS*2)+3)
-uint8_t current_event[EV_MAX_LEN];
+Event current_event;
// at 0.016 ms per tick, 255 ticks = 4.08 s
static volatile uint16_t ticks_since_last_event = 0;
@@ -52,508 +46,174 @@ static volatile uint16_t ticks_since_last_event = 0;
#define RELEASE_TIMEOUT 24
#endif
-#define A_ENTER_STATE 1
-#define A_LEAVE_STATE 2
-#define A_REENTER_STATE 3
-#define A_TICK 4
-#define A_SLEEP_TICK 5
-#define A_PRESS 6
-#define A_HOLD 7
-#define A_RELEASE 8
-#define A_RELEASE_TIMEOUT 9
-#define A_OVERHEATING 10
-#define A_UNDERHEATING 11
-#define A_VOLTAGE_LOW 12
-//#define A_VOLTAGE_CRITICAL 13
-#define A_DEBUG 255 // test event for debugging
+/* Event structure
+ * Bit 7: 1 for a button input event, 0 for all others.
+ * If bit 7 is 1:
+ * Bits 0,1,2,3: Click counter. Up to 15 clicks.
+ * Bit 4: 1 for a "press" event, 0 for a "release" event.
+ * Bit 5: 1 for a "hold" event, 0 otherwise.
+ * Bit 6: 1 for a "timeout" event, 0 otherwise.
+ * If bit 7 is 0:
+ * Sort of ad-hoc, shown in #defines below.
+ */
+
+// event masks / bits
+#define B_SYSTEM 0b00000000
+#define B_CLICK 0b10000000
+#define B_TIMEOUT 0b01000000
+#define B_HOLD 0b00100000
+#define B_PRESS 0b00010000
+#define B_RELEASE 0b00000000
+#define B_COUNT 0b00001111
+#define B_FLAGS 0b11110000
// Event types
-// TODO: make these progmem-only?
-Event EV_debug[] = {
- A_DEBUG,
- 0 } ;
-Event EV_enter_state[] = {
- A_ENTER_STATE,
- 0 } ;
-Event EV_leave_state[] = {
- A_LEAVE_STATE,
- 0 } ;
-Event EV_reenter_state[] = {
- A_REENTER_STATE,
- 0 } ;
-Event EV_tick[] = {
- A_TICK,
- 0 } ;
+#define EV_none 0
+
+// Events which aren't button presses
+#define EV_debug (B_SYSTEM|0b01111111)
+#define EV_enter_state (B_SYSTEM|0b00001000)
+#define EV_leave_state (B_SYSTEM|0b00001001)
+#define EV_reenter_state (B_SYSTEM|0b00001010)
+#define EV_tick (B_SYSTEM|0b00000001)
#ifdef TICK_DURING_STANDBY
-Event EV_sleep_tick[] = {
- A_SLEEP_TICK,
- 0 } ;
+#define EV_sleep_tick (B_SYSTEM|0b00000011)
#endif
#ifdef USE_LVP
-Event EV_voltage_low[] = {
- A_VOLTAGE_LOW,
- 0 } ;
+#define EV_voltage_low (B_SYSTEM|0b00000100)
#endif
#ifdef USE_THERMAL_REGULATION
-Event EV_temperature_high[] = {
- A_OVERHEATING,
- 0 } ;
-Event EV_temperature_low[] = {
- A_UNDERHEATING,
- 0 } ;
+#define EV_temperature_high (B_SYSTEM|0b00000101)
+#define EV_temperature_low (B_SYSTEM|0b00000110)
#endif
-Event EV_click1_press[] = {
- A_PRESS,
- 0 };
-// shouldn't normally happen, but UI might reset event while button is down
-// so a release with no recorded prior hold could be possible
-Event EV_release[] = {
- A_RELEASE,
- 0 };
-Event EV_click1_release[] = {
- A_PRESS,
- A_RELEASE,
- 0 };
+
+// Button press events
+
+// shouldn't normally happen, but UI might empty_event_sequence() while button
+// is down so a release with no recorded prior hold could be possible
+#define EV_release (B_CLICK|B_RELEASE|0)
+
+#define EV_click1_press (B_CLICK|B_PRESS|1)
+#define EV_click1_release (B_CLICK|B_RELEASE|1)
+#define EV_click1_complete (B_CLICK|B_TIMEOUT|1)
#define EV_1click EV_click1_complete
-Event EV_click1_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
+#define EV_click1_hold (B_CLICK|B_HOLD|B_PRESS|1)
+#define EV_click1_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|1)
#define EV_hold EV_click1_hold
-// FIXME: Should holds use "start+tick" or just "tick" with a tick number?
-// Or "start+tick" with a tick number?
-Event EV_click1_hold[] = {
- A_PRESS,
- A_HOLD,
- 0 };
-Event EV_click1_hold_release[] = {
- A_PRESS,
- A_HOLD,
- A_RELEASE,
- 0 };
-#if MAX_CLICKS >= 2
-Event EV_click2_press[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- 0 };
-Event EV_click2_hold[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_HOLD,
- 0 };
-Event EV_click2_hold_release[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_HOLD,
- A_RELEASE,
- 0 };
-Event EV_click2_release[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- 0 };
+
+#define EV_click2_press (B_CLICK|B_PRESS|2)
+#define EV_click2_release (B_CLICK|B_RELEASE|2)
+#define EV_click2_complete (B_CLICK|B_TIMEOUT|2)
#define EV_2clicks EV_click2_complete
-Event EV_click2_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif // MAX_CLICKS >= 2
-#if MAX_CLICKS >= 3
-Event EV_click3_press[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- 0 };
-Event EV_click3_hold[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_HOLD,
- 0 };
-Event EV_click3_hold_release[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_HOLD,
- A_RELEASE,
- 0 };
-Event EV_click3_release[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- 0 };
+#define EV_click2_hold (B_CLICK|B_HOLD|B_PRESS|2)
+#define EV_click2_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|2)
+
+#define EV_click3_press (B_CLICK|B_PRESS|3)
+#define EV_click3_release (B_CLICK|B_RELEASE|3)
+#define EV_click3_complete (B_CLICK|B_TIMEOUT|3)
#define EV_3clicks EV_click3_complete
-Event EV_click3_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif // MAX_CLICKS >= 3
-#if MAX_CLICKS >= 4
+#define EV_click3_hold (B_CLICK|B_HOLD|B_PRESS|3)
+#define EV_click3_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|3)
+
+#define EV_click4_press (B_CLICK|B_PRESS|4)
+#define EV_click4_release (B_CLICK|B_RELEASE|4)
+#define EV_click4_complete (B_CLICK|B_TIMEOUT|4)
#define EV_4clicks EV_click4_complete
-Event EV_click4_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 5
+#define EV_click4_hold (B_CLICK|B_HOLD|B_PRESS|4)
+#define EV_click4_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|4)
+
+#define EV_click5_press (B_CLICK|B_PRESS|5)
+#define EV_click5_release (B_CLICK|B_RELEASE|5)
+#define EV_click5_complete (B_CLICK|B_TIMEOUT|5)
#define EV_5clicks EV_click5_complete
-Event EV_click5_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 6
+#define EV_click5_hold (B_CLICK|B_HOLD|B_PRESS|5)
+#define EV_click5_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|5)
+
+#define EV_click6_press (B_CLICK|B_PRESS|6)
+#define EV_click6_release (B_CLICK|B_RELEASE|6)
+#define EV_click6_complete (B_CLICK|B_TIMEOUT|6)
#define EV_6clicks EV_click6_complete
-Event EV_click6_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 7
+#define EV_click6_hold (B_CLICK|B_HOLD|B_PRESS|6)
+#define EV_click6_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|6)
+
+#define EV_click7_press (B_CLICK|B_PRESS|7)
+#define EV_click7_release (B_CLICK|B_RELEASE|7)
+#define EV_click7_complete (B_CLICK|B_TIMEOUT|7)
#define EV_7clicks EV_click7_complete
-Event EV_click7_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 8
+#define EV_click7_hold (B_CLICK|B_HOLD|B_PRESS|7)
+#define EV_click7_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|7)
+
+#define EV_click8_press (B_CLICK|B_PRESS|8)
+#define EV_click8_release (B_CLICK|B_RELEASE|8)
+#define EV_click8_complete (B_CLICK|B_TIMEOUT|8)
#define EV_8clicks EV_click8_complete
-Event EV_click8_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 9
+#define EV_click8_hold (B_CLICK|B_HOLD|B_PRESS|8)
+#define EV_click8_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|8)
+
+#define EV_click9_press (B_CLICK|B_PRESS|9)
+#define EV_click9_release (B_CLICK|B_RELEASE|9)
+#define EV_click9_complete (B_CLICK|B_TIMEOUT|9)
#define EV_9clicks EV_click9_complete
-Event EV_click9_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 10
+#define EV_click9_hold (B_CLICK|B_HOLD|B_PRESS|9)
+#define EV_click9_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|9)
+
+#define EV_click10_press (B_CLICK|B_PRESS|10)
+#define EV_click10_release (B_CLICK|B_RELEASE|10)
+#define EV_click10_complete (B_CLICK|B_TIMEOUT|10)
#define EV_10clicks EV_click10_complete
-Event EV_click10_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 11
+#define EV_click10_hold (B_CLICK|B_HOLD|B_PRESS|10)
+#define EV_click10_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|10)
+
+#define EV_click11_press (B_CLICK|B_PRESS|11)
+#define EV_click11_release (B_CLICK|B_RELEASE|11)
+#define EV_click11_complete (B_CLICK|B_TIMEOUT|11)
#define EV_11clicks EV_click11_complete
-Event EV_click11_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 12
+#define EV_click11_hold (B_CLICK|B_HOLD|B_PRESS|11)
+#define EV_click11_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|11)
+
+#define EV_click12_press (B_CLICK|B_PRESS|12)
+#define EV_click12_release (B_CLICK|B_RELEASE|12)
+#define EV_click12_complete (B_CLICK|B_TIMEOUT|12)
#define EV_12clicks EV_click12_complete
-Event EV_click12_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 13
+#define EV_click12_hold (B_CLICK|B_HOLD|B_PRESS|12)
+#define EV_click12_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|12)
+
+#define EV_click13_press (B_CLICK|B_PRESS|13)
+#define EV_click13_release (B_CLICK|B_RELEASE|13)
+#define EV_click13_complete (B_CLICK|B_TIMEOUT|13)
#define EV_13clicks EV_click13_complete
-Event EV_click13_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-#if MAX_CLICKS >= 14
+#define EV_click13_hold (B_CLICK|B_HOLD|B_PRESS|13)
+#define EV_click13_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|13)
+
+#define EV_click14_press (B_CLICK|B_PRESS|14)
+#define EV_click14_release (B_CLICK|B_RELEASE|14)
+#define EV_click14_complete (B_CLICK|B_TIMEOUT|14)
#define EV_14clicks EV_click14_complete
-Event EV_click14_complete[] = {
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_PRESS,
- A_RELEASE,
- A_RELEASE_TIMEOUT,
- 0 };
-#endif
-// ... and so on
-
-// A list of button event types for easy iteration
-// TODO: make this progmem-only?
-EventPtr event_sequences[] = {
- EV_click1_press,
- EV_release,
- EV_click1_release,
- EV_click1_complete,
- EV_click1_hold,
- EV_click1_hold_release,
- #if MAX_CLICKS >= 2
- EV_click2_press,
- EV_click2_hold,
- EV_click2_hold_release,
- EV_click2_release,
- EV_click2_complete,
- #endif
- #if MAX_CLICKS >= 3
- EV_click3_press,
- EV_click3_hold,
- EV_click3_hold_release,
- EV_click3_release,
- EV_click3_complete,
- #endif
- #if MAX_CLICKS >= 4
- EV_click4_complete,
- #endif
- #if MAX_CLICKS >= 5
- EV_click5_complete,
- #endif
- #if MAX_CLICKS >= 6
- EV_click6_complete,
- #endif
- #if MAX_CLICKS >= 7
- EV_click7_complete,
- #endif
- #if MAX_CLICKS >= 8
- EV_click8_complete,
- #endif
- #if MAX_CLICKS >= 9
- EV_click9_complete,
- #endif
- #if MAX_CLICKS >= 10
- EV_click10_complete,
- #endif
- #if MAX_CLICKS >= 11
- EV_click11_complete,
- #endif
- #if MAX_CLICKS >= 12
- EV_click12_complete,
- #endif
- #if MAX_CLICKS >= 13
- EV_click13_complete,
- #endif
- #if MAX_CLICKS >= 14
- EV_click14_complete,
- #endif
- // ...
-};
-
-#define events_match(a,b) compare_event_sequences(a,b)
-// return 1 if (a == b), 0 otherwise
-uint8_t compare_event_sequences(uint8_t *a, const uint8_t *b);
+#define EV_click14_hold (B_CLICK|B_HOLD|B_PRESS|14)
+#define EV_click14_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|14)
+
+#define EV_click15_press (B_CLICK|B_PRESS|15)
+#define EV_click15_release (B_CLICK|B_RELEASE|15)
+#define EV_click15_complete (B_CLICK|B_TIMEOUT|15)
+#define EV_15clicks EV_click15_complete
+#define EV_click15_hold (B_CLICK|B_HOLD|B_PRESS|15)
+#define EV_click15_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|15)
+
+
void empty_event_sequence();
uint8_t push_event(uint8_t ev_type);
-// uint8_t last_event(uint8_t offset);
-inline uint8_t last_event_num();
#define EMISSION_QUEUE_LEN 16
// no comment about "volatile emissions"
volatile Emission emissions[EMISSION_QUEUE_LEN];
-void append_emission(EventPtr event, uint16_t arg);
+void append_emission(Event 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);
+uint8_t emit_now(Event event, uint16_t arg);
+void emit(Event event, uint16_t arg);
void emit_current_event(uint16_t arg);
uint8_t nice_delay_ms(uint16_t ms);
diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c
index a79572d..acb627d 100644
--- a/spaghetti-monster/fsm-pcint.c
+++ b/spaghetti-monster/fsm-pcint.c
@@ -75,9 +75,9 @@ void PCINT_inner(uint8_t pressed) {
uint8_t pushed;
if (pressed) {
- pushed = push_event(A_PRESS);
+ pushed = push_event(B_PRESS);
} else {
- pushed = push_event(A_RELEASE);
+ pushed = push_event(B_RELEASE);
}
// check if sequence matches any defined sequences
diff --git a/spaghetti-monster/fsm-states.c b/spaghetti-monster/fsm-states.c
index 09ae804..f91dc4b 100644
--- a/spaghetti-monster/fsm-states.c
+++ b/spaghetti-monster/fsm-states.c
@@ -32,7 +32,7 @@
// TODO: function to call stacked callbacks until one returns "handled"
void _set_state(StatePtr new_state, uint16_t arg,
- EventPtr exit_event, EventPtr enter_event) {
+ Event exit_event, Event enter_event) {
// call old state-exit hook (don't use stack)
if (current_state != NULL) current_state(exit_event, arg);
// set new state
@@ -82,7 +82,7 @@ uint8_t set_state(StatePtr new_state, uint16_t arg) {
#ifndef DONT_USE_DEFAULT_STATE
// bottom state on stack
// handles default actions for LVP, thermal regulation, etc
-uint8_t default_state(EventPtr event, uint16_t arg) {
+uint8_t default_state(Event event, uint16_t arg) {
if (0) {} // this should get compiled out
#ifdef USE_LVP
diff --git a/spaghetti-monster/fsm-states.h b/spaghetti-monster/fsm-states.h
index 6e4a2a0..7d9361b 100644
--- a/spaghetti-monster/fsm-states.h
+++ b/spaghetti-monster/fsm-states.h
@@ -23,7 +23,7 @@
#include "fsm-adc.h"
// typedefs
-typedef uint8_t State(EventPtr event, uint16_t arg);
+typedef uint8_t State(Event event, uint16_t arg);
typedef State * StatePtr;
// top of the stack
@@ -36,12 +36,12 @@ StatePtr state_stack[STATE_STACK_SIZE];
uint8_t state_stack_len = 0;
void _set_state(StatePtr new_state, uint16_t arg,
- EventPtr exit_event, EventPtr enter_event);
+ Event exit_event, Event enter_event);
int8_t push_state(StatePtr new_state, uint16_t arg);
StatePtr pop_state();
uint8_t set_state(StatePtr new_state, uint16_t arg);
#ifndef DONT_USE_DEFAULT_STATE
-uint8_t default_state(EventPtr event, uint16_t arg);
+uint8_t default_state(Event event, uint16_t arg);
#endif
#endif
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index e8419bc..d5bbdb9 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -64,7 +64,9 @@ ISR(WDT_vect) {
// handle standby mode specially
if (go_to_standby) {
// emit a halfsleep tick, and process it
- emit(EV_sleep_tick, sleep_counter++);
+ emit(EV_sleep_tick, sleep_counter);
+ // wrap around from 65535 to 32768, not 0
+ sleep_counter = (sleep_counter + 1) | (sleep_counter & 0x8000);
process_emissions();
return;
}
@@ -76,54 +78,57 @@ ISR(WDT_vect) {
uint8_t pressed = button_is_pressed();
if (was_pressed != pressed) PCINT_inner(pressed);
- //if (ticks_since_last_event < 0xff) ticks_since_last_event ++;
+ // 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_event = (ticks_since_last_event + 1) \
- | (ticks_since_last_event & 0x8000);
+ //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
- // preload recent events
- uint8_t le_num = last_event_num();
- uint8_t last_event = 0;
- uint8_t prev_event = 0;
- if (le_num >= 1) last_event = current_event[le_num-1];
- if (le_num >= 2) prev_event = current_event[le_num-2];
-
// callback on each timer tick
- if (last_event == A_HOLD) {
+ if ((current_event & B_FLAGS) == (B_CLICK | B_HOLD | B_PRESS)) {
emit(EV_tick, 0); // override tick counter while holding button
}
else {
- emit(EV_tick, ticks_since_last_event);
+ emit(EV_tick, ticks_since_last);
}
// user held button long enough to count as a long click?
- if (last_event == A_PRESS) {
- if (ticks_since_last_event >= HOLD_TIMEOUT) {
- push_event(A_HOLD);
- emit_current_event(0);
+ if (current_event & B_PRESS) {
+ // during a "hold", send a hold event each tick, with a timer
+ if (current_event & B_HOLD) {
+ emit_current_event(ticks_since_last);
+ }
+ // has button been down long enough to become a "hold"?
+ else {
+ if (ticks_since_last >= HOLD_TIMEOUT) {
+ //ticks_since_last_event = 0;
+ current_event |= B_HOLD;
+ emit_current_event(0);
+ }
}
}
- // user is still holding button, so tick
- else if (last_event == A_HOLD) {
- emit_current_event(ticks_since_last_event);
- }
-
- // detect completed button presses with expired timeout
- else if (last_event == A_RELEASE) {
+ // event in progress, but button not currently down
+ else if (current_event) {
+ // "hold" event just ended
// no timeout required when releasing a long-press
// TODO? move this logic to PCINT() and simplify things here?
- if (prev_event == A_HOLD) {
+ if (current_event & B_HOLD) {
//emit_current_event(0); // should have been emitted by PCINT
empty_event_sequence();
}
// end and clear event after release timeout
- else if (ticks_since_last_event >= RELEASE_TIMEOUT) {
- push_event(A_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();
}
diff --git a/spaghetti-monster/meteor/meteor.c b/spaghetti-monster/meteor/meteor.c
index b2467d7..a50b034 100644
--- a/spaghetti-monster/meteor/meteor.c
+++ b/spaghetti-monster/meteor/meteor.c
@@ -1,5 +1,6 @@
/*
* Meteor: Meteor M43 clone UI for SpaghettiMonster.
+ * (in progress, not really in a usable state yet)
*
* Copyright (C) 2017 Selene ToyKeeper
*
@@ -29,26 +30,25 @@
#define DONT_DELAY_AFTER_BATTCHECK
//#define USE_EEPROM
//#define EEPROM_BYTES 5
-#define MAX_CLICKS 11
#include "spaghetti-monster.h"
// FSM states
-uint8_t base_off_state(EventPtr event, uint16_t arg);
-uint8_t ui1_off_state(EventPtr event, uint16_t arg);
-uint8_t ui2_off_state(EventPtr event, uint16_t arg);
-uint8_t ui3_off_state(EventPtr event, uint16_t arg);
-uint8_t base_on_state(EventPtr event, uint16_t arg, uint8_t *mode, uint8_t *group);
-uint8_t ui1_on_state(EventPtr event, uint16_t arg);
-uint8_t ui2_on_state(EventPtr event, uint16_t arg);
-uint8_t ui3_on_state(EventPtr event, uint16_t arg);
-uint8_t beacon_state(EventPtr event, uint16_t arg);
-uint8_t battcheck_state(EventPtr event, uint16_t arg);
-uint8_t strobe_state(EventPtr event, uint16_t arg);
-uint8_t biking_state(EventPtr event, uint16_t arg);
-uint8_t lockout_state(EventPtr event, uint16_t arg);
-uint8_t momentary_state(EventPtr event, uint16_t arg);
+uint8_t base_off_state(Event event, uint16_t arg);
+uint8_t ui1_off_state(Event event, uint16_t arg);
+uint8_t ui2_off_state(Event event, uint16_t arg);
+uint8_t ui3_off_state(Event event, uint16_t arg);
+uint8_t base_on_state(Event event, uint16_t arg, uint8_t *mode, uint8_t *group);
+uint8_t ui1_on_state(Event event, uint16_t arg);
+uint8_t ui2_on_state(Event event, uint16_t arg);
+uint8_t ui3_on_state(Event event, uint16_t arg);
+uint8_t beacon_state(Event event, uint16_t arg);
+uint8_t battcheck_state(Event event, uint16_t arg);
+uint8_t strobe_state(Event event, uint16_t arg);
+uint8_t biking_state(Event event, uint16_t arg);
+uint8_t lockout_state(Event event, uint16_t arg);
+uint8_t momentary_state(Event event, uint16_t arg);
// Not a FSM state, just handles stuff common to all low/med/hi states
-uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes);
+uint8_t any_mode_state(Event event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes);
#ifdef USE_EEPROM
void load_config();
@@ -99,7 +99,7 @@ void blink_fast() {
set_level(0);
}
-uint8_t base_off_state(EventPtr event, uint16_t arg) {
+uint8_t base_off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
set_level(0);
@@ -154,7 +154,7 @@ uint8_t base_off_state(EventPtr event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
-uint8_t ui1_off_state(EventPtr event, uint16_t arg) {
+uint8_t ui1_off_state(Event event, uint16_t arg) {
UI = 1;
if (event == EV_enter_state) {
return EVENT_HANDLED;
@@ -187,7 +187,7 @@ uint8_t ui1_off_state(EventPtr event, uint16_t arg) {
return base_off_state(event, arg);
}
-uint8_t ui2_off_state(EventPtr event, uint16_t arg) {
+uint8_t ui2_off_state(Event event, uint16_t arg) {
UI = 2;
if (event == EV_enter_state) {
return EVENT_HANDLED;
@@ -220,7 +220,7 @@ uint8_t ui2_off_state(EventPtr event, uint16_t arg) {
return base_off_state(event, arg);
}
-uint8_t ui3_off_state(EventPtr event, uint16_t arg) {
+uint8_t ui3_off_state(Event event, uint16_t arg) {
UI = 3;
if (event == EV_enter_state) {
return EVENT_HANDLED;
@@ -259,7 +259,7 @@ uint8_t ui3_off_state(EventPtr event, uint16_t arg) {
return base_off_state(event, arg);
}
-uint8_t base_on_state(EventPtr event, uint16_t arg, uint8_t *mode, uint8_t *group) {
+uint8_t base_on_state(Event event, uint16_t arg, uint8_t *mode, uint8_t *group) {
// 1 click: off
if (event == EV_1click) {
set_state(base_off_state, 0);
@@ -289,7 +289,7 @@ uint8_t base_on_state(EventPtr event, uint16_t arg, uint8_t *mode, uint8_t *grou
return EVENT_NOT_HANDLED;
}
-uint8_t ui1_on_state(EventPtr event, uint16_t arg) {
+uint8_t ui1_on_state(Event event, uint16_t arg) {
// turn on LED when entering the mode
static uint8_t *mode = &UI1_mode1;
static uint8_t *group = UI1_group1;
@@ -328,7 +328,7 @@ uint8_t ui1_on_state(EventPtr event, uint16_t arg) {
return base_on_state(event, arg, mode, group);
}
-uint8_t ui2_on_state(EventPtr event, uint16_t arg) {
+uint8_t ui2_on_state(Event event, uint16_t arg) {
// turn on LED when entering the mode
static uint8_t *mode = &UI2_mode1;
static uint8_t *group = UI2_group1;
@@ -377,7 +377,7 @@ uint8_t ui2_on_state(EventPtr event, uint16_t arg) {
return base_on_state(event, arg, mode, group);
}
-uint8_t ui3_on_state(EventPtr event, uint16_t arg) {
+uint8_t ui3_on_state(Event event, uint16_t arg) {
// turn on LED when entering the mode
static uint8_t *mode = &UI3_mode1;
if (event == EV_enter_state) {
@@ -424,7 +424,7 @@ uint8_t ui3_on_state(EventPtr event, uint16_t arg) {
}
-uint8_t blinky_base_state(EventPtr event, uint16_t arg) {
+uint8_t blinky_base_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(base_off_state, 0);
@@ -433,27 +433,27 @@ uint8_t blinky_base_state(EventPtr event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
-uint8_t beacon_state(EventPtr event, uint16_t arg) {
+uint8_t beacon_state(Event event, uint16_t arg) {
return blinky_base_state(event, arg);
}
-uint8_t battcheck_state(EventPtr event, uint16_t arg) {
+uint8_t battcheck_state(Event event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
-uint8_t strobe_state(EventPtr event, uint16_t arg) {
+uint8_t strobe_state(Event event, uint16_t arg) {
return blinky_base_state(event, arg);
}
-uint8_t biking_state(EventPtr event, uint16_t arg) {
+uint8_t biking_state(Event event, uint16_t arg) {
return blinky_base_state(event, arg);
}
-uint8_t lockout_state(EventPtr event, uint16_t arg) {
+uint8_t lockout_state(Event event, uint16_t arg) {
return blinky_base_state(event, arg);
}
-uint8_t momentary_state(EventPtr event, uint16_t arg) {
+uint8_t momentary_state(Event event, uint16_t arg) {
return blinky_base_state(event, arg);
}
diff --git a/spaghetti-monster/momentary/momentary.c b/spaghetti-monster/momentary/momentary.c
index d4ac1db..0372b3d 100644
--- a/spaghetti-monster/momentary/momentary.c
+++ b/spaghetti-monster/momentary/momentary.c
@@ -40,7 +40,7 @@ void light_off() {
PWM2_LVL = 0;
}
-uint8_t momentary_state(EventPtr event, uint16_t arg) {
+uint8_t momentary_state(Event event, uint16_t arg) {
if (event == EV_click1_press) {
brightness = 255;
diff --git a/spaghetti-monster/ramping-ui/ramping-ui.c b/spaghetti-monster/ramping-ui/ramping-ui.c
index e6f571d..234cdf4 100644
--- a/spaghetti-monster/ramping-ui/ramping-ui.c
+++ b/spaghetti-monster/ramping-ui/ramping-ui.c
@@ -31,12 +31,12 @@
#include "spaghetti-monster.h"
// FSM states
-uint8_t off_state(EventPtr event, uint16_t arg);
-uint8_t steady_state(EventPtr event, uint16_t arg);
-uint8_t strobe_state(EventPtr event, uint16_t arg);
+uint8_t off_state(Event event, uint16_t arg);
+uint8_t steady_state(Event event, uint16_t arg);
+uint8_t strobe_state(Event event, uint16_t arg);
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg);
-uint8_t tempcheck_state(EventPtr event, uint16_t arg);
+uint8_t battcheck_state(Event event, uint16_t arg);
+uint8_t tempcheck_state(Event event, uint16_t arg);
#endif
// brightness control
@@ -54,7 +54,7 @@ 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) {
+uint8_t off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
set_level(0);
@@ -121,7 +121,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
-uint8_t steady_state(EventPtr event, uint16_t arg) {
+uint8_t steady_state(Event event, uint16_t arg) {
// turn LED on when we first enter the mode
if (event == EV_enter_state) {
// remember this level, unless it's moon or turbo
@@ -243,7 +243,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
}
-uint8_t strobe_state(EventPtr event, uint16_t arg) {
+uint8_t strobe_state(Event event, uint16_t arg) {
if (event == EV_enter_state) {
return MISCHIEF_MANAGED;
}
@@ -281,7 +281,7 @@ uint8_t strobe_state(EventPtr event, uint16_t arg) {
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg) {
+uint8_t battcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -295,7 +295,7 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
-uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
+uint8_t tempcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c
index 2aeeddf..4142121 100644
--- a/spaghetti-monster/rampingios/rampingiosv3.c
+++ b/spaghetti-monster/rampingios/rampingiosv3.c
@@ -112,9 +112,10 @@
/********* Configure SpaghettiMonster *********/
#define USE_DELAY_ZERO
#define USE_RAMPING
+#ifndef RAMP_LENGTH
#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file
+#endif
#define USE_BATTCHECK
-#define MAX_CLICKS 10
#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending
#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency
@@ -141,34 +142,34 @@
// FSM states
-uint8_t off_state(EventPtr event, uint16_t arg);
+uint8_t off_state(Event event, uint16_t arg);
// simple numeric entry config menu
-uint8_t config_state_base(EventPtr event, uint16_t arg,
+uint8_t config_state_base(Event event, uint16_t arg,
uint8_t num_config_steps,
void (*savefunc)());
#define MAX_CONFIG_VALUES 3
uint8_t config_state_values[MAX_CONFIG_VALUES];
// ramping mode and its related config mode
-uint8_t steady_state(EventPtr event, uint16_t arg);
-uint8_t ramp_config_state(EventPtr event, uint16_t arg);
+uint8_t steady_state(Event event, uint16_t arg);
+uint8_t ramp_config_state(Event event, uint16_t arg);
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg);
+uint8_t battcheck_state(Event event, uint16_t arg);
#endif
#ifdef USE_THERMAL_REGULATION
-uint8_t tempcheck_state(EventPtr event, uint16_t arg);
-uint8_t thermal_config_state(EventPtr event, uint16_t arg);
+uint8_t tempcheck_state(Event event, uint16_t arg);
+uint8_t thermal_config_state(Event event, uint16_t arg);
#endif
// beacon mode and its related config mode
-uint8_t beacon_state(EventPtr event, uint16_t arg);
-uint8_t beacon_config_state(EventPtr event, uint16_t arg);
+uint8_t beacon_state(Event event, uint16_t arg);
+uint8_t beacon_config_state(Event event, uint16_t arg);
// soft lockout
#define MOON_DURING_LOCKOUT_MODE
-uint8_t lockout_state(EventPtr event, uint16_t arg);
+uint8_t lockout_state(Event event, uint16_t arg);
// momentary / signalling mode
-uint8_t momentary_state(EventPtr event, uint16_t arg);
+uint8_t momentary_state(Event event, uint16_t arg);
// general helper function for config modes
-uint8_t number_entry_state(EventPtr event, uint16_t arg);
+uint8_t number_entry_state(Event event, uint16_t arg);
// return value from number_entry_state()
volatile uint8_t number_entry_value;
@@ -177,7 +178,7 @@ void blink_confirm(uint8_t num);
void indicator_blink(uint8_t arg);
#endif
#ifdef USE_INDICATOR_LED
-uint8_t auxled_next_state(EventPtr event, uint16_t arg);
+uint8_t auxled_next_state(Event event, uint16_t arg);
#endif
// remember stuff even after battery was changed
@@ -246,7 +247,7 @@ uint8_t target_level = 0;
volatile uint8_t beacon_seconds = 2;
-uint8_t off_state(EventPtr event, uint16_t arg) {
+uint8_t off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if (event == EV_enter_state) {
set_level(0);
@@ -371,7 +372,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
-uint8_t steady_state(EventPtr event, uint16_t arg) {
+uint8_t steady_state(Event event, uint16_t arg) {
uint8_t mode_min = ramp_smooth_floor;
uint8_t mode_max = ramp_smooth_ceil;
uint8_t ramp_step_size = 1;
@@ -677,7 +678,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg) {
+uint8_t battcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -694,7 +695,7 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
-uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
+uint8_t tempcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -710,7 +711,7 @@ uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
#endif
-uint8_t beacon_state(EventPtr event, uint16_t arg) {
+uint8_t beacon_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -727,29 +728,24 @@ uint8_t beacon_state(EventPtr event, uint16_t arg) {
}
-uint8_t lockout_state(EventPtr event, uint16_t arg) {
+uint8_t lockout_state(Event event, uint16_t arg) {
#ifdef MOON_DURING_LOCKOUT_MODE
// momentary(ish) moon mode during lockout
- // not all presses will be counted;
- // it depends on what is in the master event_sequences table
- uint8_t last = 0;
- for(uint8_t i=0; pgm_read_byte(event + i) && (i<EV_MAX_LEN); i++)
- last = pgm_read_byte(event + i);
- if (arg == 0) { // Only turn on/off when button state changes
- if ((last == A_PRESS) || (last == A_HOLD)) {
- #ifdef LOCKOUT_MOON_LOWEST
- // Use lowest moon configured
- uint8_t lvl = ramp_smooth_floor;
- if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
- set_level(lvl);
- #else
- // Use moon from current ramp
- set_level(nearest_level(1));
- #endif
- }
- else if ((last == A_RELEASE) || (last == A_RELEASE_TIMEOUT)) {
- set_level(0);
- }
+ // button is being held
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
+ #ifdef LOCKOUT_MOON_LOWEST
+ // Use lowest moon configured
+ uint8_t lvl = ramp_smooth_floor;
+ if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
+ set_level(lvl);
+ #else
+ // Use moon from current ramp
+ set_level(nearest_level(1));
+ #endif
+ }
+ // button was released
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ set_level(0);
}
#endif
@@ -789,6 +785,9 @@ uint8_t lockout_state(EventPtr event, uint16_t arg) {
#else
mode = (mode + 1) % 3;
#endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03);
indicator_led(mode);
save_config();
@@ -807,7 +806,7 @@ uint8_t lockout_state(EventPtr event, uint16_t arg) {
#ifdef USE_INDICATOR_LED
-uint8_t auxled_next_state(EventPtr event, uint16_t arg) {
+uint8_t auxled_next_state(Event event, uint16_t arg) {
if (event == EV_enter_state) {
uint8_t mode = indicator_led_mode & 3;
#ifdef TICK_DURING_STANDBY
@@ -815,6 +814,9 @@ uint8_t auxled_next_state(EventPtr event, uint16_t arg) {
#else
mode = (mode + 1) % 3;
#endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
indicator_led_mode = mode + (indicator_led_mode & 0b00001100);
indicator_led(mode);
save_config();
@@ -830,19 +832,19 @@ uint8_t auxled_next_state(EventPtr event, uint16_t arg) {
#endif
-uint8_t momentary_state(EventPtr event, uint16_t arg) {
+uint8_t momentary_state(Event event, uint16_t arg) {
// TODO: momentary strobe here? (for light painting)
- if (event == EV_click1_press) {
+
+ // light up when the button is pressed; go dark otherwise
+ // button is being held
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
set_level(memorized_level);
- empty_event_sequence(); // don't attempt to parse multiple clicks
return MISCHIEF_MANAGED;
}
-
- else if (event == EV_release) {
+ // button was released
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
set_level(0);
- empty_event_sequence(); // don't attempt to parse multiple clicks
//go_to_standby = 1; // sleep while light is off
- // TODO: lighted button should use lockout config?
return MISCHIEF_MANAGED;
}
@@ -854,6 +856,7 @@ uint8_t momentary_state(EventPtr event, uint16_t arg) {
else if ((event == EV_tick) && (actual_level == 0)) {
if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
go_to_standby = 1; // sleep while light is off
+ // TODO: lighted button should use lockout config?
}
return MISCHIEF_MANAGED;
}
@@ -863,7 +866,7 @@ uint8_t momentary_state(EventPtr event, uint16_t arg) {
// ask the user for a sequence of numbers, then save them and return to caller
-uint8_t config_state_base(EventPtr event, uint16_t arg,
+uint8_t config_state_base(Event event, uint16_t arg,
uint8_t num_config_steps,
void (*savefunc)()) {
static uint8_t config_step;
@@ -922,7 +925,7 @@ void ramp_config_save() {
}
}
-uint8_t ramp_config_state(EventPtr event, uint16_t arg) {
+uint8_t ramp_config_state(Event event, uint16_t arg) {
uint8_t num_config_steps;
num_config_steps = 2 + ramp_style;
return config_state_base(event, arg,
@@ -950,7 +953,7 @@ void thermal_config_save() {
if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
}
-uint8_t thermal_config_state(EventPtr event, uint16_t arg) {
+uint8_t thermal_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
2, thermal_config_save);
}
@@ -965,13 +968,13 @@ void beacon_config_save() {
}
}
-uint8_t beacon_config_state(EventPtr event, uint16_t arg) {
+uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
-uint8_t number_entry_state(EventPtr event, uint16_t arg) {
+uint8_t number_entry_state(Event event, uint16_t arg) {
static uint8_t value;
static uint8_t blinks_left;
static uint8_t entry_step;
diff --git a/spaghetti-monster/spaghetti-monster.txt b/spaghetti-monster/spaghetti-monster.txt
index 0401224..9e051f1 100644
--- a/spaghetti-monster/spaghetti-monster.txt
+++ b/spaghetti-monster/spaghetti-monster.txt
@@ -112,6 +112,11 @@ Event types:
entering the state. When 'arg' exceeds 65535, it wraps around
to 32768.
+ - EV_sleep_tick: This happens every 0.5s during standby, if
+ enabled at compile time. The 'arg' is the number of ticks since
+ entering the state. When 'arg' exceeds 65535, it wraps around
+ to 32768.
+
LVP and thermal regulation:
- EV_voltage_low: Sent whenever the input power drops below the
@@ -130,57 +135,81 @@ Event types:
Button presses:
- - EV_1click: The user clicked the e-switch, released it, and
- enough time passed that no more clicks were detected.
+ Button events can be referred to either by pre-defined symbols, or
+ by teasing out the flags manually. The structure of a button
+ event is as follows:
+
+ - Bit 7: 1 for button events, 0 otherwise.
+
+ - Bit 6: 1 for a "timeout" event (signals the end of a
+ sequence), or 0 otherwise.
+
+ - Bit 5: 1 for a "hold" event, 0 otherwise. This flag is only
+ necessary because, without it, it would be impossible to
+ distinguish between "click, click, timeout" and "click, hold,
+ release".
- - EV_2clicks: The user clicked and released the e-switch twice, then
- enough time passed that no more clicks were detected.
+ - Bit 4: 1 if button is currently pressed, 0 otherwise. Button
+ release events look just like button press events, except this
+ is not set.
- - EV_3clicks: The user clicked and released the e-switch three
- times, then enough time passed that no more clicks were detected.
+ - Bits 0,1,2,3: Counter for how many clicks there have been.
+ The first click is 1, second is 2, and it goes up to 15 clicks
+ in a row. Clicks after 15 are coded as 15.
- - EV_4clicks: The user clicked and released the e-switch four times,
- then enough time passed that no more clicks were detected.
+ The pre-defined button event symbols are like the following:
- - EV_click1_hold: The user pressed the button and is still holding
- it. The 'arg' indicates how many clock ticks since the "hold"
- state started.
+ - EV_click1_press: The user pressed the button, but no time has
+ passed since then.
- - EV_click1_hold_release: The user pressed the button, held it for a
- while, and then released it. No timeout is attempted after this.
+ - EV_click1_release: The user pressed and released the button,
+ but no time has passed since then.
- - EV_click2_hold: The user clicked once, then pressed the button and
- is still holding it. The 'arg' indicates how many clock ticks
- since the "hold" state started.
+ - EV_click1_complete: The user clicked the e-switch, released
+ it, and enough time passed that no more clicks were detected.
+ (a.k.a. EV_1click)
- - EV_click2_hold_release: The user clicked once, then pressed the
- button, held it for a while, and released it. No timeout is
- attempted after this.
+ - EV_click1_hold: The user pressed the button, and continued
+ holding it long enough to count as a "hold" event. This event
+ is sent once per timer tick as long as the button is held, and
+ the 'arg' value indicates how many timer ticks since the
+ button state went from 'press' to 'hold'.
- - EV_click1_press: The user pressed the button and it's still down.
- No time has yet passed.
+ - EV_click1_hold_release: The button was released at the end of
+ a "hold" event. This is the end of the input sequence,
+ because no timeout period is used after a hold.
- - EV_click1_release: The user quickly pressed and released the
- button. The click timeout has not yet expired, so they might
- still click again.
+ It's worth noting that a "hold" event can only happen at the
+ end of an input sequence, and the sequence will reset to empty
+ after the hold is released.
- - EV_click2_press: The user pressed the button, released it, pressed
- again, and it's still down. No time has yet passed since then.
+ If the user pressed the button more than once, events follow the
+ same pattern. These are the same as above, except with a full
+ short-press and release first.
- - EV_click2_release: The quickly pressed and released the button
- twice. The click timeout has not yet expired, so they might still
- click again.
+ - EV_click2_press
+ - EV_click2_release
+ - EV_click2_complete (a.k.a. EV_2clicks)
+ - EV_click2_hold
+ - EV_click2_hold_release
+
+ Each of the above patterns continues up to 15 clicks.
+
+ To match entire categories of events, use the bitmasks provided.
+ For example, to match button events where the button is down or
+ the button is up, the code would look like this:
+
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
+ // button is down (can be a press event or a hold event)
+ }
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ // button was just released
+ }
In theory, you could also define your own arbitrary event types, and
emit() them as necessary, and handle them in State functions the same
as any other event.
- One thing to note if you create your own Event types: The copy which
- gets sent to States must be in the 'event_sequences' array, meaning
- the State gets a const PROGMEM version of the Event. It cannot simply
- send the dynamic 'current_event' object, because it has probably
- already changed by the time the callback happens.
-
Cooperative multitasking:
@@ -287,10 +316,6 @@ Useful #defines:
becomes a "click" event? Basically, the maximum time between
clicks in a double-click or triple-click.
- - MAX_CLICKS N: Convenience define to limit the size of the
- recognized Event arrays. Click sequences longer than N won't be
- recognized or sent to State functions.
-
- USE_BATTCHECK: Enable the battcheck function. Also define one of
the following to select a display style:
diff --git a/spaghetti-monster/werner/README b/spaghetti-monster/werner/README
new file mode 100644
index 0000000..5fe392d
--- /dev/null
+++ b/spaghetti-monster/werner/README
@@ -0,0 +1,56 @@
+This is a Werner-style interface for dual-switch lights
+(e-switch + clicky switch). What that means is:
+
+While the clicky switch is off:
+
+ - Click the clicky switch: Turn on, at the last-used level. The clicky
+ switch works as a momentary mode.
+
+ - Click the clicky switch while holding the e-switch: Go into sort of a
+ utility mode.
+
+While on, in a normal steady mode:
+
+ - Click the clicky switch: Turn off.
+
+ - Click the e-switch: Brighter. One step per click.
+
+ - Hold the e-switch: Dimmer. Keep holding to go down multiple steps.
+
+While in standby, in utility mode:
+
+ - Click the e-switch: Turn on.
+
+ - Hold the e-switch: Turn on at lowest level.
+
+ - Double-click the e-switch: Turn on at highest level.
+
+ - Triple-click the e-switch: Battery check mode.
+
+ - Quad-click the e-switch: Ramp config mode.
+
+While in battery check mode:
+
+ - Click either switch: Turn off.
+
+ - Double-click the e-switch: Go to temperature check mode.
+
+While in temperature check mode:
+
+ - Click either switch: Turn off.
+
+ - Double-click the e-switch: Go to battery check mode.
+
+ - Quad-click the e-switch: Go to thermal config mode.
+
+Ramp config mode and thermal config mode work the same as in Anduril or
+RampingIOS V3. The options are:
+
+ - Ramp config mode:
+ 1. Floor level.
+ 2. Ceiling level.
+ 3. Number of steps.
+
+ - Thermal config mode:
+ 1. Calibrate sensor by entering current temperature in C.
+ 2. Set temperature limit to 30 C + N clicks.
diff --git a/spaghetti-monster/werner/build-all.sh b/spaghetti-monster/werner/build-all.sh
index 944b31d..43879bb 100755
--- a/spaghetti-monster/werner/build-all.sh
+++ b/spaghetti-monster/werner/build-all.sh
@@ -14,6 +14,6 @@ for TARGET in \
FW3A \
; do
echo "===== $TARGET ====="
- ../../../bin/build-85.sh "$UI" "-DFSM_${TARGET}_DRIVER"
+ ../../../bin/build.sh 85 "$UI" "-DFSM_${TARGET}_DRIVER"
mv -f "$UI".hex "$UI".$TARGET.hex
done
diff --git a/spaghetti-monster/werner/werner.c b/spaghetti-monster/werner/werner.c
index 3c55d98..b6cdf12 100644
--- a/spaghetti-monster/werner/werner.c
+++ b/spaghetti-monster/werner/werner.c
@@ -73,7 +73,6 @@
#define USE_RAMPING
#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file
#define USE_BATTCHECK
-#define MAX_CLICKS 4
#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending
#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency
@@ -92,26 +91,26 @@
// FSM states
-uint8_t off_state(EventPtr event, uint16_t arg);
+uint8_t off_state(Event event, uint16_t arg);
// simple numeric entry config menu
-uint8_t config_state_base(EventPtr event, uint16_t arg,
+uint8_t config_state_base(Event event, uint16_t arg,
uint8_t num_config_steps,
void (*savefunc)());
#define MAX_CONFIG_VALUES 3
uint8_t config_state_values[MAX_CONFIG_VALUES];
// ramping mode and its related config mode
-uint8_t steady_state(EventPtr event, uint16_t arg);
-uint8_t ramp_config_state(EventPtr event, uint16_t arg);
+uint8_t steady_state(Event event, uint16_t arg);
+uint8_t ramp_config_state(Event event, uint16_t arg);
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg);
+uint8_t battcheck_state(Event event, uint16_t arg);
#endif
#ifdef USE_THERMAL_REGULATION
-uint8_t tempcheck_state(EventPtr event, uint16_t arg);
-uint8_t thermal_config_state(EventPtr event, uint16_t arg);
+uint8_t tempcheck_state(Event event, uint16_t arg);
+uint8_t thermal_config_state(Event event, uint16_t arg);
#endif
// general helper function for config modes
-uint8_t number_entry_state(EventPtr event, uint16_t arg);
+uint8_t number_entry_state(Event event, uint16_t arg);
// return value from number_entry_state()
volatile uint8_t number_entry_value;
@@ -152,7 +151,7 @@ uint8_t target_level = 0;
#endif
-uint8_t off_state(EventPtr event, uint16_t arg) {
+uint8_t off_state(Event event, uint16_t arg) {
// turn emitter off when entering state
if ((event == EV_enter_state) || (event == EV_reenter_state)) {
// let the user know the power is connected
@@ -230,7 +229,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
-uint8_t steady_state(EventPtr event, uint16_t arg) {
+uint8_t steady_state(Event event, uint16_t arg) {
uint8_t mode_min = ramp_discrete_floor;
uint8_t mode_max = ramp_discrete_ceil;
uint8_t ramp_step_size = ramp_discrete_step_size;
@@ -375,7 +374,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
#ifdef USE_BATTCHECK
-uint8_t battcheck_state(EventPtr event, uint16_t arg) {
+uint8_t battcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -392,7 +391,7 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg) {
#endif
#ifdef USE_THERMAL_REGULATION
-uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
+uint8_t tempcheck_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
set_state(off_state, 0);
@@ -415,7 +414,7 @@ uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
// ask the user for a sequence of numbers, then save them and return to caller
-uint8_t config_state_base(EventPtr event, uint16_t arg,
+uint8_t config_state_base(Event event, uint16_t arg,
uint8_t num_config_steps,
void (*savefunc)()) {
static uint8_t config_step;
@@ -463,7 +462,7 @@ void ramp_config_save() {
if (val) ramp_discrete_steps = val;
}
-uint8_t ramp_config_state(EventPtr event, uint16_t arg) {
+uint8_t ramp_config_state(Event event, uint16_t arg) {
uint8_t num_config_steps;
num_config_steps = 3;
return config_state_base(event, arg,
@@ -491,14 +490,14 @@ void thermal_config_save() {
if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
}
-uint8_t thermal_config_state(EventPtr event, uint16_t arg) {
+uint8_t thermal_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
2, thermal_config_save);
}
#endif
-uint8_t number_entry_state(EventPtr event, uint16_t arg) {
+uint8_t number_entry_state(Event event, uint16_t arg) {
static uint8_t value;
static uint8_t blinks_left;
static uint8_t entry_step;
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.