//----------------------------------------------------
/**
	\file		ctk/hw/dataflash_at45db.h
	\ingroup	hardware
	\ingroup	arm7

	\brief		Knihovna pro pristup k DataFlash pameti AT45DB011
				<<< CTBRD06 >>>

	\author		ConTeK s.r.o., Pavel Bazika
	\version	01.01
	\date		02.04.2007

	\note		Urceno pro vlozeni do hwboard

	\todo		Komentar k funkci na radku 197 a zkopirovat ho do "c"
*/
//----------------------------------------------------

#ifndef _DATAFLASH_AT45DB_H_
#define _DATAFLASH_AT45DB_H_

#include <hwsubmdl.h>
#include <nvmem.h>
#include <libsets.h>
#include <dataflash_at45db_cmd.h>
#include <sync.h>
#include "stmachine.h"


//----------------------------------------------------
//!	Stavy automatu operaci dataflash

/*typedef enum _DATAFLASH_FSM
{
	DFS_IDLE = 0,				//!< Zadna cinnost
	//DFS_BW_STOREOLDPAGE,		//!< Buffered write - ulozeni predchozi stranky
	//DFS_BW_WAIT_STOREOLDPAGE,	//!< Buffered write - cekani na ulozeni predchozi stranky
	//DFS_BW_WAIT_READPAGE,		//!< Buffered write - nacteni nove stranky do bufferu
	//DFS_BW_WRITEDATA,			//!< Buffered write - zapis dat do bufferu se strankou
	//DFS_BW_WAIT_WRITEDATA,		//!< Buffered write - cekani na zapis dat do bufferu

	DFS_WAIT,					//!< Cekani na dokonceni prikazu
	DFS_STATUSCHECK,			//!< Prvni cekani na RDY v status registru
	DFS_STATUSWAIT,				//!< Cekani na RDY v status registru
	DFS_WAITCOMPARE				//!< Cekani na porovnani bufferu s pameti

} DATAFLASH_FSM;*/


//----------------------------------------------------
//!	Operace dataflash

typedef enum _DATAFLASH_TICK_OP
{
	DOP_NONE = 0,
	DOP_STATUSWAIT,
	DOP_COMPARE
} DATAFLASH_TICK_OP;

//----------------------------------------------------
//!	Kontext dataflash

typedef struct _DATAFLASH_CTX
{
	NVMEMDESC			Parent;				//!< Nonvolatile mem deskriptor

	STMACHINE			TickStm;			//!< Automat obsluhy cekajicich transakci dataflash

	union
	{
		uint8_t * RW;
		const uint8_t * RO;
	} RamAddr;								//!< Adresa v RAM pri operaci

	uint16_t			FlashPage;			//!< Stranka ve flash pri operaci
	uint16_t 			FlashAddr;			//!< Adresa v ramci stranky pri operaci
	ptr_t				Size;				//!< Velikost dat, nad kterymi se operuje

	SPIDESC				*Spi;				//!< Kontext spi, kam je dataflash pripojena
	uint8_t				SpiChannel;			//!< Kanal spi

	uint16_t			BufferedPage;		//!< Cislo stranky nactene do bufferu

	uint8_t				PageAddrBits;		//!< Pocet bitu v adrese bytu v ramci stranky
	uint16_t			PageAddrMask;		//!< Maska na vymaskovani cisla stranky z adresy
	uint16_t			PageSize;			//!< Velikost stranky
	uint16_t			PageCount;			//!< Pocet stranek

	uint8_t				SecurityRegUserSize;		//!< Velikost programovatelne casti security registru
	uint8_t				SecurityRegSize;			//!< Velikost security registru

	bool_t				CompareResult;		//!< Misto pro ulozeni vysledku porovavani

	volatile bool_t		SignalTick;			//!< Priznak dokonceni operace, na kterou v tiku cekame
	DATAFLASH_TICK_OP	TickOperation;		//!< Operace provadena v tiku
	uint8_t				OperationStatus;	//!< Stav posledni SPI operace

	STMACHINE			BuffWrStm;			//!< Automat obsluhy bufferedWrite transakci
	volatile bool_t		WrStmWaiting;		//!< Priznak provadeni transakce uvnitr bufferedWrite automatu

	DECL_DMA_STRUCT_ITEM(uint8_t, HwStatus);			//!< Uloziste pro status registr
	DECL_DMA_STRUCT_ITEM(DFC_BYTE, CmdStatus);			//!< Prikaz pro cteni status registru
	DECL_DMA_STRUCT_ITEM(DFC_ADDR, CmdAddr);			//!< Prikaz pro praci s adresou
	DECL_DMA_STRUCT_ITEM(DFC_ADDR_DUM1, CmdAddrDum1);	//!< Prikaz pro praci s adresou (jen stranka)
	DECL_DMA_STRUCT_ITEM(DFC_ADDR_DUM4, CmdAddrDum4);	//!< Prikaz pro praci s adresou (cteni)
} DATAFLASH_CTX;


