//----------------------------------------------------
/**
	\file		onewire.h	
	\ingroup	all
	
	\brief	Knihovna one-wire komunikace	
			<<< ALL >>>
			
	\author	ConTeK s.r.o., Bc. Stanek Jan	
	\version	01.02
	\date		16.7.2010
*/
//----------------------------------------------------
#ifndef _ONEWIRE_H_
#define _ONEWIRE_H_		//!< Definice pritomnosti knihovny

#include <libsets.h>
#ifndef MSVC
 #include <onewireHW.h>
#endif 
#include <stmachine.h>
#include "hal.h"
#include "nlist2.h"

struct _ONE_WIRE_CTX;
typedef void (*owCallback)(struct _ONE_WIRE_CTX * _ctx, bool_t _status);	//!< Definice callbacku

//----------------------------------------------------
//!	\name	Definice obecnych prikazu 1-wire
//@{
#define OW_READ_ROM		0x33	//!< Cteni identifikace zarizeni - musi byt pripojeno pouze jedno zarizeni
#define OW_MATCH_ROM	0x55	//!< Adresace konkretniho zarizeni
#define OW_SKIP_ROM		0xCC	//!< Adresace vsech zarizeni na sbernici
//@}

//----------------------------------------------------
//!	\name	Definice vyhledavacich prikazu 1-wire
//@{	//!	\note	Vyhledavani podle prikazu neimplementovano
#define OW_COND_SEARCH	0xEC	//!< Vyhledavani zarizeni s aktivnim priznakem (alarm atd..)
#define OW_SEARCH_ROM	0xF0	//!< Vyhledavani vsech zarizeni
//@}


//----------------------------------------------------
/**
	\brief  Kontext one-wire zarizeni
*/
//----------------------------------------------------
typedef struct _ONE_WIRE_DEVICE
{
	uint8_t	FamilyID;				//!< Identifikace - typ zarizeni
	uint8_t	ID[6];					//!< Identifikace - unikatni ID
	uint8_t	CRC;					//!< Kontrolni soucet ID retezce
	struct _ONE_WIRE_CTX * host;	//!< Ukazatel na sbernici
#ifndef MSVC
} __attribute__((packed)) ONE_WIRE_DEVICE;
#else
}ONE_WIRE_DEVICE;
#endif

//----------------------------------------------------
/**
	\brief  Kontext obsluhy one-wire sbernice
*/
//----------------------------------------------------
typedef struct _ONE_WIRE_CTX
{
	HAL_CTX		Parent;			//!< Rodic vrstvy

	uint8_t		channel;		//!< Prirazeny kanal
	uint8_t		device_count;	//!< Zadany pocet pripojenych zarizeni
	uint8_t		device_found;	//!< Pocet nalezenych zarizeni

	STMACHINE	Stm;			//!< Stavovy automat obsluhy

	LIST		devices;		//!< List nalezenych zarizeni

	bool_t running;				//!< Priznak inicializace
	bool_t ready;				//!< Priznak zda jiz jsou zarizeni nalezena
	bool_t (*isReady)(struct _ONE_WIRE_CTX * _ctx);	//!< Dotaz na pripravenost zarizeni

	struct
	{
		STMACHINE	Stm;		//!< Automat bytovych transakci
		bool_t		Tx_rq;		//!< Priznak pozadavku na vysilani
		uint8_t		byte_Tx;	//!< Obsah vysilaneho bytu
		uint8_t		byte_Rx;	//!< Obsah prijateho bytu
		uint8_t		bit_index;	//!< Ukazatel aktualne zpracovavaneho bitu
	}byteExchange;

	struct
	{
		uint8_t *	ID;			//!< ID obsluhovaneho zarizeni
		uint8_t *	Tx;			//!< Ukazatel dat pro odeslani
		uint8_t	*	Rx;			//!< Ukazatel pameti pro prijem
		uint8_t		RomCMD;		//!< Prikaz adresace
		uint8_t		FceCMD;		//!< Prikaz funkce
		uint8_t		tx_size;	//!< Velikost bloku odesilanych dat
		uint8_t		rx_size;	//!< Velikost bloku prijmanych dat
		owCallback	cb;			//!< Callback volany po dokonceni transakce
		uint16_t	timeLock;	//!< Cas uzamceni sbernice pro dalsi transakce
		uint8_t		index;		//!< Pomocna promenna transakce
	}transact;

	struct
	{
		STMACHINE	Stm;					//!< Stavovy automat prohledavani sbernice

		uint8_t		ROM_no[8];				//!< Posledni nalezene ID

		//indexy prohledavani
		uint8_t		bit_index;				//!< Aktualni pozice
		uint8_t		LastDiscrepancy;		//!< Pozice posledni kolize
		uint8_t		LastFamilyDiscrepancy;	//!< Pozice posledni kolize
		uint8_t		LastZero;				//!< Pozice posledni nalezene nuly

		bool_t		LastDeviceFlag;			//!< Priznak nalezeni vsech zarizeni

		bool_t		SearchDirection;		//!< Zvoleny smer prohledavani dalsiho bitu

		bool_t		id_bit;					//!< Precteny bit
		bool_t		id_bit_cmp;				//!< Precteny negovany bit

		bool_t		SearchResult;			//!< Vysledek posledniho prohledavani

	}searchRom;

	struct _ONE_WIRE_CTX * next;			//!< Odkaz na dalsi sbernici (pro spojovy seznam)

}ONE_WIRE_CTX;

