#include "header.h"

// 14.3.3 : alternate functions on port D
// PD2 : - INT0 (External Interrupt 0 Input)
//       - PCINT18 (Pin Change Interrupt 18)
// 12.4 : Interrupt Vectors in ATmega328 and ATmega328P
//       - INT0 : External Interrupt Request 0

typedef enum {
    DOWN,
    UP
} State;
volatile uint8_t button_state = UP;

// Table 13-2 : interrupt types
#define INT0_LOW		((0 << ISC01) | (0 << ISC00))
#define INT0_LOGICAL	((0 << ISC01) | (1 << ISC00))
#define INT0_FALLING	((1 << ISC01) | (0 << ISC00))
#define INT0_RAISING	((1 << ISC01) | (1 << ISC00))

// use interruption to change led1 state when button1 is pressed
int main() {
	MODE_OUTPUT(LED1);
	CLEAR_ELEM(LED1);
	MODE_INPUT(BUTTON1);
    PULLUP_ON(BUTTON1);

	SREG |= ENABLE_GLOBAL_INTERRUPT;

    EIMSK = (1 << INT0);								// 13.2.2 : Enable INT0 interrupt (EIMSK – External Interrupt Mask Register)
	EICRA = INT0_LOGICAL;								// Table 13-2 : trigger type (EICRA – External Interrupt Control Register A)

    while (1);
}

ISR(INT0_vect) {
	button_state = (button_state == UP) ? DOWN : UP;
	if (button_state == UP) {
		TOGGLE_ELEM(LED1);
	}
	_delay_ms(50);										// for debounce, bad idea to put it here in more complexe codes, it is blocking
	EIFR |= (1 << INTF0);								// 13.2.3 : clear flag, when the flag is set it triggers the interrupt, and eventhough it should be clear by the trigger, it can be set again by the bouncing
}
