//----------------------------------------------------
/**
	\file		ctk/inc/iolib.h
	\ingroup	hardware
	\ingroup	all

	\brief		Knihovna vstupu vystupu
				<<< ALL >>>

	\author		ConTeK s.r.o., Ing. Vladimir Kastner, Ing. Pavel Bazika
	\version	01.02
	\date		11.08.2008
*/
//----------------------------------------------------

#ifndef _IOLIB_H_
#define _IOLIB_H_		//!< Definice pritomnosti knihovny

#include <libsets.h>
#include <ctktypes.h>
#include <timeticks.h>
#include <list.h>
#include <sync.h>

//----------------------------------------------------
//!	\name	Typy analogovych/digitalnich IO
//@{

typedef	uint16_t	ioaddr_t;	//!< Typ adresy IO
typedef	uint16_t	aiodata_t;	//!< Typ dat analogovych IO
typedef uint8_t		iodata_t;	//!< Typ dat digitalnich vstupu
//@}

//----------------------------------------------------
//!	Pozadavek na aktualizaci vsech hodnot

#define IO_UPDATE_ALL	UINT16_MAX


//----------------------------------------------------
//!	\name	Definice prace s mnozinami digitalnich IO
//@{
#define sGetBitValue(_val, _bit)	(((_val >> _bit) & 0x01) == 1 ? TRUE : FALSE ) //<! \brief	Vraci hodnotu daneho bitu	\param _val hodnota \param	_bit cislo bitu

#define sGetBitIndex(_sig)		((_sig) & 0x7)						//<! \brief	Vraci bit index	\param _sig	jmeno signalu
#define sGetByteMask(_sig)		(1 << sGetBitIndex(_sig))			//<! \brief	Vraci byte masku signalu	\param _sig	jmeno signalu
#define sGetByteIndex(_sig)		((_sig) >> 3)						//<! \brief	Vraci byte index	\param _sig	jmeno signalu
#define sDInpByte(_idx)			(gIO.DInpVal[(_idx)])				//<! \brief	Zpristupni byte digitalnich vstupu	\param _idx	index byte
#define sDOutpByte(_idx)		(gIO.DOutpVal[(_idx)])				//<! \brief	Zpristupni byte digitalnich vystupu	\param _idx	index byte
#define sDInpXByte(_idx)		(gIO.DInpX[(_idx)])					//<! \brief	Zpristupni byte Xor masky digitalnich vstupu	\param _idx	index byte
#define sDOutpXByte(_idx)		(gIO.DOutpX[(_idx)])				//<! \brief	Zpristupni byte Xor masky digitalnich vystupu	\param _idx	index byte
#define sDInpSigByte(_sig)		(sDInpByte(sGetByteIndex(_sig)))	//<! \brief	Zpristupni byte digitalnich vstupu	\param _sig	jmeno signalu
#define sDOutpSigByte(_sig)		(sDOutpByte(sGetByteIndex(_sig)))	//<! \brief	Zpristupni byte digitalnich vystupu	\param _sig	jmeno signalu
#define sDInpSigXByte(_sig)		(sDInpXByte(sGetByteIndex(_sig)))	//<! \brief	Zpristupni byte Xor masky digitalnich vstupu	\param _sig	jmeno signalu
#define sDOutpSigXByte(_sig)	(sDOutpXByte(sGetByteIndex(_sig)))	//<! \brief	Zpristupni byte Xor masky digitalnich vystupu	\param _sig	jmeno signalu

#define sAInpVal(_idx)			(gIO.AInpVal[(_idx)])				//<! \brief	Zpristupni hodnoty analogovech vstupu	\param _idx	index vstupu
#define sAOutpVal(_idx)			(gIO.AOutpVal[(_idx)])				//<! \brief	Zpristupni byte analogovych vystupu	\param _idx	index vystupu
//@}


//----------------------------------------------------
/**
	\brief	Metody IO knihovny
*/
//----------------------------------------------------
//@{
struct _IODEVICE;

typedef bool_t (*iomUpdate) (struct _IODEVICE * const _ctx, ioaddr_t _addr);

