/* 
Program, ktery po precteni dat z UARTu nastavi vstup a pocet mereni (konstantni rychlost vzorkovani) 
vysle po kazdem mereni data na UART. Po poslednim mereni vysle zakoncovaci kod.
*/

#include <avr/io.h>
#include <avr/interrupt.h> // knihovna pro preruseni


#define FOSC 8000000	// rychlost CPU
#define BAUD 9600		// rychlost prenosu

void nastav_pocet(uint8_t);		//prototyp funkce pocet mereni
void nastav_vstup(uint8_t);		//prototyp funkce vyber kanalu ADC

uint8_t pocet = 0;			//def promenne
uint8_t test = 0;			//def promenne

int i;						//def promenne


int main( void )			//hlavni program - zde nnaplnime registry a povolime preruseni 
{

	ADMUX=(1<<REFS0|0<<MUX0);										//AD0 převodník nastaveni vtupu
	ADCSRA=(1<<ADPS2|1<<ADPS1|1<<ADPS0|1<<ADATE|1<<ADIE);	//povoleni AD přev, a nastaveni preddelicky
	UCSRB=(1<<TXEN|1<<RXEN|1<<RXCIE);						// povoleni vysilani UART, 
	UCSRC=(3<<UCSZ0|(1<<USBS)|1<<URSEL);					//8bit slovo, asynch prenos 
	UBRRL=FOSC/16/BAUD-1;									// NASTAVENI RYCHLOSTI prenosu reg1
	UBRRH=((FOSC/16/BAUD-1)>>8);							// NASTAVENI RYCHLOSTI prenosu reg2


sei();				//povoleni preruseni
while(1);			//nekonecna smycka - pro vyplneni volnych chvil uP
}



ISR( ADC_vect )				// preruseni kdzy skonci AD prevod
{	
	i++;									//pricte jednnicku k cislu vzorku
	
	loop_until_bit_is_set(UCSRA,UDRE);		//ceka na povoleni vysilani
			UDR=ADCH&0b00000011;	 		//vysle prvni pulku dat		
	
	loop_until_bit_is_set(UCSRA,UDRE);		//ceka na povoleni vysilani
			UDR=ADCL;						// posila druhou pulku dat
	
	loop_until_bit_is_set(UCSRA,UDRE);		//ceka na povoleni vysilani
			UDR=i;							// vysle cislo vyorku 
					
	pocet--;								//odecte jedno mereni
	
	if (pocet<1) 							// je-li posledni mereni pocet=0
		{
		ADCSRA&=~(1<<ADEN);					//vypne AD prevod
		loop_until_bit_is_set(UCSRA,UDRE);	//ceka na povoleni vysilani
			UDR=0x0A;						// oprv ysle znak LF (ASCII)
		loop_until_bit_is_set(UCSRA,UDRE);	//ceka na povoleni vysilani
			UDR=0x0D;						// opr vysle znak CR (ASCII)
		}
}



ISR( USART_RXC_vect )		//preruseni pri prijmu ramce USART
{


switch (test) {
	
	case 1:					//je-li test=1 tj. pozadavek na vstup 
	nastav_vstup (UDR);		// vyvola funkci nastaveni vstupu (bin data)
//	nastav_vstup (UDR-48);	// vyvola funkci nastaveni vstupu (ACII data-cislo)
	test = 0;				// nulovani polozky TEST - default hodnota
	break;
	
	case 2:					//je-li test=2 tj. poyadavek na pocet mereni 
	nastav_pocet (UDR);		// vyvola funkci pocet mereni
	test = 0;				// nulovani polozky TEST - default hodnota
	break;

	default:
	switch (UDR) {
		case 'v':		//prijde-li pozadavek na vstup
			test = 1;
		break;

		case 'p':		//prijde-li pozadavek na pocet mereni
			test = 2;
			i=0;
		break;
		
		default:
			loop_until_bit_is_set(UCSRA,UDRE);	//ceka na povoleni vysilani
			UDR=0xf9;							// kod chyba
		break;
		}
	break;
	}
}





void nastav_pocet(uint8_t poc)
{if (UDR>0)	
	
	{
		pocet=poc;		//prijme pocet mereni
		loop_until_bit_is_set(UCSRA,UDRE);		//ceka na povoleni vysilani
			UDR=pocet;							// vysle zpet pocet mereni
		
		ADCSRA|=(1<<ADEN|1<<ADSC);				// povoli a spusti AD prevodnik
	} 	

}



void nastav_vstup(uint8_t vstup) 
	{	

	if ((vstup<9)&&(vstup>0)) 				// cislo znaku musi byt mensi jak 8

		{	
			ADMUX=(1<<REFS0|(vstup-1)<<MUX0);		// nastavi vstup AD prevodniku
		
			loop_until_bit_is_set(UCSRA,UDRE);	//ceka na povoleni vysilani
			UDR=ADMUX;							// poznavaci kod pro odpoved na dotaz na port
		}
	else
		{							
			loop_until_bit_is_set(UCSRA,UDRE);	//ceka na povoleni vysilani
			UDR=0xf9;							// kod chyba
		}							
	}