//----------------------------------------------------
/**
 	\brief	Zapis dat do dataflash pres buffer

	\note 	Funkce vyuziva buffer dataflash pro zapis dat. Stranka je nactena do bufferu
		 	a modifikovana. Pri pozadavku na zapis do jine stranky je stranka v bufferu
		 	vymenena. Stranku lze take zapsat explicitne pomoci funkce DataFlashSaveBufferedPage

	\param	ctx			Kontext dataflash
	\param	Page		Stranka, do ktere se zapisuje
	\param	Addr		Adresa v ramci stranky
	\param	Buffer		Data k zapisu, prenaseny pres DMA
	\param	Size		Velikost dat k zapisu
*/
//----------------------------------------------------

bool_t DataFlashWriteBuffered(DATAFLASH_CTX * const _ctx, const uint16_t _page, const uint16_t _addr,
		const void * const _buffer, const uint16_t _size);


//----------------------------------------------------
/**
	\brief	Zapis sranky z bufferu do dataflash

	\param	ctx 	Kontext dataflash

*/
//----------------------------------------------------

bool_t DataFlashSaveBufferedPage(DATAFLASH_CTX * const _ctx);


//----------------------------------------------------
/**
 	\brief	Nacteni dat ze stranky v dataflash

	\note	Funkce cte data z dataflash. Data se musi nachazet ve stejne strance.

	\param	ctx			Kontext dataflash
	\param	Buffer		Misto pro ulozeni dat, prenaseno pres DMA
	\param	Page		Stranka dataflash
	\param	Addr		Adresa v ramci stranky
	\param	Size		Velikost prenasenych dat
*/
//----------------------------------------------------

bool_t DataFlashReadFromPage(DATAFLASH_CTX * const _ctx, const uint16_t _page, const uint16_t _addr, void * const _buffer,
		const uint16_t _size);


//----------------------------------------------------
/**
 	\brief	Cteni obsahu interniho bufferu 1

	\param	ctx			Kontext dataflash
	\param	_addr		Adresa v ramci bufferu
	\param	_buffer		Buffer pro ulozeni dat
	\param	_size		Pocet bytu k nacteni
*/
//----------------------------------------------------

bool_t DataFlashReadBuf1(DATAFLASH_CTX * const _ctx, const nvptr_t _addr, void * const _buffer, const nvptr_t _size);


//----------------------------------------------------
/**
 	\brief	Zapis dat z procesoru do vnitrniho bufferu 1

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

bool_t DataFlashWritePage2Buf1(DATAFLASH_CTX * const _ctx, const uint16_t _addr, void * const _buffer, const uint16_t _size);


//----------------------------------------------------
/**
	\brief	Zapis dat z procesoru do vnitrniho bufferu 2

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

void DataFlashWritePage2Buf2(DATAFLASH_CTX * const _ctx, const uint16_t _addr, const void * const _buffer, const uint16_t _size);


//----------------------------------------------------
/**
 	\brief	Zapis dat z bufferu 1 do stranky pameti

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

void DataFlashWriteBuf12MemNoErase(DATAFLASH_CTX * const _ctx, const uint16_t _page);


//----------------------------------------------------
/**
 	\brief	Zapis dat z bufferu 2 do stranky pameti

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

void DataFlashWriteBuf22MemNoErase(DATAFLASH_CTX * const _ctx, const uint16_t _page);


//----------------------------------------------------
/**
 	\brief	Zapis dat z bufferu 1 do stranky pameti s predvymazem

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

bool_t DataFlashWriteBuf12MemAutoErase(DATAFLASH_CTX * const _ctx, const uint16_t _page);


//----------------------------------------------------
/**
 	\brief	Zapis dat z bufferu 2 do stranky pameti s predvymazem

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

void DataFlashWriteBuf22MemAutoErase(DATAFLASH_CTX * const _ctx, const uint16_t _page);


bool_t DataFlashWriteMem2PageBuf2AutoErase(DATAFLASH_CTX * const _ctx, const uint16_t _page, const uint16_t _addr,
		void * const _buffer, const uint16_t _size);


//----------------------------------------------------
/**
	\name		Nacteni stranky z dataflash do interniho bufferu

	\param		_ctx				Kontext dataflash
	\param		_page			Cislo stranky, do ktere se bude zapisovat
	\param		_userData		Data predana callbacku

	\return		FALSE pri spatne adresaci, nebo v pripade chyby

	\note		Dokonceni operace je indikovano ve status registru dataflash
*/
//-----------------------------------------------------
bool_t DataFlashReadPage2Buf1(DATAFLASH_CTX * const _ctx, const uint16_t _page, void * const _userData);


