#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>

#define BUFLEN		20
#define STX			2
#define ETX			3

#define BAUD 9600
#define UBRR F_CPU/16/BAUD-1

char			RxBuf[20];
unsigned char	rx_index;
//------------------------------------------------------------------------------
void USART_Transmit_Text (char *text) {
	unsigned char	i;
	for (i=0; i<strlen(text); i++) {
		while(!(UCSR0A & (1 << UDRE0)));
		UDR0 = text[i];
	}
}
//------------------------------------------------------------------------------
ISR (USART_RX_vect)		//Obsluha prerusenie od RX
{
	char	temp, prikaz_ok = '?';
	
	temp = UDR0;
    // Začiatok rámca
	if (temp == STX) {rx_index = 0; return;}
	// Ukladanie do bufferu (ochrana proti pretečeniu)
    if (rx_index < (BUFLEN-1)) RxBuf[rx_index++] = temp;
	// Koniec rámca
    if (temp == ETX) {
		if (rx_index > 0) rx_index--;   // odstrániť ETX
        RxBuf[rx_index]='\0'; 
        // vráť čo si prijal
		USART_Transmit_Text(RxBuf);
        // test príkazu 
		if (!strcmp (RxBuf, "Reset")) {
            wdt_enable(WDTO_15MS);
            while (1);
        }
		else if (!strcmp (RxBuf, "Zapni")) {
            prikaz_ok = '+';
            PORTB |= (1<<PORTB0);
        }
		else if (!strcmp (RxBuf, "Vypni")) {
            prikaz_ok = '+';
            PORTB &= ~(1<<PORTB0);
        }
		else if (!strcmp (RxBuf, "EInt0")) {
            prikaz_ok = '+';
            EIFR |= 1<<INTF0;
            EIMSK |= 1<<INT0;
        }
		RxBuf[0] = prikaz_ok;
        RxBuf[1] = '\n';
        RxBuf[2] = '\r';
        RxBuf[3] = '\0';
		USART_Transmit_Text(RxBuf);
	}
	return;
}
//------------------------------------------------------------------------------
ISR (INT0_vect) //Obsluha externeho prerusenia INT0
{ 
	EIFR |= 1<<INTF0;				//Clear External INT0 Flag
    EIMSK &= ~(1<<INT0);			//Disable INT0
	USART_Transmit_Text ("\nINT0 Disabled\n");
}
//--------------------------------------------------------------------
void USART_Init (unsigned int ubrr)	//Serial port komunikacia
{
	// set baud rate
	UBRR0H = (unsigned char)(ubrr>>8);
	UBRR0L = (unsigned char)ubrr;
	// Enable receiver and transmitter and interrupt;
	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
	//Set Frame format: 8data 1stop
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
//-------------------------------------------------------------------
void INT0_Init (void)			//Inicializacia INT0
{
	PORTD |= 1<<PORTD2;				// Enable PD2 pull-up resistor
	EICRA |= 1<<ISC01 | 1<<ISC00;	// Trigger INT0 on rising edge
	EIFR |= 1<<INTF0;				// Clear External INT0 Flag
	EIMSK |= 1<<INT0;				// Enable INT0
}
//------------------------------------------------------------------------------
int main (void) {
	
	wdt_enable(WDTO_2S);
	DDRB |= (1<<DDB5) | (1<<DDB0);	//nastavenie vyvodov LED a PB0 (LED1) na vystup
	USART_Init (UBRR);
	INT0_Init ();
	sei();
	
	USART_Transmit_Text ("\nTEST Komunikacie cez Tx a Rx");
	USART_Transmit_Text ("\nReset - Reset MCU");
	USART_Transmit_Text ("\nZapni - Zapne LED1");
	USART_Transmit_Text ("\nVypni - Vypne LED1");
	USART_Transmit_Text ("\nEInt0 - Povoli ext. prerusenie 0");
	
	while(1) { 
		wdt_reset();
		PORTB |= (1<<PORTB5); _delay_ms (50);
		PORTB &= ~(1<<PORTB5); _delay_ms (500);
		PORTB |= (1<<PORTB5); _delay_ms (50);
		PORTB &= ~(1<<PORTB5); _delay_ms (1000);
	}
}
//------------------------------------------------------------------------------

