// Program pro ovladac výtahu v kabině //


#include "i2c.h"


// *** Tlacitka *** //
#define TL_STP P2_4		// Tlacitko STOP
#define TL_ZVN P2_5		// Tlacitko ZVONEK

#define LED_STP P2_6	// Podsvetleni tlacitka STOP
#define LED_ZVN P2_7	// Podsvetleni tlacitka ZVONEK

#define LED_PRE P3_4	// LED pro signalizaci pretizeni

#define SNIMAC1 P3_6	// Snimac 1
#define SNIMAC2 P3_5	// Snimac 2

#define DVERE   P3_7	// Snimac zavrenych dveri

unsigned char data stav;
unsigned char data pom_P0;
unsigned char data key_pat[3]; // 24 tlacitek pro volbu patra
unsigned char data podsvet[3]; // maska podsvetleni


unsigned char data prichozi_patro;	// cislo patra prijate od mastera
unsigned char data prichozi_data;	// dalsi data prijate od mastera


// pro tlacitka STOP,ZVONEK a senzor DVERI
bit zm_stop;
bit zm_zvonek;
bit zm_dvere;
bit castzpravy;



// *************************************************************************************************************** 
void delaynop(unsigned char time) //cca 1x = 50us
{
    while (time>0)
    {    
        delay();
		delay();
		delay();
		time--;
    }
}

void delay_ms(unsigned char pocet) // pocet * 1ms 
{
	unsigned char i;
	for (i=0;i<pocet;i++)
	{
		delaynop(20); // 20 x 50us = 1ms
	}
}


// ***MAX6953******************************************************************************************************
// LED DISPLEJ
void Disp_Config(unsigned char on_off, unsigned char blink, unsigned char blnk_spd)
{
    unsigned char flag = 0x00;
    if (on_off)   flag |= NORMOP;		// Zapnut / Vypnut
    if (blnk_spd) flag |= FSTBLNK;		// Blink 2Hz (rychly)  / Blink 1Hz (pomaly)
    if (blink)    flag |= BLNKENBL;	    // Blink povolen     / Blink zakazan
    MAX_write( ADDR5300, CONFIG, flag);
}

/*void Disp_Tst(unsigned char on_off)		// 1-Test zapnut / 0-Test vypnut
{
    MAX_write( ADDR5300, DISP_TST, on_off); // Test displeje, rozsviti se cely display
}*/

void Disp_Intens(unsigned char intenzita) // 0x0 - nejnizssi, 0xF - nejvyssi
{
    unsigned char intenz = (intenzita << 4) + intenzita; 	//posouvá se proto že bity 0-3 jsou pro jeden displej a 4-7 pro druhý 
    MAX_write( ADDR5300, INTENS10, intenz); 				// displej 0 a 1
    MAX_write( ADDR5300, INTENS32, intenz);					// displej 2 a 3
}
//LED DISPLEJ KONEC
// ***END**********************************************************************************************************


// ******* MAX 6955 ******* //
void MAX6955_Config(unsigned char on_off, unsigned char nks, unsigned char scanlmt) // Nastaveni obvodu s tlacitkama
{
    unsigned char flag = 0x00;		
	if (on_off) flag = NORMOP;          			//Když je zaplý tak flag=NORMOP- normálně funkcní
	MAX_write( ADDR5500, CONFIG, flag); 			// A to nahrajeme do konfiguračního registru
    MAX_write( ADDR5500, PORT_CNFG, nks); 			// nks - number of keys scan // KEYS_8 = 1, KEYS_16 = 2, KEYS_24 = 3, KEYS_32 =4
	MAX_write( ADDR5500, SCAN_LIMT, scanlmt);		// scan limit 1 az 8, 0x00 = 1, 0x03 = 4, 0x07 = 8
													// Zapnuti a nastaveni obvodu pro skenovani
													// pocet klaves = KEYS_X * scan limit, max 32 klaves
													// V našem pripade KEYS_24 a 0x07= 3*8=24 tlacitek
}
// *******  KONEC   ******* //

// ******* MAX 6956 ******* //
void MAX6956_Config(unsigned char on_off, unsigned char current)		// Nastavení obvodu pro podsvětlení tlacítek
{
    unsigned char flag = 0x00;
    if (on_off)   flag |= NORMOP;				// Pokud je zaponut tak uprav a nastav dispnej do chodu
    if (current)  flag |= INDICUR;				// Pokud je current v log1 zapne se indivudualní nastavení proudu diodama (nechceme proto log0) 
    MAX_write( ADDR5600, CONFIG, flag);			// Zapíše nastavení do registru CONFIG
}


