/*
 * testy.c
 *
 * Created: 25.2.2016 11:29:01
 *  Author: tomino
 */ 

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <math.h>
#include <stdint.h>


/******************************************************************************************************
										VNITRNI FUNKCE KNIHOVNY
******************************************************************************************************/

//je treba dopsat aktivaci A/D prevodniku a preruseni pro dokonceni prevodu.
void reset (void)	//všechny porty uvede do výchozího stavu, jako vstupy s pull-up rezistory
{
	DDRA=0; PORTA=255;
	DDRB=0; PORTB=255;
	DDRC=0; PORTC=255;
	DDRD=0; PORTD=255;
	DDRE=0; PORTE=255;
	DDRF=0; PORTF=255;
	DDRG=0; PORTG=255;
}

uint8_t vystup (uint8_t pin, uint8_t *maska)
{
	uint8_t port=0, i=0;
	while (pin > 7)
	{
		port++;
		pin = (pin-8); 
		i++;
	}
	switch (port)
	{
	case 0:
		switch (pin)
		{
		case 0:
			DDRA	|= (1<<DDA0);
			PORTA	&= ~(1<<PA0);
			break;
		case 1:
			DDRA	|= (1<<DDA1);
			PORTA	&= ~(1<<PA1);
			break;
		case 2:
			DDRA	|= (1<<DDA2);
			PORTA	&= ~(1<<PA2);
			break;
		case 3:
			DDRA	|= (1<<DDA3);
			PORTA	&= ~(1<<PA3);
			break;
		case 4:
			DDRA	|= (1<<DDA4);
			PORTA	&= ~(1<<PA4);
			break;
		case 5:
			DDRA	|= (1<<DDA5);
			PORTA	&= ~(1<<PA5);
			break;
		case 6:
			DDRA	|= (1<<DDA6);
			PORTA	&= ~(1<<PA6);
			break;
		case 7:
			DDRA	|= (1<<DDA7);
			PORTA	&= ~(1<<PA7);
			break;
		}
		break;
		
	case 1:
		switch (pin)
		{
			case 0:
				DDRB	|= (1<<DDB0);
				PORTB	&= ~(1<<PB0);
				break;
			case 1:
				DDRB	|= (1<<DDB1);
				PORTB	&= ~(1<<PB1);
				break;
			case 2:
				DDRB	|= (1<<DDB2);
				PORTB	&= ~(1<<PB2);
				break;
			case 3:
				DDRB	|= (1<<DDB3);
				PORTB	&= ~(1<<PB3);
				break;
			case 4:
				DDRB	|= (1<<DDB4);
				PORTB	&= ~(1<<PB4);
				break;
			case 5:
				DDRB	|= (1<<DDB5);
				PORTB	&= ~(1<<PB5);
				break;
			case 6:
				DDRB	|= (1<<DDB6);
				PORTB	&= ~(1<<PB6);
				break;
			case 7:
				DDRB	|= (1<<DDB7);
				PORTB	&= ~(1<<PB7);
				break;
		}
		break;
	case 2:
		switch (pin)
		{
			case 0:
				DDRC	|= (1<<DDC0);
				PORTC	&= ~(1<<PC0);
				break;
			case 1:
				DDRC	|= (1<<DDC1);
				PORTC	&= ~(1<<PC1);
				break;
			case 2:
				DDRC	|= (1<<DDC2);
				PORTC	&= ~(1<<PC2);
				break;
			case 3:
				DDRC	|= (1<<DDC3);
				PORTC	&= ~(1<<PC3);
				break;
			case 4:
				DDRC	|= (1<<DDC4);
				PORTC	&= ~(1<<PC4);
				break;
			case 5:
				DDRC	|= (1<<DDC5);
				PORTC	&= ~(1<<PC5);
				break;
			case 6:
				DDRC	|= (1<<DDC6);
				PORTC	&= ~(1<<PC6);
				break;
			case 7:
				DDRC	|= (1<<DDC7);
				PORTC	&= ~(1<<PC7);
				break;
		}
		break;
	case 3:
		switch (pin)
		{
			case 0:
				DDRD	|= (1<<DDD0);
				PORTD	&= ~(1<<PD0);
				break;
			case 1:
				DDRD	|= (1<<DDD1);
				PORTD	&= ~(1<<PD1);
				break;
			case 2:
				DDRD	|= (1<<DDD2);
				PORTD	&= ~(1<<PD2);
				break;
			case 3:
				DDRD	|= (1<<DDD3);
				PORTD	&= ~(1<<PD3);
				break;
			case 4:
				DDRD	|= (1<<DDD4);
				PORTD	&= ~(1<<PD4);
				break;
			case 5:
				DDRD	|= (1<<DDD5);
				PORTD	&= ~(1<<PD5);
				break;
			case 6:
				DDRD	|= (1<<DDD6);
				PORTD	&= ~(1<<PD6);
				break;
			case 7:
				DDRD	|= (1<<DDD7);
				PORTD	&= ~(1<<PD7);
				break;
		}
		break;
	case 4:
		switch (pin)
		{
			case 0:
				DDRE	|= (1<<DDE0);
				PORTE	&= ~(1<<PE0);
				break;
			case 1:
				DDRE	|= (1<<DDE1);
				PORTE	&= ~(1<<PE1);
				break;
			case 2:
				DDRE	|= (1<<DDE2);
				PORTE	&= ~(1<<PE2);
				break;
			case 3:
				DDRE	|= (1<<DDE3);
				PORTE	&= ~(1<<PE3);
				break;
			//PE4 a PE5 jsou piny pro TWI proto nejsou zde vyuzity
			case 6:
				DDRE	|= (1<<DDE6);
				PORTE	&= ~(1<<PE6);
				break;
			case 7:
				DDRE	|= (1<<DDE7);
				PORTE	&= ~(1<<PE7);
				break;
		}
		break;
	case 5:
		switch (pin)
		{
			case 0:
				DDRF	|= (1<<DDF0);
				PORTF	&= ~(1<<PF0);
				break;
			case 1:
				DDRF	|= (1<<DDF1);
				PORTF	&= ~(1<<PF1);
				break;
			case 2:
				DDRF	|= (1<<DDF2);
				PORTF	&= ~(1<<PF2);
				break;
			case 3:
				DDRF	|= (1<<DDF3);
				PORTF	&= ~(1<<PF3);
				break;
			case 4:
				DDRF	|= (1<<DDF4);
				PORTF	&= ~(1<<PF4);
				break;
			case 5:
				DDRF	|= (1<<DDF5);
				PORTF	&= ~(1<<PF5);
				break;
			case 6:
				DDRF	|= (1<<DDF6);
				PORTF	&= ~(1<<PF6);
				break;
			case 7:
				DDRF	|= (1<<DDF7);
				PORTF	&= ~(1<<PF7);
				break;
		}
		break;
	case 6:
		switch (pin)
		{
			case 0:
				DDRG	|= (1<<DDG0);
				PORTG	&= ~(1<<PG0);
				break;
			case 1:
				DDRG	|= (1<<DDG1);
				PORTG	&= ~(1<<PG1);
				break;
			case 2:
				DDRG	|= (1<<DDG2);
				PORTG	&= ~(1<<PG2);
				break;
			case 3:
				DDRG	|= (1<<DDG3);
				PORTG	&= ~(1<<PG3);
				break;
			case 4:
				DDRG	|= (1<<DDG4);
				PORTG	&= ~(1<<PG4);
				break;
		}
		break;
	}
	pin = pow(2,pin);
	if (pin>2) pin++;
	maska[i] = (maska[i] | pin);
	return 5;		
}

