//----------------------------------------------------
/**
	\file		ctk/inc/canopentime.h
	\ingroup	can
	\ingroup	all

	\brief		Vrstva realizujici timeouty pro CANOpen
				<<< ALL >>>

	\author		ConTeK s.r.o., Pavel Bazika
	\version	01.01
	\date		05.09.2007
*/
//----------------------------------------------------

#ifndef _CNOPENTIME_H_
#define _CNOPENTIME_H_

#include <canopen.h>


//----------------------------------------------------
//!	Stav SDO automatu


typedef enum _COTS_STATE
{
	COTSS_READY = 0,
	COTSS_WAITSEND,
	COTSS_WAITRSP
} COTS_STATE;


//----------------------------------------------------
//!Stav PDO automatu

typedef enum _COTP_STATE
{
	COTPS_WAITOPER = 0,
	COTPS_WAITTIMER,
	COTPS_ERRORSENT,
	COTPS_BLOCKERRSEND
} COTP_STATE;


//----------------------------------------------------
//!	Forward deklarace kontextu

struct _CANOPENTIME_CTX;


//----------------------------------------------------
//@{
//!	\name	Metody objektu

typedef void (*cotmSendSDO_t) (struct _CANOPENTIME_CTX * _ctx, const CANIDTYPE _id, const sdo_cmd_t _command, const sdo_index_t _index, 
							   const sdo_subindex_t _subIndex, const void * _data, const uint8_t _size);

typedef void (*cotmSendError_t) (const struct _CANOPENTIME_CTX * _ctx);

typedef void (*cotmNoResponse_t) (const struct _CANOPENTIME_CTX * _ctx);

typedef void (*cotmPDOError_t) (const struct _CANOPENTIME_CTX * _ctx);

typedef COMSG_TYPE (*cotmRecv_t) (struct _CANOPENTIME_CTX * _ctx, const CAN_BUFFER * _msg);

typedef void (*cotmTick_t) (struct _CANOPENTIME_CTX * _ctx);
//@}


//----------------------------------------------------
//!	Struktura pro uchovani SDO pozadavku

typedef struct _CANOPENTIME_SDOREQ
{
	CANIDTYPE		ID;
	uint8_t			DataSize;
	CANOPENMSG_SDO	Msg;
} CANOPENTIME_SDOREQ;


//----------------------------------------------------
//!	Kontext objektu

typedef struct _CANOPENTIME_CTX
{
	CANOPEN_CTX			Parent;			//!< Predek

	COTS_STATE			SState;			//!< Stav automatu kontroly SDO komunikace
	COTP_STATE			PState;			//!< Stav automatu kontroly PDO komunikace

	// metody
	cotmSendSDO_t		SendSDO;		//!< Metoda pro odeslani SDO

	// callbacky
	cotmSendError_t		cbSendError;	//!< Callback volany pri chybe vysilani
	cotmNoResponse_t	cbNoResponse;	//!< Callback volany v pripade, ze neprisla odpoved na pozadavek
	cotmPDOError_t		cbPDOError;		//!< Callback volany pri preruseni pravidelneho prijmu PDO
	cotmRecv_t			cbRecv;			//!< Callback volany pri prijmu paketu
	cotmTick_t			cbTick;			//!< Callback volany pri tiku

	// hodnoty timeoutu
	ticks_t				RetryTimeout;	//!< timeout mezi odeslanim pozadavku, paklize neprisla odpoved
	uint8_t				RetryCount;		//!< pocet opakovani pozadavku
	ticks_t				SendTimeout;	//!< timeout odeslani zpravy
	lticks_t			PeriodTimeout;	//!< timeout prijeti pravidelne PDO zpravy

	// casovace - odmeruji cas timeoutu
	ticks_t				RetryTimer;
	uint8_t				RetryCounter;
	ticks_t				SendTimer;
	lticks_t			PeriodTimer;

	CANOPENTIME_SDOREQ	SDOReq;				//!< buffer na ulozeni pozadavku

	volatile bool_t		flRunning;			//!< Priznak inicializace knihovny

} CANOPENTIME_CTX;


//----------------------------------------------------
/**
	\brief	Funkce zjistuje, zda je knihovna pripravena k vysilani

	\param	_ctx		Kontext CANOpenTime

	\return	TRUE	V pripade, ze je knihovna pripravena
*/
//---------------------------------------------------

bool_t COTReady(const CANOPENTIME_CTX * const _ctx);


//----------------------------------------------------
/**
	\brief	Funkce umoznuje vypnout hlidani PDO

	\param	_ctx		Kontext CANOpenTime
	\param	_block		Je-li TRUE, pak se vola callback s chybou pri vyprseni PDO timeoutu
*/
//!---------------------------------------------------

void COTPEnablePDOError(CANOPENTIME_CTX * const _ctx, const bool_t _enable);


//----------------------------------------------------
/**
//!	\brief	Inicializace knihovny

	\param	_ctx			Kontext CANOpenTime
	\param	_cmm			Pridruzeny komunikacni objekt
	\param	_priority		Priorita tohoto zarizeni v ramci seznamu CANDEVICE
	\param	_retryTimeout	Prodleva mezi opakovanim pozadavku
	\param	_retryCount		Pocet opakovani pozadavku
	\param	_sendTimeout	Maximalni doba pro odeslani pozadavku
	\param	_periodTimeout	Maximalni prodleva mezi prichody PDO zpravy

	\return	TRUE			Pokud inicializace probehla uspesne
*/
//----------------------------------------------------

bool_t COTInitialize(CANOPENTIME_CTX * const _ctx, CANCOMMDESC * const _cmm, const uint8_t _priority, const ticks_t _retryTimeout,
						const uint8_t _retryCount, const ticks_t _sendTimeout, const lticks_t _periodTimeout);


//----------------------------------------------------
/**
	\brief	Ukonceni knihovny

	\param	_ctx	Kontext CANOpenTime

	\return	TRUE	Pokud se ukonceni zdarilo
*/
//----------------------------------------------------

bool_t COTFinalize(CANOPENTIME_CTX * const _ctx);

#endif // _CANOPENTIME_H_
