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-pcint.c | 76 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 spaghetti-monster/fsm-pcint.c (limited to 'spaghetti-monster/fsm-pcint.c') diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c new file mode 100644 index 0000000..763c1fe --- /dev/null +++ b/spaghetti-monster/fsm-pcint.c @@ -0,0 +1,76 @@ +/* + * fsm-pcint.c: PCINT (Pin Change Interrupt) 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_PCINT_C +#define FSM_PCINT_C + +#include +#include + +uint8_t button_is_pressed() { + // debounce a little + uint8_t highcount = 0; + // measure for 16/64ths of a ms + for(uint8_t i=0; i (BP_SAMPLES/2)); + //button_was_pressed = result; + return result; +} + +inline void PCINT_on() { + // enable pin change interrupt for pin N + GIMSK |= (1 << PCIE); + // only pay attention to the e-switch pin + //PCMSK = (1 << SWITCH_PCINT); + // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default) + // MCUCR &= 0b11111101; MCUCR |= 0b00000001; +} + +inline void PCINT_off() { + // disable all pin-change interrupts + GIMSK &= ~(1 << PCIE); +} + +//void button_change_interrupt() { +ISR(PCINT0_vect) { + + //DEBUG_FLASH; + + uint8_t pushed; + + // add event to current sequence + if (button_is_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) emit_current_event(0); +} + +#endif -- 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-pcint.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'spaghetti-monster/fsm-pcint.c') diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c index 763c1fe..c04375a 100644 --- a/spaghetti-monster/fsm-pcint.c +++ b/spaghetti-monster/fsm-pcint.c @@ -59,10 +59,25 @@ ISR(PCINT0_vect) { //DEBUG_FLASH; - uint8_t pushed; + /* + uint8_t pressed; // add event to current sequence - if (button_is_pressed()) { + pressed = button_is_pressed(); + PCINT_inner(pressed); + */ + if (! PCINT_since_WDT) { + PCINT_since_WDT = 1; + PCINT_inner(button_is_pressed()); + } +} + +// should only be called from PCINT and WDT +// (is a separate function to reduce code duplication) +void PCINT_inner(uint8_t pressed) { + uint8_t pushed; + + if (pressed) { pushed = push_event(A_PRESS); } else { pushed = push_event(A_RELEASE); @@ -70,7 +85,9 @@ ISR(PCINT0_vect) { // check if sequence matches any defined sequences // if so, send event to current state callback - if (pushed) emit_current_event(0); + if (pushed) { + button_last_state = pressed; + emit_current_event(0); + } } - #endif -- 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-pcint.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'spaghetti-monster/fsm-pcint.c') diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c index c04375a..722cb88 100644 --- a/spaghetti-monster/fsm-pcint.c +++ b/spaghetti-monster/fsm-pcint.c @@ -24,20 +24,19 @@ #include uint8_t button_is_pressed() { - // debounce a little - uint8_t highcount = 0; - // measure for 16/64ths of a ms - for(uint8_t i=0; i (BP_SAMPLES/2)); - //button_was_pressed = result; - return result; + while ((readings != 0) && (readings != 0xFFFFFFFF)); + button_last_state = readings; + return readings; } inline void PCINT_on() { @@ -59,20 +58,15 @@ ISR(PCINT0_vect) { //DEBUG_FLASH; - /* - uint8_t pressed; + // as it turns out, it's more reliable to detect pin changes from WDT + // because PCINT itself tends to double-tap when connected to a + // noisy / bouncy switch (so the content of this function has been + // moved to a separate function, called from WDT only) + // PCINT_inner(button_is_pressed()); - // add event to current sequence - pressed = button_is_pressed(); - PCINT_inner(pressed); - */ - if (! PCINT_since_WDT) { - PCINT_since_WDT = 1; - PCINT_inner(button_is_pressed()); - } } -// should only be called from PCINT and WDT +// should only be called from PCINT and/or WDT // (is a separate function to reduce code duplication) void PCINT_inner(uint8_t pressed) { uint8_t pushed; -- cgit v1.2.3 From 8267c1f121d9766e37d2056004bd7bb47b512288 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Wed, 24 Jan 2018 18:28:29 -0700 Subject: Save a few bytes by changing how PCINT is defined. Minor comment cleaning. --- spaghetti-monster/fsm-pcint.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'spaghetti-monster/fsm-pcint.c') diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c index 722cb88..a79572d 100644 --- a/spaghetti-monster/fsm-pcint.c +++ b/spaghetti-monster/fsm-pcint.c @@ -54,6 +54,8 @@ inline void PCINT_off() { } //void button_change_interrupt() { +EMPTY_INTERRUPT(PCINT0_vect); +/* ISR(PCINT0_vect) { //DEBUG_FLASH; @@ -65,6 +67,7 @@ ISR(PCINT0_vect) { // PCINT_inner(button_is_pressed()); } +*/ // should only be called from PCINT and/or WDT // (is a separate function to reduce code duplication) -- cgit v1.2.3