~toykeeper/flashlight-firmware/fsm

483.12.14 by Selene ToyKeeper
switched the rest of FSM + Anduril to use SPDX license headers
1
// fsm-pcint.c: PCINT (Pin Change Interrupt) functions for SpaghettiMonster.
2
// Copyright (C) 2017-2023 Selene ToyKeeper
3
// SPDX-License-Identifier: GPL-3.0-or-later
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
4
483.12.14 by Selene ToyKeeper
switched the rest of FSM + Anduril to use SPDX license headers
5
#pragma once
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
6
7
#include <avr/interrupt.h>
8
#include <util/delay_basic.h>
9
10
uint8_t button_is_pressed() {
451.1.1 by Selene Scriven
refactored how interrupts work...
11
    uint8_t value = ((SWITCH_PORT & (1<<SWITCH_PIN)) == 0);
12
    button_last_state = value;
13
    return value;
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
14
}
15
16
inline void PCINT_on() {
433.1.1 by Selene Scriven
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
17
    #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
18
        // enable pin change interrupt
19
        GIMSK |= (1 << PCIE);
20
        // only pay attention to the e-switch pin
21
        #if 0  // this is redundant; was already done in main()
22
        PCMSK = (1 << SWITCH_PCINT);
23
        #endif
24
        // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default)
25
        // MCUCR &= 0b11111101;  MCUCR |= 0b00000001;
26
    #elif (ATTINY == 1634)
27
        // enable pin change interrupt
28
        #ifdef SWITCH2_PCIE
29
        GIMSK |= ((1 << SWITCH_PCIE) | (1 << SWITCH2_PCIE));
30
        #else
31
        GIMSK |= (1 << SWITCH_PCIE);
32
        #endif
483.3.1 by Gabriel Hart
Add AVR 1-Series and t1616 board and scripts
33
    #elif defined(AVRXMEGA3)  // ATTINY816, 817, etc)
34
        SWITCH_ISC_REG |= PORT_ISC_BOTHEDGES_gc;
433.1.1 by Selene Scriven
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
35
    #else
36
        #error Unrecognized MCU type
37
    #endif
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
38
}
39
40
inline void PCINT_off() {
433.1.1 by Selene Scriven
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
41
    #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
42
        // disable all pin-change interrupts
43
        GIMSK &= ~(1 << PCIE);
44
    #elif (ATTINY == 1634)
45
        // disable all pin-change interrupts
46
        GIMSK &= ~(1 << SWITCH_PCIE);
483.3.1 by Gabriel Hart
Add AVR 1-Series and t1616 board and scripts
47
    #elif defined(AVRXMEGA3)  // ATTINY816, 817, etc)
48
        SWITCH_ISC_REG &= ~(PORT_ISC_gm);
433.1.1 by Selene Scriven
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
49
    #else
50
        #error Unrecognized MCU type
51
    #endif
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
52
}
53
54
//void button_change_interrupt() {
433.1.1 by Selene Scriven
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
55
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634)
483.4.4 by Selene Scriven
slightly reorganized declaration of PCINT to make it easier to read
56
    #ifdef PCINT_vect
57
    ISR(PCINT_vect) {
58
    #else
59
    ISR(PCINT0_vect) {
60
    #endif
483.3.1 by Gabriel Hart
Add AVR 1-Series and t1616 board and scripts
61
#elif defined(AVRXMEGA3)  // ATTINY816, 817, etc)
483.4.4 by Selene Scriven
slightly reorganized declaration of PCINT to make it easier to read
62
    ISR(SWITCH_VECT) {
63
        // Write a '1' to clear the interrupt flag
64
        SWITCH_INTFLG |= (1 << SWITCH_PIN);
433.1.1 by Selene Scriven
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
65
#else
66
    #error Unrecognized MCU type
67
#endif
483.4.4 by Selene Scriven
slightly reorganized declaration of PCINT to make it easier to read
68
69
    irq_pcint = 1;  // let deferred code know an interrupt happened
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
70
71
    //DEBUG_FLASH;
72
310 by Selene Scriven
Debouncing finally works (at least, it does on my two test hosts).
73
    // as it turns out, it's more reliable to detect pin changes from WDT
74
    // because PCINT itself tends to double-tap when connected to a
75
    // noisy / bouncy switch (so the content of this function has been
76
    // moved to a separate function, called from WDT only)
77
    // PCINT_inner(button_is_pressed());
309 by Selene Scriven
Greatly improved button debouncing. Helps a lot on FW3A and my light saber.
78
}
79
310 by Selene Scriven
Debouncing finally works (at least, it does on my two test hosts).
80
// should only be called from PCINT and/or WDT
309 by Selene Scriven
Greatly improved button debouncing. Helps a lot on FW3A and my light saber.
81
// (is a separate function to reduce code duplication)
82
void PCINT_inner(uint8_t pressed) {
483.1.7 by Selene Scriven
fixed bug: button release events were sending 0 as the arg instead of the number of ticks the button was held
83
    button_last_state = pressed;
84
85
    // register the change, and send event to the current state callback
86
    if (pressed) {  // user pressed button
87
        push_event(B_PRESS);
309 by Selene Scriven
Greatly improved button debouncing. Helps a lot on FW3A and my light saber.
88
        emit_current_event(0);
483.1.7 by Selene Scriven
fixed bug: button release events were sending 0 as the arg instead of the number of ticks the button was held
89
    } else {  // user released button
90
        // how long was the button held?
91
        push_event(B_RELEASE);
483.1.71 by Selene Scriven
fixed bug: ticks_since_last_event wasn't getting reset on button hold release
92
        emit_current_event(ticks_since_last_event);
309 by Selene Scriven
Greatly improved button debouncing. Helps a lot on FW3A and my light saber.
93
    }
483.1.71 by Selene Scriven
fixed bug: ticks_since_last_event wasn't getting reset on button hold release
94
    ticks_since_last_event = 0;
199 by Selene Scriven
Completely reorganized SpaghettiMonster code into smaller logical pieces: fsm-*.c and fsm-*.h.
95
}
483.1.72 by Selene Scriven
reorganized code in fsm-events.* to put things in a more coherent order
96