/* void MAX6956_Test(unsigned char on_off)	//0 - test off, 1 - test on
{
    MAX_write( ADDR5600, DISP_TST, on_off); //- TEST Podsvetlení tlacítek
}
*/

void MAX6956_GlobalCur(unsigned char current) // Nastaveni proudu diodama rozsah 0x00 az 0x15 odpovida 1.5mA - 24mA 
{
    MAX_write( ADDR5600, GLOB_CUR, current);
}

void MAX6956_ActiveLED(unsigned char mask[3])    // inv mask[0] = p8 p7 p6 p5 p4 p3 p2 p1
{   unsigned char pom = 0;
    MAX_write( ADDR5600, PCM4, 0x00);
    MAX_write( ADDR5600, PCM8, 0x00);
    MAX_write( ADDR5600, PCM12, 0x00);
    MAX_write( ADDR5600, PCM16, 0x00);
    MAX_write( ADDR5600, PCM20, 0x00);
    MAX_write( ADDR5600, PCM24, 0x00);
    MAX_write( ADDR5600, PCM28, 0x00); 
    if ((mask[0] & 2) == 0) pom  = 2;
    if ((mask[0] & 8) == 0) pom |= 1;
    MAX_write( ADDR5600, RBP4_7, pom);
    pom = 0;
    if ((mask[0] & 4) == 0) pom  = 2;
    if ((mask[0] & 1) == 0) pom |= 1;
    MAX_write( ADDR5600, RBP30_31, pom);
    pom = ~mask[0];
    pom >>= 4;
    MAX_write( ADDR5600, RBP6_13, pom);
    pom = ~mask[1];
    MAX_write( ADDR5600, RBP10_17, pom);
    pom = ~mask[2];
    MAX_write( ADDR5600, RBP18_25, pom);
}
// *******  KONEC   ******* //


void Init(void)
{   P0 = 0xFF;		// Nastaveni vystupu portu P0 na log. 0
    P1 = 0xFF;		// Nastaveni portu P1 pro cteni
    SCL = 1;		// I2C Clock pro display 
    SDA = 1;		// I2C Data pro display
    TL_STP = 1;		// Tlacitko vypnuto (signaly jsou negované)
    TL_ZVN = 1;		// Tlacitko vypnuto (signaly jsou negované)
    LED_STP = 0;	// LED stop tlacitka vypnuta
    LED_ZVN = 0; 	// LED zvonku vypnuta
	LED_PRE = 0;
    SNIMAC1 = 1;	// Snimac neni sepnit (negovany signal)
    SNIMAC2 = 1;	// Snimac neni sepnit (negovany signal)
    DVERE   = 1;	// Snimac dveri
    zm_stop = 0;	// Pomocny bit pro stop tlacitko
    zm_zvonek = 0;	// Pomocny bit pro zvonek
	zm_dvere = 0;	// Dvere jsou otevreny

    key_pat[0] = 0; // Zadne tlacitko neni seple [08/07/06/05/04/03/02/01]
    key_pat[1] = 0; // Zadne tlacitko neni seple [16/15/14/13/12/11/10/09]
    key_pat[2] = 0; // Zadne tlacitko neni seple [24/23/22/21/20/19/18/17]

    podsvet[0] = 0xFF;	// Zhasnuto podsvetleni 1111 1111
    podsvet[1] = 0xFF;	// Zhasnuto podsvetleni 1111 1111
    podsvet[2] = 0xFF;	// Zhasnuto podsvetleni 1111 1111

    castzpravy = 0;

    /**** Nastaveni preruseni ****/
    IT0 = 1;   // Configure interrupt 0 (pro sestupnou hranu je-li IT0 = 1) /INT0 (P3.2)
    IT1 = 1;
    EX0 = 1;   // Enable EX0 Interrupt
    EX1 = 1;
    EA = 1;
    /**** MAX6953 ****/
    Disp_Config(1,1,1);    // Zapne ovladac displeje s blikanim 2Hz
    //Disp_Tst(1);
    Disp_Intens(0x7); // Nastaveni stredni intenzity svitivosti displeje
    //MAX_write( ADDR5300, D0P0, CH_NIC);    MAX_write( ADDR5300, D0P1, CH_NIC);
    //MAX_write( ADDR5300, D1P0, CH_NIC);    MAX_write( ADDR5300, D1P1, CH_NIC);
    //MAX_write( ADDR5300, D2P0, CH_NIC);    MAX_write( ADDR5300, D2P1, CH_NIC);
    /**** MAX6955 ****/
    MAX6955_Config(1,KEYS_24,0x07);	//Zapnuti obvodu pro tlacitka 1-24 a nastaveni 24 tlacitek
    MAX_write( ADDR5500, KEY_A_MSK, 0xFF); // povoleni preruseni pro 8 tlacitk
    MAX_write( ADDR5500, KEY_B_MSK, 0xFF); // povoleni preruseni pro dalsich 8 tlacitk
    MAX_write( ADDR5500, KEY_C_MSK, 0xFF); // povoleni preruseni pro pouzivane tlacitka
    /**** MAX6956 ****/
    MAX6956_Config(1,0);			//Zapnuti obvodu podsvetleni
    //MAX6956_Test(1);
    MAX6956_GlobalCur(0x07);		// Nastaveni proudu (svitivosti)
    MAX6956_ActiveLED(podsvet);		// Rozsviti ledky, ktere se maji.
    /***/
    
	
	stav=0;
    if ((P1 & 0x70) == 0x20) stav=1;
    else if ((P1 & 0x70) == 0x30) stav=2;
    else if ((P1 & 0x70) == 0x40) stav=3;
    else if ((P1 & 0x70) == 0x50) stav=4;
    else if ((P1 & 0x70) == 0x60) stav=5;
    else if ((P1 & 0x70) == 0x70) stav=6;
}
// ZOBRAZENI NA DISPLEJI /////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Zobraz_na_3(unsigned char znak1, unsigned char znak2, unsigned char znak3)
{   
	MAX_write( ADDR5300, D0P0, znak1);MAX_write( ADDR5300, D0P1, znak1);
    MAX_write( ADDR5300, D1P0, znak2);MAX_write( ADDR5300, D1P1, znak2);
    MAX_write( ADDR5300, D2P0, znak3);MAX_write( ADDR5300, D2P1, znak3);
}


