#include"funkce.h"

volatile unsigned int sp_k_imp_cer=56;//spravne pocty impulsu pro kontrolu kodovani
volatile unsigned int sp_k_imp_zm=28;//50Hz
volatile unsigned int sp_k_imp_zl=14;
volatile unsigned int sp_k_imp_zel=10;


volatile unsigned int sp_s_imp_cer=56;//50Hz
volatile unsigned int sp_s_imp_zm=28;
volatile unsigned int sp_s_imp_zl=14;
volatile unsigned int sp_s_imp_zel=10;

static volatile unsigned char poc_pretec_c1=0;
volatile unsigned char znak=0;

//******************************************************************************
void nastav_c1(void)
{
//******************************************************************************
//               Nastavení čítače 1/ interní krystal 1MHz, preteceni 2Hz
//******************************************************************************
//COM1Ax - generování signálu OC1A
//COM1Bx - generování signálu OC1B
//WGM1x  - režim čítače
TCCR1A=((0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(0<<WGM11)|(0<<WGM10));
TCNT1=0;
OCR1A=0;
OCR1B=0;
ICR1=62499;
//ICNC1 - povolí sejmutí
//ICES1 - vybírá hranu sejmutí
//WGM1x - režim čítače
//CS2x  - vstupní frekvence čítače
TCCR1B=((0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10));
//TOIE1  - povolí přerušení při přetečení
//sbi(TIMSK,TOIE1);
//TICIE2 - povolí přerušení při sejmutí čítače
//sbi(TIMSK,TICIE1);
//OCIE1A - povolí přerušení při komparaci s registrem A
sbi(TIMSK,OCIE1A);
//OCIE1B - povolí přerušení při komparaci s registrem B
//sbi(TIMSK,OCIE1B);
sei();
poc_pretec_c1=0;
}
//*******************************************************************************
void init(void)
{
	DDRC=0;
	PORTC=0xff;		//nastaveni brany C, jako vstupni, zap. pull-up rezistoru
		
	DDRD=0;			//nastaveni brany D
	PORTD=0xff;

	DDRB=1<<PB1;	//nastaveni brany B bit PB1 vystupni
	schyba;
	OSCCAL=181;		//kalibrace interniho oscilatoru




	unsigned char pomoc=0;
	unsigned int impulsy=0;
	for(unsigned int i=0;i<100;i++) {_delay_ms(1);}
	nastav_c1();
	while(poc_pretec_c1<2)		//mereni frekvence sig. napeti trojnasobne nacitani
	{
			if(u24)
			{
				_delay_us(5);
				if(u24)
				{
					_delay_us(5);
					if(u24)
					{
						if(pomoc){impulsy++;pomoc=0;}
					}
					
					
					
				}
			}
		
			else
			{
				_delay_us(5);
				if(!u24)
				{
					_delay_us(5);
					if(!u24)
					{
					pomoc=1;
					}
				
				}
			}
		
	}
	cli();
	if(impulsy>120)				// podle zmerene frekvence sig. napeti prirad spravne hodnoty impulsu
	{
		sp_k_imp_cer=84;		//kodovaci pulperioda pro 75Hz
		sp_k_imp_zm=42;
		sp_k_imp_zl=21;
		sp_k_imp_zel=14;
		
		sp_s_imp_cer=84;		//signalni pulperioda 75Hz
		sp_s_imp_zm=42;
		sp_s_imp_zl=21;
		sp_s_imp_zel=14;
		
	}
	if (impulsy>400)
	{
		sp_s_imp_cer=306;					//signalni pulperioda pro 275Hz
		sp_s_imp_zm=153;
		sp_s_imp_zl=77;
		sp_s_imp_zel=51;
	}



	
}

//**********************************************************************************
ISR(TIMER1_COMPA_vect)//obsluha preruseni inkrementace pocitadla
 {
	poc_pretec_c1++;
 }
//***********************************************************************************

void test_vstupu (void)
{
	unsigned char brana_C=0;
	
	brana_C=PINC;							//opetovne nacteni kvuli zakmitum
	_delay_us(200);
	if(brana_C!=PINC) return;				//ochrana proti ruseni
	
	switch (brana_C)						//prirad zvoleny rezim
	{
		case 0b111110:znak=24;break;		//cervena
		case 0b111101:znak=12;break;		//zlute mezikruzi
		case 0b111011:znak=6;break;			//zluta
		case 0b110111:znak=4;break;			//zelena
		case 0b101111:znak=24;break;		//test, zde cervena
		case 0b011111:znak=33;break;		//signalni napeti
		default: znak=66;					//zakaz
	}		
	
}
//************************************************************************************

void f_chyba(void)
{
	schyba;			//nastav chybovy vystup
	for(;;){}
}
//************************************************************************************
void k_kodovani(unsigned char s_p_k_imp,unsigned char s_p_s_imp)
{
	unsigned char pomoc=0,barva=0,imp=0,poc_chyb=0,poc_spravnych=0;
	nastav_c1();
	poc_pretec_c1=0;
	barva=znak;
	for(;;)								//kodovaci pulperioda dobeh stareho kodu
	{
		if(!i24)break;					//pokud protece sig. proud ukonci pulperiodu
		test_vstupu();
		if(barva!=znak) return;			//pokud nastala zmena prac. rezimu jednotky return
		if(poc_pretec_c1>2) f_chyba();	//pokud vyprsi timeout tak chyba
	}
	poc_pretec_c1=0;					//signalni pulperioda dobeh stareho kodu
	for(;;)
	{
		if(!i13)break;
		test_vstupu();
		if(barva!=znak) return;
		if(poc_pretec_c1>2) f_chyba();
	}
	//*****************************
	//kontrola noveho kodu
	while(barva==znak)
	{
		if(poc_spravnych>100)			//pokud probehlo 100 bezproblemovych pulperiod, tak dekrementuj pocet chyb
		{
			if(poc_chyb>0)poc_chyb--;
		}
		if(poc_chyb>=2) f_chyba();
		imp=0;
		poc_pretec_c1=0;
		pomoc=0;
		while(poc_pretec_c1<=2)			//kodovaci pulperioda
		{
			if(!i24)break;
			if(!i13)					//pocitani impulsu kodovaciho proudu
			{
				_delay_us(5);			//opakovane nacteni
				if(!i13)
				{
					if(!pomoc) {imp++;pomoc=1;}
				}
			}
			else 
			{
				_delay_us(5);
				if(i13)pomoc=0;
				
			}
		}
		if(imp<(s_p_k_imp-2)){poc_chyb++;poc_spravnych=0;}//vyhodnoceni
		if(imp>(s_p_k_imp+2)){poc_chyb++;poc_spravnych=0;}
		else poc_spravnych++;
		imp=0;
		poc_pretec_c1=0;
		pomoc=0;
		while(poc_pretec_c1<=2)								//signalni pulperioda
		{
			if(!i13)break;
			if(!i24)										//pocitani impulsu sig. proudu
			{
				_delay_us(5);
				if(!i24)
				{
					if(!pomoc) {imp++;pomoc=1;}
				}
			}
			else 
			{
				_delay_us(5);
				if(i24)pomoc=0;
			}
			
		}
		if(imp<(s_p_s_imp-2)){poc_chyb++;poc_spravnych=0;}//vyhodnoceni
		if(imp>(s_p_s_imp+2)){poc_chyb++;poc_spravnych=0;}
		else poc_spravnych++;
			
			
		poc_pretec_c1=0;
		for(;;)												//kodovaci pulperioda
		{
			if(!i24)break;
			test_vstupu();
			if(barva!=znak)return;
			if(poc_pretec_c1>2) f_chyba();
		}
		poc_pretec_c1=0;
		for(;;)												//signalni pulperioda
		{
			if(!i13)break;
			test_vstupu();
			if(barva!=znak)return;
			if(poc_pretec_c1>2) f_chyba();
		}
	}
	
	
	
}
//*********************************************************************************************

void k_s_nap(void)			// kontrola rezimu pripojeneho sig. napeti
{
	unsigned char barva=0;
	nastav_c1();
	barva=znak;
	while(barva==znak)
	{
	if(!(i24))
	{
		_delay_us(10);
		if(!i24)poc_pretec_c1=0;
	}
	if(poc_pretec_c1>1)f_chyba();
	test_vstupu();
	
		
		
		
	}
}
//**********************************************************************************************

void k_vypnuto(void)		//kontrola stavu vypnuto
{
	unsigned char barva=znak;
	
	for(unsigned char i=0;i<200;i++)_delay_ms(10);
	for(;;)
	{
		test_vstupu();
		if(barva!=znak) return;
		if(!i24|!i13)
		{
			_delay_us(50);
			if(!i24|!i13) f_chyba();			
		
		}		
	
	}
	
}


