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

	\brief		Knihovna pro pristup k nevolatilním pametem
				<<< ALL >>>
			
	\author		ConTeK s.r.o., Ing. Vladimir Kastner
	\version	01.01
	\date		12.01.2007
*/
//----------------------------------------------------

#ifndef _NVMEMSTOR_H_
#define _NVMEMSTOR_H_

#include <ctktypes.h>
#include <nvmem.h>
//#include <ucrc16.h>

//----------------------------------------------------
//!	\brief	Definice backlogu
//!	\note	Maximalni velikost dat backlogu

#define MAXBLOGSIZE		256		 


//----------------------------------------------------
//!	\brief	Hlavicka pameti 
//!
//!	\note	musi byt zarovnano na modulo 4
//!
typedef struct
{
	uint16_t	Magic;			//!< Cislo MAGIC_NUMBER
	uint16_t	Version;		//!< Verze datove zakladny

} MEMHEADER;


//----------------------------------------------------
//!	Polozka backlogu 
//!
typedef struct
{
	uint8_t		NvIndx;					//!< index nevolatilni pameti
	void *		RamPtr;					//!< Adresa dat v ram
	ptr_t		MemPtr;					//!< Adresa dat v mem
	ptr_t		DSize;					//!< Delka dat
//	ptr_t		SegRamPtr;				// Adresa segmentu dat v ram
//	ptr_t		SegMemPtr;				// Adresa segmentu dat v ram
//	ptr_t		SegDSize;				// Delka segmentu dat
	uint8_t		Data[ MAXBLOGSIZE ];	//!< Data
	
} BLOGITEM;


//----------------------------------------------------
//!	\brief	Struktura backlogu
//!
//!	\note	musi byt zarovnano na modulo 4
//!
typedef struct
{
	bool_t		Valid;			//!< Priznak platnosti, TRUE = data platna
//	crc16_t		Crc;			// Crc polozky
	BLOGITEM	Item;			//!< Polozka backlogu
	
} BACKLOG;


//----------------------------------------------------
//!	Maximalni pocet nevolatilnich pameti

#define MAXNVMEMSTOR	4


//----------------------------------------------------
//!	\brief	Kontext automatu pro pristup k nevolatilnim datum
//!
//!	\note	Backlog data jsou vytvarena v prvni nevolatilni pameti NvMemArray[0]
//!			tato pamet musi byt typu RAM
//!
typedef struct 
{
	volatile bool_t		flRunning;			//!< je inicializovano, po ininializaci na TRUE, pred ukoncenim FALSE
	volatile bool_t		flTick;				//!< je provaden Tick = TRUE
	volatile uint8_t	State;				//!< Stav automatu
	uint8_t		OldState;				//!< Minuly stav automatu
	uint8_t		Cmd;					//!< Prikaz
	uint8_t		Res;					//!< Vysledek operace
	uint16_t	NvVersion;				//!< Verze nevolatilni datove struktury
	volatile NVMEMDESC *	NvMem;		//!< Aktualni nevolatilni pamet
	volatile NVMEMDESC *	NvMemArray[ MAXNVMEMSTOR ]; //!< Seznam nevolatilnich pameti
	BACKLOG		BLog;					//!< Backlog data

} NVMEMSTORDESC;

#define FirstPass (nvmsD->State != nvmsD->OldState)


//----------------------------------------------------
/**
	\brief	Kontext automatu NvMemStor
*/
//----------------------------------------------------

extern NVMEMSTORDESC NvMemStor;


//----------------------------------------------------
//!	\name	Pocatky umisteni struktur v nevolatilni pameti
//@{

#define nvmem nvmsD->NvMem
#define nvindx nvmsD->BLog.Item.NvIndx

#define NvBLog NvMemArray[0]
#define nvblog nvmsD->NvMemArray[0]

#define MemHeadPtr 0
#define HeadSize sizeof(MEMHEADER)

#define DataBLogPtr &nvmsD->BLog.Item.Data[0]
#define RamBLogPtr &nvmsD->BLog
#define MemBLogPtr sizeof(MEMHEADER)
#define BLogSize sizeof(BACKLOG)

#define MemDataPtr \
	( nvmsD->BLog.Item.NvIndx ) ? \
		nvmsD->BLog.Item.MemPtr  + sizeof(MEMHEADER) : \
		nvmsD->BLog.Item.MemPtr  + sizeof(MEMHEADER) + sizeof(BACKLOG)
#define RamDataPtr nvmsD->BLog.Item.RamPtr
#define DataSize nvmsD->BLog.Item.DSize

#define nvversion nvmsD->NvVersion
//@}

//----------------------------------------------------
/**
	\brief	Krok automatu pro pristup k datum nevolatilni pameti

	\param	nvmsD	struktura contextu automatu
*/
//----------------------------------------------------