void Disp_Porucha(void)
{   
	// DOSLO K PORUSE PORUCHU RESIME
	unsigned char cas=450;
	Zobraz_na_3(CH_POML,CH_NIC,CH_D);delay_ms(cas);
	Zobraz_na_3(CH_NIC,CH_D,CH_O);delay_ms(cas);
	Zobraz_na_3(CH_D,CH_O,CH_S);delay_ms(cas);
	Zobraz_na_3(CH_O,CH_S,CH_L);delay_ms(cas);
	Zobraz_na_3(CH_S,CH_L,CH_O);delay_ms(cas);
	Zobraz_na_3(CH_L,CH_O,CH_NIC);delay_ms(cas);
	Zobraz_na_3(CH_O,CH_NIC,CH_K);delay_ms(cas);
	Zobraz_na_3(CH_NIC,CH_K,CH_NIC);delay_ms(cas);
	Zobraz_na_3(CH_K,CH_NIC,CH_P);delay_ms(cas);
	Zobraz_na_3(CH_NIC,CH_P,CH_O);delay_ms(cas);
	Zobraz_na_3(CH_P,CH_O,CH_R);delay_ms(cas);
	Zobraz_na_3(CH_O,CH_R,CH_U);delay_ms(cas);
	Zobraz_na_3(CH_R,CH_U,CH_S);delay_ms(cas);
	Zobraz_na_3(CH_U,CH_S,CH_E);delay_ms(cas);
	Zobraz_na_3(CH_S,CH_E,CH_NIC);delay_ms(cas);
	Zobraz_na_3(CH_E,CH_NIC,CH_P);delay_ms(cas);
	Zobraz_na_3(CH_NIC,CH_P,CH_O);delay_ms(cas);
	Zobraz_na_3(CH_P,CH_O,CH_R);delay_ms(cas);
	Zobraz_na_3(CH_O,CH_R,CH_U);delay_ms(cas);
	Zobraz_na_3(CH_R,CH_U,CH_C);delay_ms(cas);
	Zobraz_na_3(CH_U,CH_C,CH_H);delay_ms(cas);
	Zobraz_na_3(CH_C,CH_H,CH_U);delay_ms(cas);
	Zobraz_na_3(CH_H,CH_U,CH_NIC);delay_ms(cas);
	Zobraz_na_3(CH_U,CH_NIC,CH_R);delay_ms(cas);
	Zobraz_na_3(CH_NIC,CH_R,CH_E);delay_ms(cas);
	Zobraz_na_3(CH_R,CH_E,CH_S);delay_ms(cas);
	Zobraz_na_3(CH_E,CH_S,CH_I);delay_ms(cas);
	Zobraz_na_3(CH_S,CH_I,CH_M);delay_ms(cas);
	Zobraz_na_3(CH_I,CH_M,CH_E);delay_ms(cas);
	Zobraz_na_3(CH_M,CH_E,CH_NIC);delay_ms(cas);
	Zobraz_na_3(CH_E,CH_NIC,CH_POML);delay_ms(cas);
	Zobraz_na_3(CH_NIC,CH_POML,CH_NIC);delay_ms(cas);
	
}

