#include "includes.h"

/*
prvni vstup   204000AD00060100FF0100000100
dalsi vstupy  200100AD00060100FF0100000100
prvni vystup  204000AD00060100FF0100010101
dalsi vystupy 200100AD00060100FF0100010101
*/


tsModule module[MAX_MODULES];


// definice typu jednotlivych IO na kazdem modulu MODULES_MODE_IO
// adresace v poli odpovida definicim cisel modulu
// v kazdem radku je pole ktere obsahuje nejdrive vsechny vstupy a pak vystupy pro jedotlive IO v poradi
const tUChar MODULE_MODE_0 []  = {	MODE_BINP,		// IN1
									MODE_BINP,		// IN2
									MODE_BINP,		// TAMPER - prefix 0x40 doplnovan fixne
									MODE_BOUT,		// rele
								 };
								 
// spolecna definice pro jednokanalove merici moduly
const tUChar MODULE_MODE_1 [1]  = {	MODE_VINP,				// pouze jeden kanal
								 };

// spolecna definice pro dvoukanalove merici moduly
const tUChar MODULE_MODE_2 [2]  = {	MODE_VINP,MODE_VINP,	// dva kanaly
								 };

// interni I/O jednotky - ctecky
// nasmerici vstupy se chovaji jako moduly
// indexace odpovida identifikacnim kodum daneho modulu - omezeno na 8 max.
const tUChar *MODULES_MODE_IO [MAX_MODULES]  =
 {
	MODULE_MODE_0, 		// modul 0 
	MODULE_MODE_1, 		// modul 1 
	MODULE_MODE_2, 		// modul 2 
	MODULE_MODE_1, 		// modul 3 
	MODULE_MODE_1, 		// modul 4 
	MODULE_MODE_1, 		// modul 5 
	MODULE_MODE_1, 		// modul 6 
	MODULE_MODE_1, 		// modul 7 
 };


//*****************************************************************************************************************
// definice moznych periferii pro ctecky - obdoba definici modulu u GRU01
const tUChar MODULES_NUM_IO [MAX_MODULES][2] =
 { // vstupy , vystupy
   { 3 , 1, },	// 0 - jednotka	ma vstupy tlacitka IN1, IN2, vystup je RELE, TAMPER je externi vstup 
   { 1 , 0, },	// 1 - mereni napajeciho napeti 
   { 2 , 0, },	// 2 - mereni teploty
   { 1 , 0, },	// 3 - mereni proudu
   { 1 , 0, },	// 4 - mereni osvetleni
   { 1 , 0, },	// 5 - mereni rychlosti vetru
   { 1 , 0, },	// 6 - mereni vlhkosti
   { 1 , 0, },	// 7 - rezerva
 };


//*****************************************************************************************************************
tUChar numModuleIO(tUChar _typ, tUChar _ioFlag)
{
 return(MODULES_NUM_IO[_typ][_ioFlag]);
}


//*****************************************************************************************************************
// vraci informaci jestli adresovaný IO je binarni nebo analogovy, podle definice MODE_xxxx 
tUChar getModeIO(GUINTRECORD _iodadr)
{
  	
  if((_iodadr.VALUE.LO&ADDR_OUTPUT))		// vystup
   {
    // vystupy na jednotce samotne
    if(_iodadr.VALUE.HI == 0) return(MODE_BOUT);
	
	// nebo vzit pocet vstupu daneho modulu a odtoho zacit pocitat vystupy - protoze je to v jednom poli
    return( MODULES_MODE_IO[module[_iodadr.VALUE.HI-1].type][(MODULES_NUM_IO[module[_iodadr.VALUE.HI-1].type][0])+(_iodadr.VALUE.LO&~ADDR_OUTPUT)-1] );
   }	
  else
   {				// vstup
    // vstupy na jednotce samotne
    if(_iodadr.VALUE.HI == 0) return(MODE_BINP);
	// nebo na sbernici
    return( MODULES_MODE_IO[module[_iodadr.VALUE.HI-1].type][_iodadr.VALUE.LO-1] );
   } 

}





