diff options
| author | Selene ToyKeeper | 2017-08-19 17:20:46 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2017-08-19 17:20:46 -0600 |
| commit | 73a5a6974a98aa73ab392272b4d69d285c85dee5 (patch) | |
| tree | 8bbd44cd1875da1f1af81d5bcdc997015361fe19 /spaghetti-monster/fsm-events.h | |
| parent | Extra debouncing in PCINT (don't emit event if push was rejected). (diff) | |
| download | anduril-73a5a6974a98aa73ab392272b4d69d285c85dee5.tar.gz anduril-73a5a6974a98aa73ab392272b4d69d285c85dee5.tar.bz2 anduril-73a5a6974a98aa73ab392272b4d69d285c85dee5.zip | |
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
Diffstat (limited to 'spaghetti-monster/fsm-events.h')
| -rw-r--r-- | spaghetti-monster/fsm-events.h | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h new file mode 100644 index 0000000..434fa10 --- /dev/null +++ b/spaghetti-monster/fsm-events.h @@ -0,0 +1,197 @@ +/* + * fsm-events.h: Event-handling functions for SpaghettiMonster. + * + * Copyright (C) 2017 Selene ToyKeeper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef FSM_EVENTS_H +#define FSM_EVENTS_H + +#include <avr/pgmspace.h> + +// typedefs +typedef PROGMEM const uint8_t Event; +typedef Event * EventPtr; +typedef struct Emission { + EventPtr event; + uint16_t arg; +} Emission; + +#define EV_MAX_LEN 16 +uint8_t current_event[EV_MAX_LEN]; +// at 0.016 ms per tick, 255 ticks = 4.08 s +// TODO: 16 bits? +static volatile uint16_t ticks_since_last_event = 0; + +// timeout durations in ticks (each tick 1/60th s) +#define HOLD_TIMEOUT 24 +#define RELEASE_TIMEOUT 24 + +#define A_ENTER_STATE 1 +#define A_LEAVE_STATE 2 +#define A_TICK 3 +#define A_PRESS 4 +#define A_HOLD 5 +#define A_RELEASE 6 +#define A_RELEASE_TIMEOUT 7 +// TODO: add events for over/under-heat conditions (with parameter for severity) +#define A_OVERHEATING 8 +#define A_UNDERHEATING 9 +// TODO: add events for low voltage conditions +#define A_VOLTAGE_LOW 10 +//#define A_VOLTAGE_CRITICAL 11 +#define A_DEBUG 255 // test event for debugging + +// Event types +Event EV_debug[] = { + A_DEBUG, + 0 } ; +Event EV_enter_state[] = { + A_ENTER_STATE, + 0 } ; +Event EV_leave_state[] = { + A_LEAVE_STATE, + 0 } ; +Event EV_tick[] = { + A_TICK, + 0 } ; +#ifdef USE_LVP +Event EV_voltage_low[] = { + A_VOLTAGE_LOW, + 0 } ; +#endif +#ifdef USE_THERMAL_REGULATION +Event EV_temperature_high[] = { + A_OVERHEATING, + 0 } ; +Event EV_temperature_low[] = { + A_UNDERHEATING, + 0 } ; +#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 }; +#define EV_1click EV_click1_complete +Event EV_click1_complete[] = { + A_PRESS, + A_RELEASE, + A_RELEASE_TIMEOUT, + 0 }; +#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 }; +Event EV_click2_press[] = { + A_PRESS, + A_RELEASE, + A_PRESS, + 0 }; +Event EV_click2_release[] = { + A_PRESS, + A_RELEASE, + A_PRESS, + A_RELEASE, + 0 }; +#define EV_2clicks EV_click2_complete +Event EV_click2_complete[] = { + A_PRESS, + A_RELEASE, + A_PRESS, + A_RELEASE, + A_RELEASE_TIMEOUT, + 0 }; +Event EV_click3_press[] = { + A_PRESS, + A_RELEASE, + A_PRESS, + A_RELEASE, + A_PRESS, + 0 }; +Event EV_click3_release[] = { + A_PRESS, + A_RELEASE, + A_PRESS, + A_RELEASE, + A_PRESS, + A_RELEASE, + 0 }; +#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 }; +// ... and so on + +// A list of button event types for easy iteration +EventPtr event_sequences[] = { + EV_click1_press, + EV_release, + EV_click1_release, + EV_click1_complete, + EV_click1_hold, + EV_click1_hold_release, + EV_click2_press, + EV_click2_release, + EV_click2_complete, + EV_click3_press, + EV_click3_release, + EV_click3_complete, + // ... +}; + +#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); +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 delete_first_emission(); +//#define emit_now emit +uint8_t emit_now(EventPtr event, uint16_t arg); +void emit(EventPtr event, uint16_t arg); +void emit_current_event(uint16_t arg); + +#endif |