void VynulujPodsvetleni(unsigned char patro) //Vynuluje podsvetleni pokud jsme v tomto patre
{
	unsigned char kde;
	unsigned char maska=1;
	if (patro<9) kde=0;						//zjistime jestli to je v podsvet[0] 
	if ((patro>8)&&(patro<17)) kde=1;		//zjistime jestli to je v podsvet[1] 
	if (patro>16) kde=2;					//zjistime jestli to je v podsvet[2]
    patro=(patro-1)%8;						//diky tomuto zjistim ktery bit to je
	podsvet[kde] =podsvet[kde] | (maska<<patro); //posunu tu jednicku tam kde ma byt a dikz log souctu tam bude misto log0 sviti , log1 nesviti
	MAX6956_ActiveLED(podsvet);
}

void Zobraz2(unsigned char rpatro, unsigned char rdata)
{
	bit porucha;
	bit jede;
	bit up;
	bit down;
	
	if ((rdata&0x01)>0) porucha=1;	   //D2-porucha
	else porucha=0;
	if ((rdata&0x02)>0) jede=1;		   //D3-jede
	else jede=0;
	if ((rdata&0x04)>0) down=1;		   //D4-dolu
	else down=0;
	if ((rdata&0x08)>0) up=1;		   //D5-nahoru
	else up=0;

	//MAX_write( ADDR5300, D0P0, CH_NIC);MAX_write( ADDR5300, D0P1, CH_NIC);	 //	Smazaní všeho z displeje 0
    //MAX_write( ADDR5300, D1P0, CH_NIC);MAX_write( ADDR5300, D1P1, CH_NIC);	 //	Smazaní všeho z displeje 1
    //MAX_write( ADDR5300, D2P0, CH_NIC);MAX_write( ADDR5300, D2P1, CH_NIC);	 //	Smazaní všeho z displeje 2
	
	if (porucha==0)
	{
		 
		 if((jede==0)&& (down==0)&& (up==0)) // Zrusi pozadavek na zastaveni v paktre pokud tam jiz jsme a zhsne led
			 {
			 	MAX_write( ADDR5300, D0P0, CH_POML);
				MAX_write( ADDR5300, D0P1, CH_POML);
				VynulujPodsvetleni(rpatro);			
			 }
	
		 if((jede==1)&& (up==1)) 		//Jedem nahoru
			 {
			 	MAX_write( ADDR5300, D0P0, CH_NAH);	MAX_write( ADDR5300, D0P1, CH_NAH);
			 }
		 if((jede==1)&& (down==1)) 		//Jedem dolu
			 {
			 	MAX_write( ADDR5300, D0P0, CH_DOL); MAX_write( ADDR5300, D0P1, CH_DOL);
			 }
		 if((jede==0)&& (up==1)) 		//Pojedem nahoru, nemusi se vyuzit, ale je lepsi kdyz ta možnost tady je
			 {
				MAX_write( ADDR5300, D0P0, CH_NAH);
				MAX_write( ADDR5300, D0P1, CH_NIC);
			 }
		 if((jede==0)&& (down==1)) 		//Pojedem dolu, nemusi se vyuzit, ale je lepsi kdyz ta možnost tady je
			 {
				MAX_write( ADDR5300, D0P0, CH_DOL);
				MAX_write( ADDR5300, D0P1, CH_NIC);
			 }
		 if(((jede==1)&& ((down==0)&&(up==0)))||((down==1)&&(up==1))||(rpatro==0))
			{
			
			 if((jede==1)&& ((down==0)&&(up==0)))		//Kdyz dostavam signal ze jede ale nedostavam smer tak se zobrazi chyba -2-
				 {
				 	  MAX_write( ADDR5300, D0P0, CH_POML);MAX_write( ADDR5300, D0P1, CH_POML);
					  MAX_write( ADDR5300, D1P0, CH_2);MAX_write( ADDR5300, D1P1, CH_2);
					  MAX_write( ADDR5300, D2P0, CH_POML);MAX_write( ADDR5300, D2P1, CH_POML);
				 }
			 if  ((down==1)&&(up==1))					//Kdyz dostavam signal ze jede nebo pojede zaroven nahoru i dolu chyba -3-
				 {
					  MAX_write( ADDR5300, D0P0, CH_POML);MAX_write( ADDR5300, D0P1, CH_POML);
					  MAX_write( ADDR5300, D1P0, CH_3);MAX_write( ADDR5300, D1P1, CH_3);
					  MAX_write( ADDR5300, D2P0, CH_POML);MAX_write( ADDR5300, D2P1, CH_POML);
				 }
			 if (rpatro==0)								//Doslo k pretizeni rosvit LEDKU
				 {
				 	//Nech na obrazovce to co bylo. Kabina je pretížená
					LED_PRE=1;	
				 }
				
			
			}
			
		else 	//Klidne vypis patro
		 	{										
			LED_PRE=0;// Kabina není pretížená	 
					 if ((rpatro>0)&&(rpatro<10)) 	//Pokud je paro v intervalu <20,24>  tak na prostrednim displeji zobrazi "0"
						 {
							 MAX_write(ADDR5300,D1P0,CH_0);MAX_write(ADDR5300,D1P1,CH_0);
						 }
					 if ((rpatro>9)&&(rpatro<20)) 	//Pokud je paro v intervalu <10,19>  tak na prostrednim displeji zobrazi "1"
						 {
							 MAX_write(ADDR5300,D1P0,CH_1);MAX_write(ADDR5300,D1P1,CH_1); 
						 }
					 if ((rpatro>19)&&(rpatro<25)) 	//Pokud je paro v intervalu <20,24>  tak na prostrednim displeji zobrazi "2"
						 {
							 MAX_write(ADDR5300,D1P0,CH_2);MAX_write(ADDR5300,D1P1,CH_2);
						 }
					 	 //
					 if (rpatro<25)
				 		{	
						 	switch (rpatro % 10)
						            {   case 0 : MAX_write(ADDR5300,D2P0,CH_0);MAX_write(ADDR5300,D2P1,CH_0);break;
						                case 1 : MAX_write(ADDR5300,D2P0,CH_1);MAX_write(ADDR5300,D2P1,CH_1);break;
						                case 2 : MAX_write(ADDR5300,D2P0,CH_2);MAX_write(ADDR5300,D2P1,CH_2);break;
						                case 3 : MAX_write(ADDR5300,D2P0,CH_3);MAX_write(ADDR5300,D2P1,CH_3);break;
						                case 4 : MAX_write(ADDR5300,D2P0,CH_4);MAX_write(ADDR5300,D2P1,CH_4);break;
						                case 5 : MAX_write(ADDR5300,D2P0,CH_5);MAX_write(ADDR5300,D2P1,CH_5);break;
						                case 6 : MAX_write(ADDR5300,D2P0,CH_6);MAX_write(ADDR5300,D2P1,CH_6);break;
						                case 7 : MAX_write(ADDR5300,D2P0,CH_7);MAX_write(ADDR5300,D2P1,CH_7);break;
						                case 8 : MAX_write(ADDR5300,D2P0,CH_8);MAX_write(ADDR5300,D2P1,CH_8);break;
						                case 9 : MAX_write(ADDR5300,D2P0,CH_9);MAX_write(ADDR5300,D2P1,CH_9);break;
						            }
						}

					 else
						{		   //Pokud je cislo patra vetsi nez 24 da na displej chybu -1-
							MAX_write( ADDR5300, D0P0, CH_POML);MAX_write( ADDR5300, D0P1, CH_POML);
							MAX_write( ADDR5300, D1P0, CH_1);MAX_write( ADDR5300, D1P1, CH_1);
							MAX_write( ADDR5300, D2P0, CH_POML);MAX_write( ADDR5300, D2P1, CH_POML);
						}
		  	}
		
	}
	else						   //Kdyz nastala porucha	
	{
		
		if (rpatro!=31)   //Nejsou tam lidi kabina neni zatizena PLC neposila cislo patra 31
				{
				MAX_write( ADDR5300, D0P0, CH_e);MAX_write( ADDR5300, D0P1, CH_e);
		        MAX_write( ADDR5300, D1P0, CH_r);MAX_write( ADDR5300, D1P1, CH_r);	
		        MAX_write( ADDR5300, D2P0, CH_r);MAX_write( ADDR5300, D2P1, CH_r);
				}

		if (rpatro==31)   //Jsou tam lidi kabina je zatizena PLC posila cislo patra 31
				{
					Disp_Porucha();
				}
   
	
	}
}

