From 8c7d0b40693284f237fb9a24221a725b16c7d399 Mon Sep 17 00:00:00 2001
From: Imbus <>
Date: Tue, 2 Apr 2024 14:25:11 +0200
Subject: [PATCH] Various interrupts

---
 main.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 62 insertions(+), 9 deletions(-)

diff --git a/main.c b/main.c
index 17f29f2..8e2ee04 100644
--- a/main.c
+++ b/main.c
@@ -2,9 +2,18 @@
 #include <avr/io.h>
 #include <avr/sleep.h>
 #include <avr/wdt.h>
+#include <util/delay.h>
 
 #define LED_PIN PB5  // Define the pin connected to the LED
 
+// Flipping the led every 0.5s using the overflow interrupt
+ISR(TIMER1_OVF_vect) {
+    PORTB ^= _BV(LED_PIN);                             // Toggle the LED
+    TCNT1 = (uint16_t)(65535 - (F_CPU / 1024) * 0.5);  // Reset the counter
+    TIFR1 |= (1 << TOV1);  // Clear the interrupt flag
+}
+
+// 'Pulse' the LED
 ISR(TIMER1_COMPA_vect) {
     // Static variable to keep track of the number of interrupts
     static uint16_t counter = 0;
@@ -14,6 +23,7 @@ ISR(TIMER1_COMPA_vect) {
     // Modulo magic, see below for explanation
     if (++counter % 2 == 0) {
         OCR1A = 15624 / 2;
+        counter = 0;
     } else {
         OCR1A = 15624 / 16;
     }
@@ -22,34 +32,77 @@ ISR(TIMER1_COMPA_vect) {
     TIFR1 |= (1 << TOV1);
 }
 
+// External interrupt
+ISR(INT0_vect) {
+    PORTB ^= _BV(LED_PIN);  // Toggle the LED
+    _delay_ms(200);         // Debounce
+}
+
 // We will use Timer1 for the interrupt
 void configure_interrupt() {
-    TCNT1 = 0;   // Initialize the counter value to 0
-    TCCR1A = 0;  // Set the timer to normal mode
-    TCCR1B = 0;  // Set the timer to normal mode
-    OCR1A = 15624 / 16;  // 31250 for a 2s delay, 15624 for a 1s delay
+    TCCR1A = 0;                           // Set the timer to normal mode
+    TCCR1B = 0;                           // Set the timer to normal mode
     TCCR1B |= (1 << WGM12);               // Set the timer to CTC mode
     TCCR1B |= (1 << CS02) | (1 << CS00);  // Set the prescaler to 1024
     TIMSK1 |= (1 << OCIE1A);              // Enable overflow interrupt
-    sei();  // Enable global interrupts (cli() to disable)
+    sei();      // Enable global interrupts (cli() to disable)
+    OCR1A = 0;  // 31250 for a 2s delay, 15624 for a 1s delay
+    TCNT1 = (uint16_t)(65535 - (F_CPU / 1024) * 0.5);  // Reset the counter
+}
+
+void configure_external_interrupt() {
+    // Set the external interrupt to trigger on the falling edge
+    EICRA |= (1 << ISC01);
+    EICRA &= ~(1 << ISC00);
+
+    // Enable the external interrupt
+    EIMSK |= (1 << INT0);  // Pin D2 is INT0
+
+    DDRD &= ~_BV(PD2);  // Set the pin as an input
+    PORTD |= _BV(PD2);  // Enable the pull-up resistor
+
+    // Enable global interrupts
+    sei();
+}
+
+void configure_ovf_interrupt() {
+    // Set the timer to normal mode
+    TCCR1A = 0;
+    TCCR1B = 0;
+
+    // Initialize the counter to 0xFFFF
+    TCNT1 = 0xFFFF;
+
+    // Set the prescaler to 1024
+    TCCR1B |= _BV(CS12) | _BV(CS10);
+
+    // Enable overflow interrupt
+    TIMSK1 |= (1 << TOIE1);
+
+    // Enable global interrupts
+    sei();
 }
 
 int main(void) {
     // Configure the LED pin as an output
     DDRB |= _BV(LED_PIN);
 
-    configure_interrupt();
+    // Choose one (or both)
+    // configure_interrupt();
+    // configure_ovf_interrupt();
+    configure_external_interrupt();
 
     // Set the watchdog timer to 8 seconds
-    wdt_enable(WDTO_8S);
+    // wdt_enable(WDTO_8S);
+    // wdt_disable();
+    // wdt_reset(); // Reset the watchdog timer
 
     // Set the sleep mode to idle
     set_sleep_mode(SLEEP_MODE_IDLE);
 
     // Pat the dog and sleep until the next interrupt
     while (1) {
-        wdt_reset();
-        sleep_mode();
+        sleep_mode();  // Doesent sleep through interrupts
     }
 
     return 0;