From 73a5a6974a98aa73ab392272b4d69d285c85dee5 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Sat, 19 Aug 2017 17:20:46 -0600
Subject: Completely reorganized SpaghettiMonster code into smaller logical
pieces: fsm-*.c and fsm-*.h.
---
spaghetti-monster/fsm-wdt.c | 107 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 spaghetti-monster/fsm-wdt.c
(limited to 'spaghetti-monster/fsm-wdt.c')
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
new file mode 100644
index 0000000..afcf467
--- /dev/null
+++ b/spaghetti-monster/fsm-wdt.c
@@ -0,0 +1,107 @@
+/*
+ * fsm-wdt.c: WDT (Watch Dog Timer) 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_WDT_C
+#define FSM_WDT_C
+
+#include
+#include
+
+void WDT_on()
+{
+ // interrupt every 16ms
+ //cli(); // Disable interrupts
+ wdt_reset(); // Reset the WDT
+ WDTCR |= (1<= 1) last_event = current_event[le_num-1];
+ if (le_num >= 2) prev_event = current_event[le_num-2];
+
+ // 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);
+ }
+ }
+
+ // 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) {
+ // no timeout required when releasing a long-press
+ // TODO? move this logic to PCINT() and simplify things here?
+ if (prev_event == A_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);
+ emit_current_event(0);
+ empty_event_sequence();
+ }
+ }
+
+ #if defined(USE_LVP) || defined(USE_THERMAL_REGULATION)
+ // start a new ADC measurement every 4 ticks
+ static uint8_t adc_trigger = 0;
+ adc_trigger ++;
+ if (adc_trigger > 3) {
+ adc_trigger = 0;
+ ADCSRA |= (1 << ADSC) | (1 << ADIE);
+ }
+ #endif
+}
+
+#endif
--
cgit v1.2.3
From 2ec533abd4592958bef3ec818870e3fb41b64b29 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Thu, 28 Sep 2017 17:03:58 -0600
Subject: Added reversing to Anduril. Made EV_tick always send 0 while in
"hold" state. Reversing is a build-time option.
---
spaghetti-monster/fsm-wdt.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
(limited to 'spaghetti-monster/fsm-wdt.c')
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index afcf467..7cbe0d2 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -50,9 +50,6 @@ ISR(WDT_vect) {
ticks_since_last_event = (ticks_since_last_event + 1) \
| (ticks_since_last_event & 0x8000);
- // callback on each timer tick
- emit(EV_tick, ticks_since_last_event);
-
// if time since last event exceeds timeout,
// append timeout to current event sequence, then
// send event to current state callback
@@ -64,6 +61,14 @@ ISR(WDT_vect) {
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) {
+ emit(EV_tick, 0); // override tick counter while holding button
+ }
+ else {
+ emit(EV_tick, ticks_since_last_event);
+ }
+
// user held button long enough to count as a long click?
if (last_event == A_PRESS) {
if (ticks_since_last_event >= HOLD_TIMEOUT) {
--
cgit v1.2.3
From d50c46d08a6d7f52dffb9b43784c62b11d78df8c Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 11 Dec 2017 19:56:15 -0700
Subject: Greatly improved button debouncing. Helps a lot on FW3A and my light
saber. Debouncing isn't 100% yet though.
---
spaghetti-monster/fsm-wdt.c | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster/fsm-wdt.c')
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index 7cbe0d2..bee2914 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -50,13 +50,42 @@ ISR(WDT_vect) {
ticks_since_last_event = (ticks_since_last_event + 1) \
| (ticks_since_last_event & 0x8000);
+ // just in case the pin change interrupt missed something
+ uint8_t le_num = last_event_num();
+ uint8_t last_event = 0;
+ if (le_num >= 1) last_event = current_event[le_num-1];
+ uint8_t pressed = button_is_pressed();
+ uint8_t was_pressed_before = (last_event == A_PRESS) || (last_event == A_HOLD);
+ //if (pressed != button_last_state) {
+ if (pressed != was_pressed_before) {
+ PCINT_inner(pressed);
+ /*
+ uint8_t pushed;
+ if (pressed) {
+ pushed = push_event(A_PRESS);
+ } else {
+ pushed = push_event(A_RELEASE);
+ }
+
+ // check if sequence matches any defined sequences
+ // if so, send event to current state callback
+ if (pushed) {
+ button_last_state = pressed;
+ emit_current_event(0);
+ }
+ */
+ }
+ PCINT_since_WDT = 0;
+
// 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 le_num = last_event_num();
+ le_num = last_event_num();
+ //uint8_t last_event = 0;
+ 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];
--
cgit v1.2.3
From 8c13fd82557dadbe81023c534cd19c31ec40bde4 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Dec 2017 15:22:42 -0700
Subject: Debouncing finally works (at least, it does on my two test hosts).
---
spaghetti-monster/fsm-wdt.c | 38 +++++++-------------------------------
1 file changed, 7 insertions(+), 31 deletions(-)
(limited to 'spaghetti-monster/fsm-wdt.c')
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index bee2914..777bef0 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -45,47 +45,23 @@ inline void WDT_off()
// clock tick -- this runs every 16ms (62.5 fps)
ISR(WDT_vect) {
+ // detect and emit button change events
+ uint8_t was_pressed = button_last_state;
+ uint8_t pressed = button_is_pressed();
+ if (was_pressed != pressed) PCINT_inner(pressed);
+
//if (ticks_since_last_event < 0xff) 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);
- // just in case the pin change interrupt missed something
- uint8_t le_num = last_event_num();
- uint8_t last_event = 0;
- if (le_num >= 1) last_event = current_event[le_num-1];
- uint8_t pressed = button_is_pressed();
- uint8_t was_pressed_before = (last_event == A_PRESS) || (last_event == A_HOLD);
- //if (pressed != button_last_state) {
- if (pressed != was_pressed_before) {
- PCINT_inner(pressed);
- /*
- uint8_t pushed;
- if (pressed) {
- pushed = push_event(A_PRESS);
- } else {
- pushed = push_event(A_RELEASE);
- }
-
- // check if sequence matches any defined sequences
- // if so, send event to current state callback
- if (pushed) {
- button_last_state = pressed;
- emit_current_event(0);
- }
- */
- }
- PCINT_since_WDT = 0;
-
// 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();
- le_num = last_event_num();
- //uint8_t last_event = 0;
- last_event = 0;
+ 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];
--
cgit v1.2.3
From 30b13cc13baba55ac1610ad471ca737a6c817683 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Wed, 24 Jan 2018 18:27:44 -0700
Subject: Work around issues related to ADC interrupt auto-triggering itself.
(was firing off 1000 times faster than desired, causing several issues) (now
only executes when explicitly requested by the WDT)
---
spaghetti-monster/fsm-wdt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster/fsm-wdt.c')
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index 777bef0..ff96ffb 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -107,9 +107,9 @@ ISR(WDT_vect) {
// start a new ADC measurement every 4 ticks
static uint8_t adc_trigger = 0;
adc_trigger ++;
- if (adc_trigger > 3) {
- adc_trigger = 0;
+ if (0 == (adc_trigger & 3)) {
ADCSRA |= (1 << ADSC) | (1 << ADIE);
+ adcint_enable = 1;
}
#endif
}
--
cgit v1.2.3