diff --git a/module04/ex02/main.c b/module04/ex02/main.c index b0dc699..17961b1 100644 --- a/module04/ex02/main.c +++ b/module04/ex02/main.c @@ -20,7 +20,13 @@ // 13.2.6 : PCMSK2 – Pin Change Mask Register 2 // -> (1 << PCINT20) | (1 << PCINT18) +#define TIMER_TOP_MS 20 + volatile uint8_t value = 0; +volatile Boolean pressed = FALSE; +volatile Boolean timer_0_init = FALSE; +volatile Boolean timer_delay_enabled = FALSE; +volatile uint16_t timer_delay = 0; void print_binary(int value) { int mask_3 = 0b1000; @@ -53,14 +59,58 @@ void decrement_led() { print_binary(value); } +void timer0_init_1_ms() { + TCCR0A |= (1 << WGM01); // CTC mode + OCR0A = 249; // Compare match every 1ms (F_CPU / Prescaler = 16,000,000 / 64 = 250,000 ticks/sec) + TIMSK0 |= (1 << OCIE0A); // Enable Compare Match A interrupt + TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64 + sei(); // Enable global interrupts + timer_0_init = TRUE; +} + +void launch_delay_ms(void) { + if (!timer_0_init) { + timer0_init_1_ms(); + } + CLEAR(PCICR, PCIE2); // disable interupt PCINT2 + CLEAR(PCMSK2, PCINT20); + CLEAR(PCMSK2, PCINT18); + timer_delay = 0; + timer_delay_enabled = TRUE; + SET(PCIFR, PCIF2); // reset flag interrupt PCINT2 +} + +ISR(TIMER0_COMPA_vect) { + if (!timer_delay_enabled) { + return; + } + timer_delay++; + if (timer_delay >= TIMER_TOP_MS) { + // TOGGLE_ELEM(LED1); + timer_delay_enabled = FALSE; + SET(PCICR, PCIE2); // re-enable interupt PCINT2 + SET(PCMSK2, PCINT20); + SET(PCMSK2, PCINT18); + } +} + void on_press(int bit, void (*action)(void)) { - if ((TEST(PIND, bit)) == 0) { + // if ((TEST(PIND, bit)) == 0) { + // action(); + // _delay_ms(20); + // while ((TEST(PIND, bit)) == 0) { + // continue; + // } + // _delay_ms(20); + // } + launch_delay_ms(); + if (!pressed) { + // if ((TEST(PIND, bit)) == 0) { + // } + pressed = TRUE; action(); - _delay_ms(20); - while ((TEST(PIND, bit)) == 0) { - continue; - } - _delay_ms(20); + } else { + pressed = FALSE; } } @@ -84,6 +134,10 @@ int main() { } ISR(PCINT2_vect) { - on_press(SW1, increment_led); - on_press(SW2, decrement_led); + if (!TEST_PIN(BUTTON1)) { + on_press(SW1, increment_led); + } + if (!TEST_PIN(BUTTON2)) { + on_press(SW2, decrement_led); + } }