unsigned char Parita(unsigned char d_patro,unsigned char d_zbytek)	// Licha parita je dobra pokud bity O = log0 a V=log1
																	// Program v plc pocita sudou + 1(bit V je v log1) -> Proto pokud je parita lichá tak to je zprávné
{
	unsigned char soucet=0;		//Uchovava pocet jednicek
	unsigned char pom;			//Pomocna
	unsigned char i;			//Pomocna do for cyklu

	for(i=0;i<5;i++)		//Cyklus FOR pro spocitani jednicek v Bytu patro
	{
		pom=d_patro;
		pom=pom>>i;
		pom=pom & 0x01;
		if (pom==1) soucet++;
	}

	for(i=0;i<7;i++)		//Cyklus FOR pro spocitani jednicek v Bytu zbytek
	{
		pom=d_zbytek;
		pom=pom>>i;
		pom=pom & 0x01;
		if (pom==1) soucet++;
	}	
	if (soucet & 0x01)	return 1; //Lichá parita na výstupu 1
	else				return 0; //Sudá parita na výstupu 0
}


// Konec Zobrazeni/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




unsigned char Parita_odchozi(void)
{
	unsigned char soucet=0;		//Uchovava pocet jednicek
	unsigned char pom;			//Pomocna
	unsigned char i;			//Pomocna do for cyklu

	for(i=0;i<8;i++)		//Cyklus FOR pro spocitani jednicek
	{
		pom=~podsvet[0];
		pom=pom>>i;
		pom=pom & 0x01;
		if (pom==1) soucet++;
	}
	for(i=0;i<8;i++)		//Cyklus FOR pro spocitani jednicek
	{
		pom=~podsvet[1];
		pom=pom>>i;
		pom=pom & 0x01;
		if (pom==1) soucet++;
	}
	for(i=0;i<8;i++)		//Cyklus FOR pro spocitani jednicek
	{
		pom=~podsvet[2];
		pom=pom>>i;
		pom=pom & 0x01;
		if (pom==1) soucet++;
	}
	if (SNIMAC1 == 0) soucet++;
    if (SNIMAC2 == 0) soucet++;
    if (zm_zvonek == 1) soucet++;
    if (zm_stop == 1) soucet++;
	if (soucet & 0x01)	return 1; //Kdyz je pocet jednicek lichy na výstupu 1
	else				return 0; //Kdyz je pocet jednicek sudy na výstupu 0
}


