//--------------------Komunikace pomocí rozhraní UART -----------------------------
//---------------------------------------------------------------------------------
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define LCD
#include "mojelib1.h"

// globální proměné----------------------------------------------------------------
char znak = 0;			// znak z klávesnice určen k zapsání přes UART
char p_vyslano = 7;		// pozice vyslaného znaku v poli
char p_prijato = 7;		// pozice prijateho znaku v poli
char prijato[10];		// pole prijatých znaků
char vyslano[10];		// pole vyslaných znaků
//prototypy------------------------------------------------------------------------
void klavesa(void); 	// podprogram pro čtení z klávesnice
void vypis(void);		// podprogram pro výpis na LCD

//-------------------hlavní program------------------------------------------------
int main (void)
{
	// nastavení UART rozhraní---------------------------------------------
	UCSRA = 0b00100000;	// vymazání zásobníku UDR
	UCSRB = 0b10011000;	// přerušení při kompletním příjmu, povolení módu přijímače a vysílače
	UCSRC = 0b10000110;	// asynchronní mód - rámec 8N1 (8dat. bitů, bez parity, 1 stop bit)
	UBRRL = 103;		// pro SR = 9600 baud;

	// nastavení periférií a LCD ------------------------------------------
	DDRB=0xff;			// nastavení DDR pro LCD a nastavení PORTUC
	DDRC = 0xff;		
	PORTC = 0b11000010;	// nastavení LCD
	init_lcd();			// inicializace LCD
	_delay_ms(10);
	cls();				// smazání LCD displeje
	_delay_ms(10);
	

	sei();				// povolení přerušení

	while(1)
	{
		klavesa();		// načti znak z klávesnice
		vypis();		// vypiš aktuální znaky
	}
}


void klavesa(void)				// čtení z klávesnice
{
	DDRA=0x00;			// nastavení registrů pro klávesnici
	DDRB=0xff;
	DDRD=0b10110011;	

	// ostatní sloupce kromě prvního musí být v logické 1
	PORTD |= 0x33;
	
	PORTB &= 0b11111100;	//chci 1 sloupec  (1,4,7,*)
	_delay_ms(2);
		if (!(PINA&0b00000100)) znak='1';
		if (!(PINA&0b00001000)) znak='4';
		if (!(PINA&0b00100000))	znak='7';
		if (!(PINA&0b01000000))	znak='*';
	PORTB|=0b00000010;  // první sloupec nastavit opět do logické 1


	PORTD&=0b11011111;	//chci 2. sloupec (2,5,8,0)
	_delay_ms(2);
	   	if (!(PINA&0b00000100)) znak='2';
		if (!(PINA&0b00001000)) znak='5';
		if (!(PINA&0b00100000)) znak='8';
		if (!(PINA&0b01000000))	znak='0';
	PORTD |=0b00100000;

	
	PORTD&=0b11101111;	//chci 3. sloupec (3,6,9,#)
	_delay_ms(2);
		if (!(PINA&0b00000100)) znak='3';
		if (!(PINA&0b00001000)) znak='6';
		if (!(PINA&0b00100000)) znak='9';			
		if (!(PINA&0b01000000)) znak='#';
	PORTD |=0b000100000;

	if(znak!=0)		// pokud je znak různý od 0
	{
		if (p_vyslano==17)		// pokud je dosaženo nad limit adresace v poli
		{
			cls();				// vymaže displej a vynuluje hodnoty
			_delay_ms(10);
			for(int i=0;i<10;i++)
				vyslano[i]=0;
			p_vyslano=7;		// resetuje počítadlo
		}
		vyslano[p_vyslano-7] = znak;	// uloží do pole nový znak
		UDR = znak;						// vyšle znak přes UART znak
		znak = 0;						// nuluje znak
		p_vyslano++;					// posune se adresace na další prvek v poli
	}
}

ISR (USART_RXC_vect)				// přerušení při kompletním příjmu
{
	if (p_prijato==17)				// pokud je dosaženo max. velikosti pole
	{
			cls();					// vymaže pole a displej
			_delay_ms(10);
			for(int i=0;i<10;i++)
				prijato[i]=0;
			p_prijato=7;			// resetuje počítadlo - adresu v poli
	}
	prijato[p_prijato-7] = UDR;		// uloží do pole přijatou hodnotu
	p_prijato++;					// posune se v poli
	
	
}


void vypis (void)					// výpis hodnot na displeji
{
		gotoxy(1,1);				// pevně fixovaný výpis na LCD
		lcd_text("Posli:");
		gotoxy(2,1);
		lcd_text("Doslo:");

		for(int i=7; i<p_vyslano;i++)	// výpis pole odeslaných hodnot od začátku do dosaženou hodnotu
		{
			gotoxy(1,i);
			lcd_c(vyslano[i-7]);
		}

		for(int i=7; i<p_prijato;i++)	// výpis pole přijatých hodnot od začátku po dosaženou hodnotu
		{
			gotoxy(2,i);
			lcd_c(prijato[i-7]);
		}		
		
		_delay_ms(100);					// časová prodleva

}

