aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--justfile2
-rw-r--r--src/button.c57
-rw-r--r--src/button.h20
-rw-r--r--src/display.c5
-rw-r--r--src/main.c32
-rw-r--r--src/rtc.c2
6 files changed, 97 insertions, 21 deletions
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 <avr/io.h>
+#include <stdint.h>
+
+#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 <stdbool.h>
+#include <stdint.h>
+
+#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 <stdint.h>
#include <util/delay.h>
+#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 <stdbool.h>
#include <util/delay.h>
+#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;