void snimace_a_stop(void)
{
	if (zm_stop == 1) pom_P0 |= 0x08; 						// pokud byl zmacknut stop tak je bit "B" v log1  (AXXXBXXX)
    if ((SNIMAC1 == 0) && (SNIMAC2 == 0)) pom_P0 |= 0x80; 	// pokud jsou sepnuty oba spinace tak je bit "A" v log1
}

/*
Lo P1 = vst sl 5, Hi P1 = vst sl 6, Lo P0 vyst sl 5, Hi P0 vyst sl 6
P1,P0 /data jsou negovane
   _________________________________
   |    SLAVE 6     |     SLAVE 5  |
   ---------------------------------
P1 | Zadost mastera |Data pro slave|  Prichozi data
   ---------------------------------
P0 |Data pro mastera| Zadost slave |  Odchozi data

podsvet[0] |24|23|22|21|20|19|18|17|  //Pokud sviti (byl pozadavek) tak je zde ulozena log0.
podsvet[1] |16|15|14|13|12|11|10| 9|
podsvet[2] | 8| 7| 6| 5| 4| 3| 2| 1|

*/


void main(void)
{   Init(); 							
    while (1) 
    {   
// S0
		// cyklus 111-----------------------------------------------------------------------------------------------------------------------
		if (((~P1 & 0x70) == 0x70) && (stav == 0))  // X111XXX Pozadavek mastera 111 a zaroven stav 0  
                      
        {   
			if (castzpravy == 0) pom_P0 = 0x00; // E2 E1 E0    0 0 0
            else 				 pom_P0 = 0x10;	// E2 E1 E0    0 0 1
            snimace_a_stop();					// Priprava dat pro rychle odeslani pro tlacitko stop a pri sepnuti obou snimacu (AXXXBXXX)
			delaynop(30);
            prichozi_data |= (~P1 & 0x07);			// Pridani poslednich bitu D1,O,V do promenne prichozi_data |0|D5|D4|D3|D2|D1|O|V|
            
			if (Parita(prichozi_patro,prichozi_data)) 	// Parita bere ohled i na bity O a V
							{
								prichozi_data=prichozi_data>>3;		   	//Zahazuju paritni bit a O a V, do zobraz vstupuje:
								Zobraz2(prichozi_patro,prichozi_data);	// prichozi_patro |0||0|0|D10|D9|D8|D7|D6| a prichozi_data |0|0|0|0|D5|D4|D3|D2|
							}
			

            P0 = ~(pom_P0 | 0x07); // Zadost slavu 111   |A|E2|E1|E0|B|1|1|1|
            stav = 1;
        }
// S1
		// cyklus 101-----------------------------------------------------------------------------------------------------------------------
        if (((~P1 & 0x70) == 0x50) && (stav == 1))  // X101XXX Pozadavek mastera 101 a zaroven stav 1 

        {   
			if (castzpravy == 0) pom_P0 = ((~podsvet[1] >> 1) & 0x70);  //Odeslani tlacitek 16,15,14 |0|D16|D15|D14|0|0|0|0|
            else 	if (zm_dvere == 1) pom_P0 = 0x10;  //Zavrene       // Odesilani nic,nic,dvere   |0|0|0|1|0|0|0|0|
                 	else 			pom_P0 = 0x00;	//Otevrene		// Odesilani nic,nic,dvere   |0|0|0|0|0|0|0|0|
            snimace_a_stop();						// Priprava dat pro rychle odeslani pro tlacitko stop a pri sepnuti obou snimacu (AXXXBXXX)
			

            P0 = ~(pom_P0 | 0x05); // Zadost slavu 101   |A|D16|D15|D14|B|1|0|1| nebo  |A|0|0|DV|B|1|0|1|
            stav = 2;
        }
	
// S2
		// cyklus 100-----------------------------------------------------------------------------------------------------------------------
        if (((~P1 & 0x70) == 0x40) && (stav == 2))  	// X100XX Pozadavek mastera 100a zaroven stav 2

        {   
			if (castzpravy == 0) pom_P0 = ((~podsvet[1] << 2) & 0x70); //Odeslani tlacitek 13,12,11 |0|D13|D12|D11|0|0|0|0|
            else 									// Odesilani parita,zvonek,stop   |0|P|Z|S|0|0|0|
			{
					pom_P0=0;
					if ((Parita_odchozi()) == 0) pom_P0 |= 0x40;  //pokud je pocet jednicek sudy, paritni bit je log 1 jedna se o LICHOU paritu
					if (zm_zvonek==1)		 pom_P0 |= 0x20;
		 		    if (zm_stop==1)			 pom_P0 |= 0x10;
   			}
            snimace_a_stop();			// Priprava dat pro rychle odeslani pro tlacitko stop a pri sepnuti obou snimacu (AXXXBXXX)
        

			P0 = ~(pom_P0 | 0x04); // Zadost slavu 100   |A|D13|D12|D11|B|1|0|0| nebo  |A|0|0|DV|B|1|0|1|
            stav = 3;
        }
	
// S3
		// cyklus 011-----------------------------------------------------------------------------------------------------------------------
        if (((~P1 & 0x70) == 0x30) && (stav == 3))              // X011XX Pozadavek mastera 011 a zaroven stav 3

        {   if (castzpravy == 0) 						//Odeslani tlacitek 10,9,8 |0|D10|D9|D8|0|0|0|0|
			{
				pom_P0=0;										//0|0|0|0|0|0|0|
				pom_P0 = (pom_P0 | ( (~podsvet[1] << 5) & 0x60) );	//|0|D10|D9|0|0|0|0|0|
				pom_P0 = (pom_P0 | ( (~podsvet[0] >> 3) & 0x10) );	//|0|D10|D9|D8|0|0|0|0|
            }
            else										//Odeslani snimace2,snimace1,tlacitka 24 |0|S2|S1|D24|0|0|0|0|
		    {
				pom_P0=0;
				if (SNIMAC2 == 0) pom_P0 |=0x40; 				//|0|S2|0|0|0|0|0|0|
	    		if (SNIMAC1 == 0) pom_P0 |=0x20;				//|0|0|S1|0|0|0|0|0|
	    		pom_P0 = (pom_P0 | ( (~podsvet[2] >> 3) & 0x10) );	//|0|S2|S1|D24|0|0|0|0|
   			}
            snimace_a_stop();			// Priprava dat pro rychle odeslani pro tlacitko stop a pri sepnuti obou snimacu (AXXXBXXX)

            P0 = ~(pom_P0 | 0x03);		// Zadost slavu 011   
            stav = 4;
        }
		
// S4
		// cyklus 010-----------------------------------------------------------------------------------------------------------------------
        if (((~P1 & 0x70) == 0x20) && (stav == 4))                       // cyklus 010

        {   if (castzpravy == 0) pom_P0 = (~podsvet[0] & 0x70);                 //tl  7,  6,  5
            else 				 pom_P0 = (~podsvet[2] & 0x70);                 //tl 23, 22, 21 
            snimace_a_stop();			// Priprava dat pro rychle odeslani pro tlacitko stop a pri sepnuti obou snimacu (AXXXBXXX)
            delaynop(30);

            prichozi_patro = (~P1 & 0x07); // patro b4 b3 b2
            prichozi_patro <<= 3;

            P0 = ~(pom_P0 | 0x02);		// Zadost slavu 010
			

            stav = 5;
        }
		
// S5
		// cyklus 001-----------------------------------------------------------------------------------------------------------------------
        if (((~P1 & 0x70) == 0x10) && (stav == 5))                       // cyklus 001

        {   if (castzpravy == 0) pom_P0 = ((~podsvet[0] << 3) & 0x70); 					//tl  4,  3,  2
            else 				 pom_P0 = ((~podsvet[2] << 3) & 0x70);                   //tl 20, 19, 18
            snimace_a_stop();			// Priprava dat pro rychle odeslani pro tlacitko stop a pri sepnuti obou snimacu (AXXXBXXX)
            delaynop(30);
            prichozi_patro |= (~P1 & 0x07); // patro b1 b0
            prichozi_data = prichozi_patro & 1; // data nahoru
            prichozi_patro >>= 1;
            prichozi_data <<= 3;

            P0 = ~(pom_P0 | 0x01);		// Zadost slavu 001
            stav = 6;
        }
		
// S6
		// cyklus 000-----------------------------------------------------------------------------------------------------------------------
        if (((~P1 & 0x70) == 0x00) && (stav == 6))                       // cyklus 000

        {   if (castzpravy == 0) 	
			{
			pom_P0 = ((~podsvet[0] << 6) & 0x40); 				//tl  1, O=0, V=1 
	        pom_P0 = (pom_P0 | 0x00);
			pom_P0 = (pom_P0 | 0x10);
			}
	  		else 					
			{
			pom_P0 = ((~podsvet[2] << 6) & 0x40);				//tl  17, O=0, V=1 
	  		pom_P0 = (pom_P0 | 0x00);
			pom_P0 = (pom_P0 | 0x10);
	        }

  
            delaynop(30);
            prichozi_data |= (~P1 & 0x07); // data dolu jizda porucha
            prichozi_data <<= 3;
            castzpravy = ~castzpravy;

            P0 = ~(pom_P0 | 0x00);		// Zadost slavu 000
            stav = 0;
        }
	


/////////////////////////// ***Tlacitka*** ///////////////////////////////////////////////////////

// Nacteni zmacklych tlacitek
			
			if ((key_pat[0] > 0) || (key_pat[1] > 0) || (key_pat[2] > 0)) //kdyz bylo zmacknute nejake tlacitko
			{   
				
				podsvet[0] &= ~key_pat[0]; 
	            podsvet[1] &= ~key_pat[1]; 
	            podsvet[2] &= ~key_pat[2]; 
	            MAX6956_ActiveLED(podsvet);
	            key_pat[0] = 0x00;
	            key_pat[1] = 0x00;
	            key_pat[2] = 0x00;					
	        }

// Tlacitko zvonek
			if ((zm_zvonek==1)&(TL_ZVN==0))
			{
				LED_ZVN = 1;			
			}
	      	else
			{
				LED_ZVN=0;
				zm_zvonek=0;
			}
// Tlacitko stop
			if (zm_stop==1)
			{
				LED_STP = 1;
				podsvet[0] = 0xFF; 			//Vypni podsvetleni resp informace o tlacitkach
	            podsvet[1] = 0xFF;			//Vypni podsvetleni resp informace o tlacitkach
	            podsvet[2] = 0xFF;			//Vypni podsvetleni resp informace o tlacitkach
	            MAX6956_ActiveLED(podsvet); // Zhasni vse
			}
// Tlacitko dvere (koncovy spinac dveri)
			if ((DVERE == 0)) // Dvere jsou zavrene
			{
				//signalizace on
				zm_dvere=1;   
			}
	      	else
			{
				//signalizace off
				zm_dvere=0;
			}
			
      
    }
}

void tl_interrupt(void) interrupt 0
{
	EA=0;
	if (TL_ZVN == 0) zm_zvonek=1;
	if (TL_STP == 0) zm_stop = 1;  
	EA=1;									  
}

void keyboard_interrupt(void) interrupt 2
{
	EA=0;
	key_pat[0] = MAX_read( ADDR5500, KEY_A_MSK);
	key_pat[1] = MAX_read( ADDR5500, KEY_B_MSK);
	key_pat[2] = MAX_read( ADDR5500, KEY_C_MSK);
	LED_STP = 0;
	zm_stop =0;
	EA=1;
}
