/*
 * tester_master.c
 *
 * Created: 11.4.2016 23:32:58
 *  Author: tomino
 */ 


#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "displej.h"
#include "menu.h"
#include "TWI_MASTER.h"
#include "SPI_master.h"
#include "testy_master.h"

const PROGMEM uint8_t selftest[] =
{255,0,1,2,24,0,18,19,10,32,18,40,0,0};	//vodič 25, pruchozi/0000, konektor A/00, piny 8/9, nuly pro ukonceni smycky
const PROGMEM uint8_t ukazkova_data[]={'A','S','C',' ','1','3','0',' ',' ',' ',' ',' ',' ',255,0,1,2,24,0,18,19,10,0,18,40,0,0,0};

uint8_t data[611],  *p_data;
uint16_t ukazatel=0, i=0;
const uint8_t *p_selftest, *p_ukazka;

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

void nuluj_data(void)
{
	for (i=0;i<612;i++)
	{
		data[i]=0;
	}
}


uint8_t nahraj_data(uint8_t ukazatel)	//nacita soubor z pameti a zpracovava a distribuuje data
{
	uint32_t adr=0;
	uint8_t adr_1=0, adr_2=0, adr_3=0, byte_1=0, byte_2=0, byte_3=0, byte_4=0, i=0, TWI_adr=0;
	char nazev[13];
	vymazLCD();
	adr=adresa(ukazatel);				//4bajty, tri z nich obsahuji adresu, nutno preskocit delku nazvu
	//deleni adresy do jednotlivych bajtu
	adr_3=adr;
	adr_2=adr>>8;
	adr_1=adr>>16;
	
	PORTB &= ~(1<<PB0);				//CS je nula pro otevreni kanalu
	SPI_nahrej(3);					//prikaz pro cteni	
	//adresa (3byty)
	SPI_nahrej(adr_1);
	SPI_nahrej(adr_2+213);
	SPI_nahrej(adr_3);
	adr=0;
	while (adr<14)
	{
		SPI_nahrej(15);
		nazev[adr] = SPDR;
		adr++;
	}
	nazev[13]=0;
	zapistext(1,1,"test:");
	zapistext(1,7,nazev);
	
	//nahrani bytu do pameti
	SPI_nahrej(15);
	byte_1=SPDR;
	SPI_nahrej(15);
	byte_2=SPDR;
	SPI_nahrej(15);
	byte_3=SPDR;
	SPI_nahrej(15);
	byte_4=SPDR;
	i=0;
	//vyhodnoceni dat a rozeslani
	while ((byte_1 != 0) | (byte_2 != 0))				//pouze v pripade ze jsou na danych pozicich data
	{
		data[(3*i)+1]=byte_1;							//ulozi data pro vypis vysledku
		data[(3*i)+2]=byte_2;
		//adresa vystupu
		if ((byte_3 & 0b00000010)==2)	TWI_adr=108;
		else	TWI_adr=100;
		while (byte_3>50)
		{
			TWI_adr = TWI_adr+2;
			byte_3 = byte_3 - 51;
		}
		byte_3= (byte_3+0b10000000);
		byte_3= TWI_data(i, byte_3+1, TWI_adr);
		if (byte_3 == 0)						//nahravani se nepovedlo
		{
			TWI_instrukce (254);
			vymazLCD();
			zapistext (3,7, "INT. ERR");
			byte_3= tlacitka();
			return 5;
		}
		
		//adresa vstupu
		if ((byte_2 & 0b00000001)==1)	TWI_adr=110;
		else	TWI_adr=102;
		while (byte_4>51)
		{
			TWI_adr = TWI_adr+2;
			byte_4 = byte_4 - 51;
		}
		byte_4= TWI_data(i, byte_4+1, TWI_adr);
		if (byte_4 == 0)
		{
			TWI_instrukce (254);
			vymazLCD();
			zapistext (3,7, "INT. ERR");
			byte_4= tlacitka();
			return 5;
		}
		
		//nahrani dalsich 4 bytu pro dalsi cyklus
			SPI_nahrej(15);
			byte_1=SPDR;
			SPI_nahrej(15);
			byte_2=SPDR;
			SPI_nahrej(15);
			byte_3=SPDR;
			SPI_nahrej(15);
			byte_4=SPDR;
			i++;
	}
	
	PORTB |= (1<<PB0);				//uzavre kanal k pameti
	TWI_instrukce(254);				//vypne programovaci mod
	return 0;
}

/***************************************************************************************************************
											HLAVNI SMYCKA PROGRAMU
***************************************************************************************************************/

int main(void)
{
	DDRA=(255);
	PORTA=(0);				//zapne portA jako vystup bez pullup rezistoru
	zapniTWI_master();
	zapni_SPI_master();
	zapniLCD();
	zapistext(2,5,"AHOJ");
	DDRC=0;					//vstupy
	PORTC=255;				//pull-up rezistory
	p_data = &data[0];
	p_selftest = &selftest[0];
	ukazatel=PINC;			//nacte stav tlacitek
	
	for (i=0; i<10; i++)
	{
		_delay_ms(100);
		if (ukazatel==25)		//skryte menu pro mazani
		{
			skryte_menu(p_selftest, p_data);
			while (ukazatel != 4)
			{
			testuj(p_data);
			vypis_vysledku(p_data);
			//dotaz na opetovné testování
			zapistext(2,5,"testovat znovu?");
			zapistext(3,5,"   ANO         ");
			zapistext(4,5,"   NE          ");
			ukazatel = 4;
			sipky(ukazatel);
			i = tlacitka();
			while (i != 252)
			{
				switch (i)
				{
					case 243:
					ukazatel = 3;
					break;
					
					case 143:
					ukazatel = 4;
					break;
				}
				sipky(ukazatel);
				i = tlacitka();
			
			}
			}
			i=11;				//vyskoci ze smycky
			vymazLCD();
	}
	
	ukazatel=PINC;			//nacte stav tlacitek pro dalsi cyklus
	}
	vymazLCD();
	nuluj_data();
	
	while(1)
    {
		p_data = &data[0];
		p_selftest = &selftest[0];
		ukazatel=vyber_svazku();
		ukazatel=nahraj_data(ukazatel);
		if (ukazatel == 0)
		{
			
		}
		else nuluj_data();		//pri neuspesnem nahrani dat se data vynuluji
    }
}