#include <avr/interrupt.h>

uint8_t index = 0;
const uint8_t buffer_size = 60;
char str[buffer_size];

void pin_configure(void);
void transmit_byte_serially(uint8_t);
void output1(char);
void transmit_string(const char*);
void start_timer_baud_10000(void);//for 100 microsecond delay
void wait_and_stop_timer(void);
void configure_uart3(void);
void reset_string(void);

void pin_configure(void) {
    volatile char *dirf, *outf, *dirj;
    dirf = (volatile char *)0x30;
    outf = (volatile char *)0x31;
    dirj = (volatile char *)0x104;
    *dirf = 0xFF;
    *outf = 0x01;
    *dirj = 0x00;
}

void output1(char x) {
    volatile char *outf = (volatile char *)0x31;
    *outf = x;
}

void transmit_byte_serially(uint8_t x) {
    start_timer_baud_10000();
    output1(0x00); // Start bit
    wait_and_stop_timer();

    for (uint8_t i = 0; i < 8; i++) { 
        start_timer_baud_10000();
        if (x & (1 << i)) {
            output1(0x01);
        } else {
            output1(0x00);
        }
        wait_and_stop_timer();
    }

    start_timer_baud_10000();
    output1(0x01); // Stop bit
    wait_and_stop_timer();
}

void transmit_string(const char *str) {
    while (*str) {
        transmit_byte_serially(*str);
        str++;
    }
    transmit_byte_serially('\0');
}

void start_timer_baud_10000(void) {
    volatile char *tccr1a, *tccr1b, *ocr1aL, *ocr1aH;
    tccr1a = (volatile char *)0x80;
    tccr1b = (volatile char *)0x81;
    ocr1aL = (volatile char *)0x88;
    ocr1aH = (volatile char *)0x89;

    *tccr1a = 0x00;
    *tccr1b = 0x0A; // CTC mode set prescaler to 8 for 100us delay approx
    *ocr1aH = 0x00;
    *ocr1aL = 0xC7; // Load value 199 to compare register for 100us delay
}

void wait_and_stop_timer(void) {
    volatile char *tifr1, *tcnt1L, *tcnt1H, *tccr1b;
    tifr1 = (volatile char *)0x36;
    tcnt1L = (volatile char *)0x84;
    tcnt1H = (volatile char *)0x85;
    tccr1b = (volatile char *)0x81;
    while (1) {
        if (*tifr1 & (1 << 2)) { // Check the timer compare match flag bit
            *tifr1 = (1 << 2); // Clear the flag bit
            *tcnt1H = 0x00; // Reset timer
            *tcnt1L = 0x00;
            *tccr1b = 0x00; // Stop the timer
            break;
        }
    }
}

void reset_string(void) {
    for (int i = 0; i < buffer_size; i++) {
        str[i] = '\0';
    }
    index = 0;
}

void configure_uart3(void) {
    volatile char *udr3, *ubrr3l, *ubrr3h, *ucsr3a, *ucsr3b, *ucsr3c;
    udr3 = (volatile char *)0x136;
    ubrr3l = (volatile char *)0x134;
    ubrr3h = (volatile char *)0x135;
    ucsr3a = (volatile char *)0x130;
    ucsr3b = (volatile char *)0x131;
    ucsr3c = (volatile char *)0x132;

    *ubrr3h = 0x00;//lower bits were low 
    *ubrr3l = 0x63; // set baud rate 10000
    *ucsr3b = 0x98; // set rx interupt bit and rx enable bit
    *ucsr3c = 0x06; // 1 stop bit, 8 data bits,asynchronous mode

   // Serial.println("Successfully configured USART3");
}

ISR(USART3_RX_vect, ISR_BLOCK) {
   volatile char data=0x00;
  volatile char*udr3;
  udr3=(volatile char*)0x136;
  data=*udr3;
    if (index < buffer_size && data != '\0') {
        str[index++] = data;
    } else {
        Serial.print("Received data: ");
        Serial.println(str);
        reset_string();
    }
}

void setup() {
    Serial.begin(9600);
    pin_configure();
    sei(); // global interrupts enable
    configure_uart3();
}

void loop() {
    volatile long i;
    transmit_string("HELLO WORLD");
    for (i = 0; i < 200000; i++);
}
mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15