/*****************************************************************************************************************
*	g e t N e x t I O
*
* funkce pro nalezeni nasledujiciho nebo predhazejiciho zaznamu v tabulce modulu
* vraci 1 pokud je zaznam nalezen, vraci 0 kdyz neni nic k disposici 
* pri volani je v parametru *myOut nastavena adresa-1 od ktere se ma hledat
* pri navratu je v parametru *myOut nastavena adresa nalezeneho modulu
* vstupni parametr _ioFlag urcuje 0=vstupy, 1=vystupy
*****************************************************************************************************************/
tUInt getNextIO(GUINTRECORD *myOut, tUChar _ioFlag)
{
  tUChar	_gpio;
	
	// adresuje se nepripojeny modul, nebo nejsou pripojeny zadne moduly
	if (myOut->VALUE.HI > appCB.sensorCount) return(0);
	
	myOut->VALUE.LO &= ~ADDR_OUTPUT;
	myOut->VALUE.LO++;

	if (myOut->VALUE.HI == 0) 
	{
		if (myOut->VALUE.LO > numModuleIO(0, _ioFlag) ) 
		{
		  if (myOut->VALUE.HI < appCB.sensorCount) { myOut->VALUE.HI++; myOut->VALUE.LO = 1; }
		}
		else return(1);		
	}
	
	while(1)
	 {
		if (myOut->VALUE.HI > 0)		// osetreni pro IO na jednotce
		 {
		   _gpio = numModuleIO((module[myOut->VALUE.HI-1].type), _ioFlag);		// definice IO pro moduly
		 }
		else 
		 {
		   _gpio = numModuleIO( 0, _ioFlag);		// vzit definici IO pro master jednotku
		 }

		
		// pokud modul obsahuje nejaky io
		if(_gpio && (myOut->VALUE.LO) <= _gpio ) 	return(1);		// nasel v tomto modulu
		
		if(myOut->VALUE.HI >= appCB.sensorCount)    return(0);			// nic dalsiho
		
		myOut->VALUE.HI++;		// na dalsi modul
 		myOut->VALUE.LO = 1;	// a jeho prvni io
	    
		ClearWDT();
	 }

return(0);
}


/*****************************************************************************************************************
*	g e t P r e w I O
*
* funkce pro nalezeni nasledujiciho nebo predhazejiciho zaznamu v tabulce modulu
* vraci 1 pokud je zaznam nalezen, vraci 0 kdyz neni nic k disposici 
* pri volani je v parametru *myOut nastavena adresa-1 od ktere se ma hledat
* pri navratu je v parametru *myOut nastavena adresa nalezeneho modulu
* vstupni parametr _ioFlag urcuje 0=vstupy, 1=vystupy
*****************************************************************************************************************/
tUInt getPrewIO(GUINTRECORD *myOut, tUChar _ioFlag)
{
tUChar _gpio;

#if HW_VERSION >= 3
	if (myOut->VALUE.HI == 0) 
	 { 
		if(myOut->VALUE.LO>1) { myOut->VALUE.LO--; return(1); }		
		else return(0);		
	 }
#endif	
	
	  if( myOut->VALUE.LO>1 ) myOut->VALUE.LO--;
	  else 
	   
		  if(myOut->VALUE.HI>0) 
	  	   { 
		     myOut->VALUE.HI--;
		     if (myOut->VALUE.HI == 0) 
		       myOut->VALUE.LO = numModuleIO(0, _ioFlag);		//a jeho posledni io
		     else
		       myOut->VALUE.LO = numModuleIO((module[myOut->VALUE.HI-1].type), _ioFlag);		//a jeho posledni io
		   }
          else return(0);		// jsme na zacatku	 

	     if (myOut->VALUE.HI > appCB.sensorCount) return(0);		// adresuje se nepripojeny modul
 
	while(1)
	 {
		if (myOut->VALUE.HI > 0)		// osetreni pro IO na jednotce
		 {
		   _gpio = numModuleIO((module[myOut->VALUE.HI-1].type), _ioFlag);		// definice IO pro moduly
		 }
		else 
		 {
		   _gpio = numModuleIO( 0, _ioFlag);		// vzit definici IO pro master jednotku
		 }
		 
		
		// pokud modul obsahuje nejaky io
		if(_gpio && myOut->VALUE.LO <= _gpio ) return(1);		// nasel v tomto modulu
		
		if(myOut->VALUE.HI == 0) return(0);			// nic dalsiho
		
		myOut->VALUE.HI--;		// na dalsi modul 
		
		if (myOut->VALUE.HI == 0) 
		  myOut->VALUE.LO = numModuleIO(0, _ioFlag);		//a jeho posledni io
		else
		  myOut->VALUE.LO = numModuleIO((module[myOut->VALUE.HI-1].type), _ioFlag);		//a jeho posledni io

	    ClearWDT();
	 }

return(0);
}




/************************************************************************************
* AddVirtualModul()
*
* funkce prida do pole module[] virtualni merici periferii
************************************************************************************/
void AddVirtualModul(tUChar _type)
{
   module[appCB.sensorCount].type = 	_type;	// ulozit typ pripojene periferie
   appCB.sensorCount++;						// inkrementovat pocet nalezenych modulu
}


