From 20d86bf1e3dfdfb4c0a3ea557b54f0bea0f5c214 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 8 Feb 2026 16:18:49 +0530 Subject: Handle button state --- justfile | 2 +- src/button.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/button.h | 20 ++++++++++++++++++++ src/display.c | 5 +++++ src/main.c | 32 +++++++++++++------------------- src/rtc.c | 2 +- 6 files changed, 97 insertions(+), 21 deletions(-) create mode 100644 src/button.c create mode 100644 src/button.h diff --git a/justfile b/justfile index 224a293..e08c5fb 100644 --- a/justfile +++ b/justfile @@ -8,7 +8,7 @@ AVR_LIBC := env("AVR_LIBC", "/usr/lib/avr") F_CPU := "32768" MCU := "attiny84a" MCU_PART := "attiny84" -SRCS := "src/main.c src/display.c src/rtc.c" +SRCS := "src/main.c src/display.c src/rtc.c src/button.c" OUTDIR := "./out" PROGRAMMER := "arduino" UPLOAD_SPEED := "19200" diff --git a/src/button.c b/src/button.c new file mode 100644 index 0000000..34d799c --- /dev/null +++ b/src/button.c @@ -0,0 +1,57 @@ +#include +#include + +#include "avr/interrupt.h" +#include "button.h" +#include "rtc.h" + +bool is_button_active = false; + +uint16_t button_tick_count = 0; + +ISR(PCINT0_vect, ISR_FLATTEN) { button_tick(); } + +void button_tick() { + switch (check_button_state()) { + case BUTTON_PRESSED: + if (seconds <= 10) + seconds = 0; + else + seconds -= 10; + break; + case BUTTON_LONG_PRESSED: + seconds += 10; + break; + default: + break; + } +} + +enum ButtonState check_button_state() { + if (is_button_active && button_tick_count >= LONG_PRESS_TICK_COUNT) { + button_tick_count = 0; + is_button_active = false; + return BUTTON_LONG_PRESSED; + } + + bool in_debounce_period = is_button_active && button_tick_count > 0 && + button_tick_count < DEBOUNCE_TICK_COUNT; + + // Ignore readings from debounce period + if (!in_debounce_period) { + DDRA &= ~(1 << PA0); + PORTA &= ~(1 << PA0); + is_button_active = (PINA & (1 << PA0)) == 0; + } + + if (is_button_active) { + button_tick_count++; + } else { + if (button_tick_count >= DEBOUNCE_TICK_COUNT) { + button_tick_count = 0; + return BUTTON_PRESSED; + } + } + + return BUTTON_IDLE; +} diff --git a/src/button.h b/src/button.h new file mode 100644 index 0000000..bb41eb6 --- /dev/null +++ b/src/button.h @@ -0,0 +1,20 @@ +#ifndef _LOADED_BUTTON +#define _LOADED_BUTTON +#include +#include + +#define DEBOUNCE_TICK_COUNT 10 +#define LONG_PRESS_TICK_COUNT 60 +#define MAX_TICK_COUNT 80 + +enum ButtonState { + BUTTON_IDLE = 0, + BUTTON_PRESSED = 1, + BUTTON_LONG_PRESSED = 2, +}; + +uint16_t extern button_tick_count; + +void button_tick(); +enum ButtonState check_button_state(); +#endif diff --git a/src/display.c b/src/display.c index 8de5043..7781b7e 100644 --- a/src/display.c +++ b/src/display.c @@ -3,6 +3,7 @@ #include #include +#include "button.h" #include "display.h" #include "rtc.h" @@ -38,8 +39,12 @@ volatile uint8_t current_digit = 0; // Render current digit void display_render(void) { + button_tick(); // Check button click + DDRA |= 0b11111111; DDRB |= 0b11111111; + PORTA = 0b01111111; + PORTB = 0b00000000; write_time(minutes, seconds, current_digit); diff --git a/src/main.c b/src/main.c index cf6f7a8..6f621af 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include +#include "button.h" #include "display.h" #include "rtc.h" @@ -15,17 +16,14 @@ FUSES = { .extended = 0xff, }; -// Display -// timer 0 has lower priority than timer 1, so some ticks could get skipped due -// to interrupt starvation +// Display interrupt +// Timer 0 has lower priority than timer 1, so some ticks could get skipped on +// interrupt starvation ISR(TIM0_COMPA_vect, ISR_FLATTEN) { display_render(); } // RTC interrupt ISR(TIM1_COMPA_vect, ISR_FLATTEN) { rtc_increment(); } -#define IS_BUTTON_ON() ((PINA & (1 << PA0)) == 0) -#define ENABLE_BUTTON() (DDRA &= ~(1 << PA0)) - int main(void) { PRR = 0b0011; // Power reduction register. Shut down USI and ADC @@ -35,20 +33,16 @@ int main(void) { sei(); while (1) { - // ENABLE_BUTTON(); - // if (IS_BUTTON_ON()) { - // cli(); - // ENABLE_BUTTON(); - // _delay_ms(25); // Debounced - // if (IS_BUTTON_ON()) { - // seconds += 1; - // sei(); - // _delay_ms(50); - // continue; - // } + // switch (button_tick()) { + // case BUTTON_PRESSED: + // seconds += 5; + // break; + // case BUTTON_LONG_PRESSED: + // seconds += 10; + // break; + // default: + // break; // } - // sei(); - #ifdef STUBBED stub_run_timers(); _delay_ms(100); diff --git a/src/rtc.c b/src/rtc.c index 1ac50c3..053e651 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -19,7 +19,7 @@ void rtc_setup(void) { TIMSK1 = (1 << OCIE1A); // Enable timer overflow interrupt } -volatile uint8_t seconds = 10; +volatile uint8_t seconds = 0; volatile uint8_t minutes = 0; volatile uint8_t hours = 0; -- cgit v1.3.1