typedef void (*iomTick) (struct _IODEVICE * const _ctx);
typedef bool_t (*iomEnable) (struct _IODEVICE * const _ctx);
typedef bool_t (*iomDisable) (struct _IODEVICE * const _ctx);
typedef bool_t (*iomReady) (const struct _IODEVICE * const _ctx);
//@}


//----------------------------------------------------
//!	Rozsah namapovani IO

typedef struct _IORANGE
{
	ioaddr_t	Base;
	uint8_t		Size;
	iomUpdate	Update;
} IORANGE;


//----------------------------------------------------
//!	Struktura zarizeni disponujiciho vstupy a vystupy

typedef struct _IODEVICE_DATA
{
	bool_t	Enabled;

	IORANGE		DInp;
	IORANGE		DOutp;
	IORANGE		AInp;
	IORANGE		AOutp;

	iomTick		ReadTick;
	iomTick		WriteTick;
	iomEnable	Enable;
	iomDisable	Disable;
	iomReady	Ready;
} IODEVICE_DATA;


//----------------------------------------------------
//!	Seznam IO zarizeni

typedef struct _IODEVICE
{
	HEAD1			List;
	IODEVICE_DATA	Device;
} IODEVICE;


//----------------------------------------------------
//!	\name	Popisovace testovaciho rezimu IO
//@{

#ifdef IO_TEST

//! digital IO
typedef struct _IODIGTEST
{
	uint8_t		*Val;
	uint8_t		*Mask;
} IODIGTEST;

//! analog io
typedef struct _IOANLTEST
{
	aiodata_t 	*Val;
	bool_t		*Enabled;
} IOANLTEST;


#endif // IO_TEST
//@}

//----------------------------------------------------
/**
	\brief	Kontext analogoveho filtru
*/
//----------------------------------------------------

struct _AFILTER_CTX;

typedef void (*afmTick) (struct _AFILTER_CTX * const _ctx);
typedef void (*afmFirstValue) (struct _AFILTER_CTX * const _ctx);

typedef struct _AFILTER_CTX
{
	volatile bool_t		flRunning;

	aiodata_t 	Value;
	aiodata_t 	ActValue;

	afmTick			Tick;
	afmFirstValue	FirstValue;
} AFILTER_CTX;

typedef struct _AFILTER_EXP
{
	AFILTER_CTX	Parent;

	ticks_t		Timer;
	ticks_t		Timeout;

	aiodata_t	K;
} AFILTER_EXP;

typedef struct _AFILTER_FLOTAVG
{
	AFILTER_CTX	Parent;

	uint16_t	Size;
	aiodata_t	*Data;

	ticks_t		Timer;
	ticks_t		Timeout;

	uint16_t	Position;
} AFILTER_FLOATAVG;



//----------------------------------------------------
/**
	\brief	Kontext digitalniho filtru
*/
//----------------------------------------------------


typedef struct _DFILTER_CTX
{
	volatile bool_t		flRunning;		//!< Priznak spusteni	

	bool_t				FltValue;		//!< Filtrovana hodnota vstupu
	bool_t 				CurValue;		//!< Aktualni hodnota vstupu
			
	lticks_t			Timer;			//!< Casovac

	lticks_t			TimeUpEdge;		//!< Casovac nabezne hrany
	lticks_t			TimeDownEdge;	//!< Casovac sestupne hrany

} DFILTER_CTX;


//----------------------------------------------------
//!	Kontext knihovny vstupu a vystupu

