/*
* 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 .
*/
#ifndef FSM_EVENTS_H
#define FSM_EVENTS_H
#include
// typedefs
typedef uint8_t Event;
typedef struct Emission {
Event event;
uint16_t arg;
} Emission;
#define EVENT_HANDLED 0
#define EVENT_NOT_HANDLED 1
#define MISCHIEF_MANAGED EVENT_HANDLED
#define MISCHIEF_NOT_MANAGED EVENT_NOT_HANDLED
Event current_event;
// at 0.016 ms per tick, 255 ticks = 4.08 s
static volatile uint16_t ticks_since_last_event = 0;
// timeout durations in ticks (each tick 1/62th s)
#ifndef HOLD_TIMEOUT
#define HOLD_TIMEOUT 24
#endif
#ifndef RELEASE_TIMEOUT
#define RELEASE_TIMEOUT 18
#endif
/* 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
#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
#define EV_sleep_tick (B_SYSTEM|0b00000011)
#endif
#ifdef USE_LVP
#define EV_voltage_low (B_SYSTEM|0b00000100)
#endif
#ifdef USE_THERMAL_REGULATION
#define EV_temperature_high (B_SYSTEM|0b00000101)
#define EV_temperature_low (B_SYSTEM|0b00000110)
#endif
// 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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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);
#define EMISSION_QUEUE_LEN 16
// no comment about "volatile emissions"
volatile Emission emissions[EMISSION_QUEUE_LEN];
void append_emission(Event event, uint16_t arg);
void delete_first_emission();
void process_emissions();
//#define emit_now emit
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);
//uint8_t nice_delay_4ms(uint8_t ms);
//uint8_t nice_delay_s();
inline void interrupt_nice_delays();
#endif