void NvMemStorTick( NVMEMSTORDESC * nvmsD );


//----------------------------------------------------
/**
	\brief	Funkce pro testovani, zda je mozne automatu
			predat prikaz (tj. zavolat napr. NvMemStoreWrite)

	\param	nvmsD	struktura contextu automatu

	\return	TRUE	automat je schopen akceptovat dalsi prikaz
			FALSE	automat neni schopen
*/
//----------------------------------------------------

bool_t NvMemStorReady( NVMEMSTORDESC * nvmsD );


//----------------------------------------------------
/**
	\brief	Funkce platnosti dat v nevolatilni pameti

	\param	nvmsD	struktura contextu automatu
	\param	nvIndx	index nevolatilni pamet
	\param	memPtr	adresa kam se data v nevolatilni pameti ulozi
	\param	ramPtr	adresa odkud se budou data cist
	\param	dSize	velikost ukladanych dat
*/
//----------------------------------------------------

void NvMemStorCheck( NVMEMSTORDESC * nvmsD, uint8_t nvIndx );


//----------------------------------------------------
/*
	\brief	Funkce inicializace nevolatilni pameti

	\param	nvmsD	struktura contextu automatu
	\param	nvIndx	index nevolatilni pamet
	\param	memPtr	adresa kam se data v nevolatilni pameti ulozi
	\param	ramPtr	adresa odkud se budou data cist
	\param	dSize	velikost ukladanych dat
*/
//----------------------------------------------------

//void NvMemStorInit( NVMEMSTORDESC * nvmsD, uint8_t nvIndx, ptr_t memPtr, ptr_t ramPtr, ptr_t dSize );


//----------------------------------------------------
/**
	\brief	Funkce zabezpeceneho zapisu dat z RAM do nevolatilni pameti

	\param	nvmsD	struktura contextu automatu
	\param	nvIndx	index nevolatilni pamet
	\param	memPtr	adresa kam se data v nevolatilni pameti ulozi
	\param	ramPtr	adresa odkud se budou data cist
	\param	dSize	velikost ukladanych dat
*/
//----------------------------------------------------

void NvMemStorWrite( NVMEMSTORDESC * nvmsD, uint8_t nvIndx, ptr_t memPtr, void * ramPtr, ptr_t dSize );


//----------------------------------------------------
/**
	\brief	Funkce pro cteni dat z nevolatilni pameti do RAM
			
	\param	nvmsD	struktura contextu automatu
	\param	nvIndx	index nevolatilni pamet
	\param	ramPtr	adresa odkud se budou data cist
	\param	memPtr	adresa kam se data v nevolatilni pameti ulozi
	\param	dSize	velikost ukladanych dat
*/
//----------------------------------------------------

void NvMemStorRead( NVMEMSTORDESC * nvmsD, uint8_t nvIndx, void * ramPtr, ptr_t memPtr, ptr_t dSize );


//----------------------------------------------------
/**
	\brief	Inicializace automatu pro pristup k parametrum nevolotilni pameti

	\param	nvmsdD	struktura contextu automatu
	\param	nvMem1	ukazatel na nvmem, prvni musi byt typu RAM, je v ni ukladan backlog
	\param	memPtr	ukazatel do datove casti nvmem
	\param	defPtr	ukazatel na default data, ktera se v pripade potreby nakopiruji
	\param	dSize	velikost dat
	\param	cpDefault	1 v mnozine bitu prikazuje danou nvmem inicializovat, i kdyz data v ni obsasena jsou v poradku
	\param	ldDefault	1 v mnozine bitu oznamuje, ze v dane nvmem byla data inicializovana 

	\return	TRUE	inicializace probehla v poradku
			FALSE	chyba
*/
//----------------------------------------------------

bool_t NvMemStorInitialize( NVMEMSTORDESC * nvmsD,
							void * ramPtr1, volatile NVMEMDESC * nvMem1, ptr_t memPtr1, void * defPtr1, ptr_t dSize1,
							void * ramPtr2, volatile NVMEMDESC * nvMem2, ptr_t memPtr2, void * defPtr2, ptr_t dSize2,
							void * ramPtr3, volatile NVMEMDESC * nvMem3, ptr_t memPtr3, void * defPtr3, ptr_t dSize3,
							void * ramPtr4, volatile NVMEMDESC * nvMem4, ptr_t memPtr4, void * defPtr4, ptr_t dSize4,
							uint16_t nvVersion,
							uint8_t cpDefault,
							uint8_t * ldDefault);


//----------------------------------------------------
/**
	\brief	Ukonceni automatu pro pristup k parametrum v nevolatilni pameti

	\param	nvmsD	struktura contextu automatu
*/
//----------------------------------------------------

void NvMemStorFinalize( NVMEMSTORDESC * nvmsD );


#endif // _NVMEMSTOR_H_