typedef struct _IOLIB_CTX
{
	HEAD1			DeviceList;		//!< Seznam IO zarizeni

	uint8_t			*DInpVal;		//!< Pole hodnot digitalnich vstupu
	uint8_t			*DInpX;			//!< Pole popisu invertovanych vstupu
	DFILTER_CTX		**DInpFilter;	//!< Filtr digitalniho vstupu
	uint8_t			DInpCount;		//!< Pocet digitalnich vstupu

	uint8_t			*DOutpVal;		//!< Pole hodnot digitalnich vystupu
	uint8_t			*DOutpX;		//!< Pole popisu invertovanych vystupu
	uint8_t			DOutpCount;		//!< Pocet digitalnich vystupu

	aiodata_t		*AInpVal;		//!< Pole hodnot analogovych vstupu
	AFILTER_CTX		**AInpFilter;	//!< Seznam filtru analogovych vstupu
	uint8_t			AInpCount;		//!< Pocet analogovych vstupu

	aiodata_t		*AOutpVal;		//!< Pole hodnot analogovych vystupu
	uint8_t			AOutpCount;		//!< Pocet analogovych vystupu

#ifdef IO_TEST
	bool_t			TestMode;		//!< Testovaci rezim aktivovan
	IODIGTEST		*TestDInp;		//!< Testovaci hodnoty digitalnich vstupu
	IODIGTEST		*TestDOutp;		//!< Testovaci hodnoty digitalnich vystupu
	IOANLTEST		*TestAInp;		//!< Testovaci hodnoty analogovych vstupu
	IOANLTEST		*TestAOutp;		//!< Testovaci hodnoty analogovych vystupu
#endif // IO_TEST

	volatile bool_t			flRunning;		//!< Priznak inicializace

} IOLIB_CTX;


//----------------------------------------------------
/**
	\brief	Globalni kontext IO
*/
//----------------------------------------------------

extern IOLIB_CTX gIO;


//----------------------------------------------------
//!	\name	Definice kriticke sekce vstupu vystupu
//@{

#define IOLock		FastLock	// Vstup do kriticke sekce io
#define IOUnlock	FastUnlock	// Ukonceni pristupu do kriticke sekce io
#define iolock_t	flock_t		// typ
//@}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni digitalniho vstupu

	\param	_sig	signal

	\return	TRUE je-li signal nastaven, FALSE je-li nulovy
*/
//----------------------------------------------------