uint8_t vstup (uint8_t pin, uint8_t *maska)
{
	uint8_t i=0;
	while (pin > 7)
	{
		pin = pin-8;
		i++;
	}
	pin = pow(2,pin);
	if (pin>2) pin++;
	maska[i] = (maska[i] | pin);
	return 160;
	
	
}

/******************************************************************************************************
										VOLATELNE FUNKCE KNIHOVNY
******************************************************************************************************/

uint8_t test_soukromy (uint8_t *data, uint8_t pozice)
{
	reset();
	uint8_t byte=0, vysledek=0, i=0, j=0, maska[7], vstupy[7], *p_maska=0;
	byte = data[(3*pozice)+1];
	for (i=0;i<8;i++)
	{
		maska[i]=0;			//nuluje masku
		vstupy[i]=0;		//nuluje vstupy
	}
	if (byte != 0)
	{
		byte--;
		if (byte > 127)
		{
			byte = byte-128;
			if (byte > 35) byte = byte+2;
			p_maska=&maska[0];
			//vystup(byte, p_maska);
		}
		else
		{
			if (byte > 35) byte = byte+2;
			p_maska=&maska[0];
			vstup(byte,p_maska);
		}
	}
	byte = data[(3*pozice)+2];
	if (byte != 0)
	{
		byte--;
		if (byte > 35) byte = byte+2;
		p_maska=&maska[0];
		vstup(byte,p_maska);
	}
	else _delay_ms(5);
	vstupy[6] = (~PING & 0B00111111);
	vstupy[5] = (~PINF & 0b00001111);
	vstupy[4] = (~PINE & 0B11001111);
	vstupy[3] = (~PIND);
	vstupy[2] = (~PINC);
	vstupy[1] = (~PINB);
	vstupy[0] = (~PINA);
	vysledek = 100;
	byte=0;
	for (j=0;j<6;j++)
	{
		if ((maska[j] & vstupy[j]) == vstupy[j]) byte++;
		for (i=0;i<8;i++)
		{
			if ((maska[j] & 1) == 1) vysledek++;
			maska[j] >>= 1;
		}
		for (i=0;i<8;i++)
		{
			if ((vstupy[j] & 1) == 1) vysledek--;
			vstupy[j] >>= 1;
		}
	}
	
	//dodelani i=6 pro nevysvetlitelne potize s indexaci
	if ((maska[6] & vstupy[6]) == vstupy[6]) byte++;
	for (i=0;i<8;i++)
	{
		if ((maska[6] & 1) == 1) vysledek++;
		maska[6] >>= 1;
	}
	for (i=0;i<8;i++)
	{
		if ((vstupy[6] & 1) == 1) vysledek--;
		vstupy[6] >>= 1;
	}
	if (byte == 7) return 1;
	else if (vysledek <= 100) return 2;
	else return 3;
}


