#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define BAUD_RATE 9600UL // 9600 bits/sec
#define UBBR_VAL ((F_CPU / (BAUD_RATE * 16UL)) - 1)

#define LED (1 << PD7)
#define SW (1 << PD2)
#define SW2 (1 << PB0)
#define LED_BUILTIN (1 << PB5)

volatile uint8_t a = 0; // increased by the interrupt
volatile bool flag = false;

//************** UART **************/
void uart_init(void)
{
  UBRR0L = (uint8_t)UBBR_VAL;
  UCSR0B |= (1 << TXEN0);                  // Enabling  Tx
  UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); // Setting frame format to 8-bit, 1 stop bot & no parity
}

void uart_write(uint8_t data) // Trasmits data
{
  while (!(UCSR0A & (1 << UDRE0)))
    ; // wait until tha data reagister is enpty
  UDR0 = data;
}

void uart_print(const char *str) // To print charater/ string
{
  while (*str)
  {
    uart_write(*str++);
  }
}
/********************************************/

/// Without Interrupt ///

// int main(void){
//   DDRD &= ~SW; // SWITCH AT D2
//   DDRD |= LED; // LED AT D7

//   while(1){
//     if(PIND & SW){
//       _delay_ms(250);
//       PORTD |= LED;
//     }
//     else{
//       _delay_ms(250);
//       PORTD &= ~ LED;
//     }
//   }
// }

/// With External interrupt + PCINT///

int main(void)
{
  char UART_buffer[50];

  DDRD &= ~SW;  // SWITCH AT D2
  DDRD |= LED;  // LED AT D7
  DDRB &= ~SW2; // SWITCH AT D8
  PORTB |= SW2; // PULLUP RESISTOR ENABLED
  DDRB &= ~LED_BUILTIN;

  // Enabling PCINT intrrupt
  PCICR |= (1 << PCIE0);
  PCMSK0 |= (1 << PCINT0);

  // EICRA |= (1 << ISC01);
  // EICRA |= (1 << ISC01); // External Interrupt Control Register A -> (For any logic change)
  EICRA = 2;
  EIMSK |= (1 << INT0); // External Interupt Mask Register (Enabling External intrupt 0)

  sei();

  while (true)
  {
    if (flag)
    {
      snprintf(UART_buffer, sizeof(UART_buffer), "%d\n", a);
      uart_print(UART_buffer);
      flag = false;
    }
  }
}

ISR(INT0_vect)
{
  if (PIND & SW) // If buttons was pressed
  {
    PORTD |= LED; // LED -> ON
    _delay_ms(500);
  }
  else
  {
    PORTD &= ~LED; // LED -> OFF
  }
}

ISR(PCINT0_vect)
{
    _delay_ms(50);
  if (!(PINB & SW2))
  {
    ++a;
    flag = true;
    PORTB ^= LED_BUILTIN; // LED -> ON
  }
}