static inline bool_t sGetDInp(const ioaddr_t _sig)
{
#ifdef IO_TEST
	if (gIO.TestMode && (gIO.TestDInp != NULL) && (gIO.TestDInp->Mask[sGetByteIndex(_sig)] & sGetByteMask(_sig)))
	{
		// tento vstup je v testovacim rezimu
		uint8_t valByte = gIO.TestDInp->Val[sGetByteIndex(_sig)];
		return (valByte & sGetByteMask(_sig)) ? TRUE : FALSE;
	}
	else
#endif // IO_TEST
	{
		return ((sDInpSigByte(_sig) & sGetByteMask(_sig)) ? TRUE : FALSE);
	}
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni digitalniho vstupu, jen neni-li provadeno periodicke nacitani vstupu

	\param	_sig	signal
	\param	_val	TRUE ma-li byt signal nastaven, FALSE ma-li byt nulovan
*/
//----------------------------------------------------

static inline void sSetDInp(const ioaddr_t _sig, const bool_t _val)
{
	// funkce se provadi nezavisle na testovacim rezimu
	iolock_t lock = IOLock();
	if (_val)
	{
		sDInpSigByte(_sig) |= sGetByteMask(_sig);
	}
	else
	{
		sDInpSigByte(_sig) &= ~sGetByteMask(_sig);
	}
	IOUnlock(lock);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni byte digitalnich vstupu

	\param	_idx	index byte
	\param	_val	hodnota
*/
//----------------------------------------------------

static inline uint8_t sGetDInpByte(const ioaddr_t _idx)
{
#ifdef IO_TEST
	if (gIO.TestMode && (gIO.TestDInp != NULL))
	{
		// jsme v testovacim rezimu
		uint8_t testByte = gIO.TestDInp->Mask[_idx] & gIO.TestDInp->Val[_idx];
		uint8_t realByte = ~gIO.TestDInp->Mask[_idx] & AtomRead(sDInpByte(_idx));

		return (testByte | realByte);
	}
	else
#endif // IO_TEST
	{
		return AtomRead(sDInpByte(_idx));
	}
}

//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni byte digitalnich vstupu

	\param	_idx	index byte
	\param	_val	hodnota
*/
//----------------------------------------------------

static inline void sSetDInpByte(const ioaddr_t _idx, const uint8_t _val)
{
	// funkce se provadi nezavisle na testovacim rezimu
	AtomWrite(sDInpByte(_idx), _val);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni digitalniho vystupu

	\param	_sig	signal

	\return	TRUE je-li signal nastaven, FALSE je-li nulovy
*/
//----------------------------------------------------

static inline bool_t sGetDOutp(const ioaddr_t _sig)
{
#ifdef IO_TEST
	if (gIO.TestMode && (gIO.TestDOutp != NULL) && (gIO.TestDOutp->Mask[sGetByteIndex(_sig)] & sGetByteMask(_sig)))
	{
		// tento vystup je v testovacim rezimu
		return (gIO.TestDOutp->Val[sGetByteIndex(_sig)] & sGetByteMask(_sig)) ? TRUE : FALSE;
	}
	else
#endif // IO_TEST
	{
		return ((sDOutpSigByte(_sig) & sGetByteMask(_sig)) ? TRUE : FALSE);
	}
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni digitalniho vystupu

	\param	_sig	signal
	\param	_val	TRUE ma-li byt signal nastaven, FALSE ma-li byt nulovan
*/
//----------------------------------------------------

static inline void sSetDOutp(const ioaddr_t _sig, const bool_t _val)
{
	// funkce se provadi nezavisle na testovacim rezimu

	iolock_t lock = IOLock();
	if (_val)
	{
		sDOutpSigByte(_sig) |= sGetByteMask(_sig);
	}
	else {
		sDOutpSigByte(_sig) &= ~sGetByteMask(_sig);
	}

	IOUnlock(lock);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni byte digitalnich vystupu

	\param	_idx	index byte
	\param	_val	hodnota
*/
//----------------------------------------------------

static inline uint8_t sGetDOutpByte(const ioaddr_t _idx)
{
#ifdef IO_TEST
	if (gIO.TestMode && (gIO.TestDOutp != NULL))
	{
		// jsme v testovacim rezimu
		uint8_t testByte = gIO.TestDOutp->Mask[_idx] & gIO.TestDOutp->Val[_idx];
		uint8_t realByte = ~gIO.TestDOutp->Mask[_idx] & AtomRead(sDOutpByte(_idx));
		return testByte | realByte;
	}
	else
#endif // IO_TEST
	{
		return AtomRead(sDOutpByte(_idx));
	}
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni byte digitalnich vystupu

	\param	_idx	index byte
	\param	_val	hodnota
*/
//----------------------------------------------------

static inline void sSetDOutpByte(const ioaddr_t _idx, const uint8_t _val)
{
	// funkce se provadi nezavisle na testovacim rezimu
	AtomWrite(sDOutpByte(_idx), _val);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni analogoveho vstupu

	\param	_addr	cislo vstupu

	\return	hodnota vstupu
*/
//----------------------------------------------------

static inline aiodata_t sGetAInp(const ioaddr_t _addr)
{
#ifdef IO_TEST
	if (gIO.TestMode && (gIO.TestAInp != NULL) && gIO.TestAInp->Enabled[_addr])
	{
		// tento vstup je v testovacim rezimu
		return gIO.TestAInp->Val[_addr];
	}
	else
#endif // IO_TEST
	{
		return AtomRead(sAInpVal(_addr));
	}
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni analogoveho vstupu, jen neni-li provadeno periodicke nacitani vstupu

	\param	_sig	signal
	\param	_val	hodnota vstupu
*/
//----------------------------------------------------

static inline void sSetAInp(const ioaddr_t _addr, const aiodata_t _val)
{
	// funkce se provadi nezavisle na testovacim rezimu
	AtomWrite(sAInpVal(_addr), _val);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni analogoveho vystupu

	\param	_addr	cislo vstupu

	\return	hodnota vstupu
*/
//----------------------------------------------------

static inline aiodata_t sGetAOutp(const ioaddr_t _addr)
{
#ifdef IO_TEST
	if (gIO.TestMode && (gIO.TestAOutp != NULL) && gIO.TestAOutp->Enabled[_addr])
	{
		// tento vystup je v testovacim rezimu
		return gIO.TestAOutp->Val[_addr];
	}
	else
#endif // IO_TEST
	{
		return AtomRead(sAOutpVal(_addr));
	}
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni analogoveho vystupu

	\param	_sig	signal
	\param	_val	hodnota vstupu
*/
//----------------------------------------------------

static inline void sSetAOutp(const ioaddr_t _addr, const aiodata_t _val)
{
	// funkce se provadi nezavisle na testovacim rezimu
	AtomWrite(sAOutpVal(_addr), _val);
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni Xor masky digitalniho vstupu

	\param	_sig	signal
*/
//----------------------------------------------------

static inline void sSetDInpXMask(const ioaddr_t _sig)
{
	iolock_t lock = IOLock();
	sDInpSigXByte(_sig) |= sGetByteMask(_sig);
	IOUnlock(lock);
}


//----------------------------------------------------
/**
	\brief	Funkce pro nulovani Xor masky digitalniho vstupu

	\param	_sig	signal
*/
//----------------------------------------------------

static inline void sResetInpXMask(const ioaddr_t _sig)
{
	iolock_t lock = IOLock();
	sDInpSigXByte(_sig) &= ~sGetByteMask(_sig);
	IOUnlock(lock);
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni byte Xor masky digitalnich vstupu

	\param	_idx	index byte
	\param	_val	hodnota
*/
//----------------------------------------------------

static inline void sSetDInpXMaskByte(const ioaddr_t _idx, const uint8_t _val)
{
	AtomWrite(sDInpXByte(_idx), _val);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni byte Xor masky digitalnich vstupu

	\param	_idx	index byte
*/
//----------------------------------------------------

static inline uint8_t sGetDInpXMaskByte(const ioaddr_t _idx)
{
	return AtomRead(sDInpXByte(_idx));
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni Xor masky digitalniho vystupu

	\param	_sig	signal
*/
//----------------------------------------------------

static inline void sSetDOutpXMask (const ioaddr_t _sig)
{
	iolock_t lock = IOLock();
	sDOutpSigXByte(_sig) |= sGetByteMask(_sig);
	IOUnlock(lock);
}


//----------------------------------------------------
/**
	\brief	Funkce pro nulovani Xor masky digitalniho vystupu

	\param	_sig	signal
*/
//----------------------------------------------------

static inline void sResetDOutpXMask (const ioaddr_t _sig)
{
	iolock_t lock = IOLock();
	sDOutpSigXByte(_sig) &= ~sGetByteMask(_sig);
	IOUnlock(lock);
}


//----------------------------------------------------
/**
	\brief	Funkce pro nastaveni byte Xor masky digitalnich vystupu

	\param	_idx	index byte
	\param	_val	hodnota
*/
//----------------------------------------------------

static inline void sSetDOutpXMaskByte(const ioaddr_t _idx, const uint8_t _val)
{
	AtomWrite(sDOutpXByte(_idx), _val);
}


//----------------------------------------------------
/**
	\brief	Funkce pro cteni byte Xor masky digitalnich vystupu

	\param	_idx	index byte
*/
//----------------------------------------------------

static inline uint8_t sGetDOutpXMaskByte(const ioaddr_t _idx)
{
	return AtomRead(sDOutpXByte(_idx));
}


//----------------------------------------------------
/**
	\brief	Funkce navrati stav HW digitalniho vstupu

	\param	_sig	cislo digitalniho vstupu

	\return		Aktualni hodnota signalu, pri chybe puvodni
*/
//----------------------------------------------------

bool_t hGetDInp(const ioaddr_t _sig);


//----------------------------------------------------
/**
	\brief	Okamzite nastaveni digitalniho vystupu

	\param	_sig	Adresa vystupu
	\param	_val		Nastavovana hodnota

	\return	FALSE v pripade chyby
*/
//----------------------------------------------------

bool_t hSetDOutp(const ioaddr_t _sig, const bool_t _val);


//----------------------------------------------------
/**
	\brief	Ziskani aktualni hodnoty analogoveho vstupu

	\param	_addr	Adresa vstupu

	\return	Aktualni hodnota vstupu, pri chybe hodnota puvodni (nactena poslednim tikem)
*/
//----------------------------------------------------

aiodata_t hGetAInp(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Funkce okamzite nastavujici analogovy vystup

	\param	_addr	Adresa vystupu
	\param	_val	Nastavovana hodnota

	\return	FALSE v pripade chyby
*/
//----------------------------------------------------

bool_t hSetAOutp(const ioaddr_t _addr, const aiodata_t _val);


//----------------------------------------------------
/**
	\brief	Povoleni prace IO knihovny
*/
//----------------------------------------------------

void IOEnable(void);


//----------------------------------------------------
/**
	\brief	Deaktivace IO knihovny
*/
//----------------------------------------------------

void IODisable(void);


//----------------------------------------------------
/**
	\brief	Registrace IO zarizeni

	\param	_dev				Deskriptor zarizeni
	\param	_dInpBaseAddr	Namapovani digitalnich vstupu
	\param	_dOutpBaseAddr	Namapovani digitalnich vystupu
	\param	_adInpBaseAddr	Namapovani analogovych vstupu
	\param	_aOutpBaseAddr	Namapovani analogovych vystupu

	\return	TRUE pri uspesnem zarazeni
*/
//----------------------------------------------------

bool_t IORegisterDevice(IODEVICE * const _dev, ioaddr_t _dInpBaseAddr, ioaddr_t _dOutpBaseAddr,
					const ioaddr_t _aInpBaseAddr, const ioaddr_t _aOutpBaseAddr);


//----------------------------------------------------
/**
	\brief	Vyjmuti zarizeni

	\param	_dev				Deskriptor zarizeni

	\return	TRUE pri uspesnem vyjmuti
*/
//----------------------------------------------------

bool_t IOUnregisterDevice(IODEVICE * const _dev);


//----------------------------------------------------
/**
	\brief	Prirazeni filtru danemu analogovemu vstupu

	\param	_ctx		Kontext
	\param	_input		Cislo vstupu
	\param	_K			Konstanta filtru
	\param	_timeout	Rychlost provadeni filtru
*/
//----------------------------------------------------

void IOSetExpAInpFilter(AFILTER_EXP * _ctx, const ioaddr_t _input, aiodata_t _K, ticks_t _timeout);


//----------------------------------------------------
/**
	\brief	Prirazeni filtru klouzaveho prumeru danemu analogovemu vstupu

	\param	_ctx		Kontext
	\param	_input		Cislo vstupu
	\param	_data		Pole pro ukladani dat
	\param	_size		Velikost pole
	\param	_timeout	Rychlost provadeni filtru
*/
//----------------------------------------------------

void IOSetFloatingAInpFilter(AFILTER_FLOATAVG * _ctx, ioaddr_t _input, aiodata_t *_data, uint16_t Size, ticks_t _timeout);

void IOSetUserAInpFilter(AFILTER_CTX * _ctx, ioaddr_t _input, afmFirstValue _firstValue, afmTick _tick);


//----------------------------------------------------
/**
	\brief	Prirazeni filtru k digitalnimu vstupu
	
	\param	_ctx		Kontex filtru
	\param	_input		Cislo vstupu
	\param	_timeDownTick	Minimalni doba '0' pro prechod
	\param	_timeUpTick		Minimalni doba '1' pro prechod	
*/
//----------------------------------------------------

void IOSetDInpFilter(DFILTER_CTX * _ctx, ioaddr_t _input, lticks_t _timeDownEdge, lticks_t _timeUpEdge);

//----------------------------------------------------
/**
	\brief	Zjisteni pripravenosti IO
*/
//----------------------------------------------------

bool_t IOReady(void);


//----------------------------------------------------
/**
	\brief	Tik cteni vstupu
*/
//----------------------------------------------------

void IOReadTick(void);


//----------------------------------------------------
/**
	\brief	Tik zapisu vystupu
*/
//----------------------------------------------------

void IOWriteTick(void);


//----------------------------------------------------
/**
	\brief	Tik IO knihovny
*/
//----------------------------------------------------

void IOTick(void);


#ifdef IO_TEST

//----------------------------------------------------
/**
	\brief	Spusteni testovani daneho digitalniho IO

	\param	_addr	Adresa vstupu
	\param	_val	Pozadovana hodnota
*/
//----------------------------------------------------

void IOTestDInpStart(const ioaddr_t _addr, const bool_t _val);


//----------------------------------------------------
/**
	\brief	Zastaveni testovani daneho digitalniho IO

	\param	_addr	Adresa vstupu
*/
//----------------------------------------------------

void IOTestDInpStop(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Zjisti, zda je digitalni vstup v testovacim rezimu

	\param	_addr	Adresa vstupu
*/
//----------------------------------------------------

bool_t IODInpIsTested(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Spusteni testovani daneho digitalniho IO

	\param	_addr	Adresa vystupu
	\param	_val	Pozadovana hodnota
*/
//----------------------------------------------------

void IOTestDOutpStart(const ioaddr_t _addr, const bool_t _val);


//----------------------------------------------------
/**
	\brief	Zastaveni testovani daneho digitalniho IO

	\param	_addr	Adresa vystupu
*/
//----------------------------------------------------

void IOTestDOutpStop(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Zjisti, zda je digitalni vystup v testovacim rezimu

	\param	_addr	Adresa vystupu
*/
//----------------------------------------------------

bool_t IODOutpIsTested(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Spusteni testovani daneho analogoveho vstupu

	\param	_addr	Adresa analogoveho vstupu
	\param	_val		Hodnota, ktere ma nabyvat
*/
//----------------------------------------------------

void IOTestAInpStart(const ioaddr_t _addr, const aiodata_t _val);


//----------------------------------------------------
/**
	\brief	Zastaveni testovani daneho analogoveho vstupu

	\param	_addr	Adresa analogoveho vstupu
*/
//----------------------------------------------------

void IOTestAInpStop(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Zjisti, zda je analogovy vstup v testovacim rezimu

	\param	_addr	Adresa vstupu
*/
//----------------------------------------------------

bool_t IOAInpIsTested(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Spusteni testovani daneho analogoveho vystupu

	\param	_addr	Adresa testovaneho vystupu
	\param	_val	Hodnota, ktere ma nabyvat
*/
//----------------------------------------------------

void IOTestAOutpStart(const ioaddr_t _addr, const aiodata_t _val);


//----------------------------------------------------
/**
	\brief	Zastaveni testovani daneho analogoveho vystupu

	\param	_addr	Adresa vystupu
*/
//----------------------------------------------------

void IOTestAOutpStop(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Zjisti, zda je analogovy vystup v testovacim rezimu

	\param	_addr	Adresa vystupu
*/
//----------------------------------------------------

bool_t IOAOutpIsTested(const ioaddr_t _addr);


//----------------------------------------------------
/**
	\brief	Povoleni testovaciho rezimu digitalniho IO

	\param	_testDInp	Ukazatel na testovaci strukturu digitalnich vstupu
	\param	_testDOutp	Ukazatel na testovaci strukturu digitalnich vystupu
*/
//----------------------------------------------------

void IOEnableTestMode(IODIGTEST * const _testDInp, IODIGTEST * const _testDOutp, IOANLTEST * const _testAInp, IOANLTEST * const _testAOutp);


//----------------------------------------------------
/**
	\brief	Zastaveni testovaciho rezimu
*/
//----------------------------------------------------

void IODisableTestMode(void);

#endif // IO_TEST


//----------------------------------------------------
/**
	\brief	Inicializace IO knihovny

	\param	_dInpVal	Pole pro hodnoty digitalnich vstupu
	\param	_dInpX		Pole s inverzemi digitalnich vstupu
	\param  _dInpFilter	Pole kontextu pripadnych digitalnich filtru
	\param	_dOutpVal	Pole pro hodnoty digitalnich vystupu
	\param	_dOutpX		Pole s inverzemi digitalnich vystupu
	\param	_aInpVal	Pole pro hodnoty analogovych vstupu
	\param	_aInpFilter	Pole kontextu pripadnych analogovych filtru, muze byt NULL, kdyz se nevyuzivaji
	\param	_aOutpVal	Pole pro hodnoty analogovych vystupu
*/
//----------------------------------------------------

void IOInitialize(uint8_t *const _dInpVal, uint8_t *const _dInpX, DFILTER_CTX **const _dInpFilter, uint8_t *const _dOutpVal, uint8_t *const _dOutpX,
				  aiodata_t *const _aInpVal, AFILTER_CTX **const _aInpFilter, aiodata_t *const _aOutpVal);


//----------------------------------------------------
/**
	\brief	Finalizace
*/
//----------------------------------------------------

void IOFinalize(void);

void DFilterInitialize(DFILTER_CTX *const _ctx);

#endif // _IOLIB_H_
