// Ref:
// https://www.arnabkumardas.com/arduino-tutorial/usart-programming/
// https://atmega32-avr.com/serial-communication-avr-microcontroller-using-interrupts/
// https://baike.baidu.hk/item/USART/10593784

#define USART_BAUDRATE 9600 // Desired Baud Rate
#define BAUD_PRESCALER (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#define ASYNCHRONOUS (0<<UMSEL00) // USART Mode Selection

#define DISABLED    (0<<UPM00)
#define EVEN_PARITY (2<<UPM00)
#define ODD_PARITY  (3<<UPM00)
#define PARITY_MODE  DISABLED // USART Parity Bit Selection

#define ONE_BIT (0<<USBS0)
#define TWO_BIT (1<<USBS0)
#define STOP_BIT ONE_BIT      // USART Stop Bit Selection

#define FIVE_BIT  (0<<UCSZ00)
#define SIX_BIT   (1<<UCSZ00)
#define SEVEN_BIT (2<<UCSZ00)
#define EIGHT_BIT (3<<UCSZ00)
#define DATA_BIT   EIGHT_BIT  // USART Data Bit Selection

#define RX_COMPLETE_INTERRUPT         (1<<RXCIE0)
#define DATA_REGISTER_EMPTY_INTERRUPT (1<<UDRIE0)

volatile uint8_t USART_ReceiveBuffer; // Global Buffer

void usart_init()
{
  // Turn on the transmission reception circuitry
  // and receiver interrupt
  UCSR2B |= (1<<RXCIE2) | (1 << RXEN2) | (1 << TXEN2);
  UCSR2C |= ASYNCHRONOUS | PARITY_MODE | STOP_BIT | DATA_BIT; //(1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
  UBRR2L = BAUD_PRESCALER; // Load lower 8-bits of the baud rate value..
  // into the low byte of the UBRR register
  UBRR2H = (BAUD_PRESCALER >> 8); // Load upper 8-bits of the baud rate value..
  // into the high byte of the UBRR register
  sei();
}

ISR (USART2_RX_vect)
{
  //unsigned char value;
  USART_ReceiveBuffer = UDR2; // Fetch the received byte value into the variable “value”
  UDR2 = USART_ReceiveBuffer;   //Put the value to UDR
}

void setup() {
  usart_init();

}

void loop() {
  // put your main code here, to run repeatedly:

}