uint8_t test_verejny (uint8_t *data, uint8_t pozice)
{
	reset();
	uint8_t byte=0, vysledek=0, i=0, j=0, maska[7], vstupy[7], *p_maska=0;
	byte = data[(3*pozice)+1];
	for (i=0;i<8;i++)
	{
		maska[i]=0;			//nuluje masku
		vstupy[i]=0;		//nuluje vstupy
	}
	if (byte != 0)
	{
		byte--;
		if (byte > 127)
		{
			byte = byte-128;
			if (byte > 35) byte = byte+2;
			p_maska=&maska[0];
			vystup(byte, p_maska);
			vysledek=25;
		}
		else
		{
			_delay_ms(5);				//ceka na nastaveni vystupu z jineho kontroleru
			if (byte > 35) byte = byte+2;
			p_maska=&maska[0];
			vysledek = vstup(byte,p_maska);
		}
	}
	else return 25;
	byte = data[(3*pozice)+2];
	if (byte != 0)
	{
		byte--;
		if (byte > 35) byte = byte+2;
		p_maska=&maska[0];
		vysledek = vstup(byte,p_maska);
		vysledek=0;
	}
	_delay_ms(5);
	if (vysledek == 25) return 25;
	vstupy[6] = (~PING & 0B00111111);
	//vstupy[5] = (~PINF);
	vstupy[4] = (~PINE & 0B11001111);
	vstupy[3] = (~PIND); 
	vstupy[2] = (~PINC);
	//vstupy[1] = (~PINB);
	vstupy[0] = (~PINA);
	vysledek = 100;
	byte=0;
	for (j=0;j<6;j++)
	{
		if ((maska[j] & vstupy[j]) == maska[j]) byte++;
		for (i=0;i<8;i++)
		{
			if ((maska[j] & 1) == 1) vysledek++;
			maska[j] >>= 1;
		}
		for (i=0;i<8;i++)
		{
			if ((vstupy[j] & 1) == 1) vysledek--;
			vstupy[j] >>= 1;
		}
	}
	//dodelani i=6 pro nevysvetlitelne potize s indexaci
	if ((maska[6] & vstupy[6]) == maska[6]) byte++;
	for (i=0;i<8;i++)
	{
		if ((maska[6] & 1) == 1) vysledek++;
		maska[6] >>= 1;
	}
	for (i=0;i<8;i++)
	{
		if ((vstupy[6] & 1) == 1) vysledek--;
		vstupy[6] >>= 1;
	}
	//reset();
	if (byte==6) return 1;
	if (vysledek == 100) return 2;
	else return 3;
}