//extern uint8_t owCRC8_table[256];

//----------------------------------------------------
/**
	\brief Ziska cislo stranky z adresy
	\param _ctx		Kontext one-wire sbernice
	\param _index	Index zarizeni nalezeneho na sbernici
	\return Ukazatel k zarizeni na dane pozici
*/
//----------------------------------------------------
ONE_WIRE_DEVICE * getDeviceByIndex(ONE_WIRE_CTX * _ctx, uint8_t _index);

//----------------------------------------------------
/**
	\brief Ziska cislo stranky z adresy
	\param _ctx		Kontext one-wire sbernice
	\param _RomId	Identifikacni retezec zarizeni nalezeneho na sbernici
	\return Ukazatel k zarizeni na dane pozici
*/
//----------------------------------------------------
ONE_WIRE_DEVICE * getDeviceByID(ONE_WIRE_CTX * _ctx, uint8_t * _RomId);

//----------------------------------------------------
/**
	\brief Ziska cislo stranky z adresy
	\param _ctx		Kontext one-wire sbernice
	\param _RomCmd	Prikaz adresace
	\param _RomID	Ukazatel identifikace R/W (adresa)
	\param _FceCmd	Prikaz funkce
	\param _txMsg	Ukazatel na vysilany blok dat
	\param _txSize	Velikost odesilanych dat
	\param _rxMsg	Ukazatel na pamet pro prijem
	\param _rxSize	Velikost prijmanych dat
	\param _timeLock	Doba uzamceni sbernice po dokonceni transakce v ms
	\param _cb		Callback volany po dokonceni transakce
	\return TRUE	Transakce je prijata ke zpracovani
	\return FALSE	Sbernice obsazena predchozi transakci nebo nezadan _RomCmd
*/
//----------------------------------------------------
bool_t OneWireTransact(ONE_WIRE_CTX * _ctx, uint8_t _RomCmd, uint8_t* _RomID, uint8_t _FceCmd,	\
											uint8_t* _txMsg, uint8_t _txSize,					\
											uint8_t* _rxMsg, uint8_t _rxSize,					\
											uint16_t _timeLock, owCallback _cb);

//----------------------------------------------------
/**
	\brief Inicializace kontextu one-wire sbernice
	\param _ctx		Kontext one-wire sbernice
	\param _channel	Prirazeny kanal sbernice
	\param _count	Predpokladany pocet zarizeni na sbernici
	\return TRUE	Pokud inicializace probehla v poradku
*/
//----------------------------------------------------
bool_t OneWireInitialize(ONE_WIRE_CTX * _ctx, uint8_t _channel, uint8_t _count);

#endif //_ONEWIRE_H_