//----------------------------------------------------
/**
 	\brief	Porovnani obsahu bufferu 1 a stranky

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

bool_t DataFlashCompareBuf1(DATAFLASH_CTX * const _ctx, const uint16_t _page);


//----------------------------------------------------
/**
 	\brief	Porovnani obsahu bufferu 2 a stranky

	\param	ctx			Kontext dataflash
	\param	Page		Stranka dataflash
*/
//----------------------------------------------------

void DataFlashCompareBuf2(DATAFLASH_CTX * const _ctx, const uint16_t _page);


//----------------------------------------------------
/**
 	\brief	Vraci vysledek posledni operace compare

	\param	ctx			Kontext dataflash
*/
//----------------------------------------------------

static inline bool_t DataFlashCompareResult(const DATAFLASH_CTX * const _ctx)
{
	return _ctx->CompareResult;
}


//----------------------------------------------------
/**
 	\brief	Vymaz stranky dataflash

	\param	ctx		Kontext dataflash
	\param	Page	Stranka k vymazu
*/
//----------------------------------------------------

bool_t DataFlashErasePage(DATAFLASH_CTX * const _ctx, const uint16_t _page);


//----------------------------------------------------
/**
 	\brief	Tik dataflash

	\param	ctx		Kontext dataflash
*/
//----------------------------------------------------

void DataFlashTick(DATAFLASH_CTX * const _ctx);
void DataFlashWriteBufferedTick(DATAFLASH_CTX * const _ctx);


//----------------------------------------------------
/**
	\brief	Funkce pro inicializaci dataflash

	\param	ctx				Kontext dataflash
	\param	memD			Deskriptor nonvolatilni pameti
	\param	SpiNumber		Cislo SPI, kam je dataflash pripojena
	\param	SpiChannel		Kanal SPI
	\param	PageCount		Pocet stranek dataflash
	\param	PageSize		Velikost stranky dataflash

	\return	TRUE	inicializace probehla v poradku
			FALSE	chyba
*/

bool_t DataFlashStaticInitialize(DATAFLASH_CTX * const _ctx, SPIDESC * const _spi,
		const uint8_t _spiChannel, const uint16_t _pageCount, uint16_t _pageSize);

//----------------------------------------------------
/**
	\brief	Funkce pro inicializaci dataflash s autodetekci

	\param	ctx				Kontext dataflash
	\param	memD			Deskriptor nonvolatilni pameti
	\param	spi				Deskriptor SPI
	\param	SpiChannel		Kanal SPI

	\return	TRUE	inicializace probehla v poradku
			FALSE	chyba

	Pro uspesnou detekci je treba mit inicializovane spi
*/
//----------------------------------------------------

bool_t DataFlashDynamicInitialize(DATAFLASH_CTX * const _ctx, SPIDESC * const _spi, const uint8_t _spiChannel );


//----------------------------------------------------
/**
	\brief	Funkce pro ukonceni pristupu k nevolatilni pameti

	\param	ctx		Kontext dataflash
*/
//----------------------------------------------------

void DataFlashFinalize(DATAFLASH_CTX * const _ctx);


#endif	// _DATAFLASH_AT45DB_H_
