#ifndef _W25QXX_H
#define _W25QXX_H

#include <stdbool.h>
//#include "spi.h"

#define NEW_FW_CHECK  0x2000
#define NEW_FW_START  0x2000

#ifdef __cplusplus
 extern "C" {
#endif

struct data_in_flash
 {
	uint8_t start;
	char gn_no[2];
	uint8_t tagid[12];
	char start_time[18];
	char stop_time[18];
	char Total_time[4];
	char Bill_Amount[4];
	uint8_t ocpp_status[10];
 	uint16_t crc;
 	uint8_t end;
 	uint8_t dummy;
 };
extern struct data_in_flash data_to_flash,data_from_flash,data_to_check;
 struct Charger_status
  {
 	uint8_t start;
 	uint8_t stop;
 	char reson;
 	char error;
 	char On_Going_Tx;
 	uint32_t start_energy;
 	uint16_t voltage;
 	uint32_t energy;
 	uint8_t start_tagid[21];
 	uint32_t transaction_id;
 	char stop_time[28];
 	uint16_t charging_time;
 	uint32_t stop_energy;
 	//uint8_t stop_tagid[14];
	uint8_t Retries;   //           V3.3.1 changed
 	uint16_t Bill_Amount;
 	uint8_t ocpp_status;
 	uint8_t charging_status;
 	uint8_t charging_counter;
 	uint16_t charge_by_time;
 	uint16_t charge_by_energy;
 	uint8_t charge_by_automatic;
 	int timer;
 	unsigned int Clock_Align_Timer;
 	uint8_t hmi[36];
 	float current;
 	float power;
 	char start_time[28];
 	char start_transaction[15];
 	char stop_transaction[15];
 	char Statusnotification[15];
 	char metervalue[15];
 	char Authorised[15];
 	uint8_t Authentication_done;
 	char expiry_tag[28];
  };

extern struct Charger_status charger_status_G1, charger_status_G2, charger_status_G3;

struct rfid_data_in_flash
 {
	uint8_t start;
	char TagId[20];
	char expiry_time[28];
	char status;
 	uint16_t crc;
 	uint8_t end;
 	uint8_t dummy;
 };

extern struct rfid_data_in_flash rfid_data_to_flash,rfid_data_from_flash,rfid_data_to_check;

struct rfid_data_to
 {
	char TagId[10][20];
	char expiry_time[10][28];
	char status[10];
 };
extern struct rfid_data_to rfid_data;
typedef enum
{
	W25Q10=1,
	W25Q20,
	W25Q40,
	W25Q80,
	W25Q16,
	W25Q32,
	W25Q64,
	W25Q128,
	W25Q256,
	W25Q512,
}W25QXX_ID_t;


typedef struct
{
	W25QXX_ID_t	ID;
	uint8_t			UniqID[8];
	uint16_t    PageSize;
	uint32_t		PageCount;
	uint32_t		SectorSize;
	uint32_t		SectorCount;
	uint32_t		BlockSize;
	uint32_t		BlockCount;

	uint32_t		CapacityInKiloByte;
	
	uint8_t	StatusRegister1;
	uint8_t	StatusRegister2;
	uint8_t	StatusRegister3;
	
	volatile uint8_t	Lock;
	
}w25qxx_t;

extern w25qxx_t	w25qxx;

typedef struct
{
  uint16_t  StructGuard1;
  uint32_t  lastPointer;
  uint16_t  StructGuard2;

}FlashInfo_t;

typedef struct
{
  uint16_t  StructGuard1;
  uint16_t Added_rfid;
  uint16_t verion;
  uint32_t  lastPointer;
  uint16_t  StructGuard2;

}Rfid_FlashInfo_t;

extern FlashInfo_t FlashInfo;
extern FlashInfo_t FlashInfo_1;
extern Rfid_FlashInfo_t rfid_pointer;

//############################################################################
// in Page,Sector and block read/write functions, can put 0 to read maximum bytes 
//############################################################################
bool	W25qxx_Init(void);

void	W25qxx_EraseChip(void);
void 	W25qxx_EraseSector(uint32_t SectorAddr);
void 	W25qxx_EraseBlock(uint32_t BlockAddr);

uint32_t	W25qxx_PageToSector(uint32_t	PageAddress);
uint32_t	W25qxx_PageToBlock(uint32_t	PageAddress);
uint32_t	W25qxx_SectorToBlock(uint32_t	SectorAddress);
uint32_t	W25qxx_SectorToPage(uint32_t	SectorAddress);
uint32_t	W25qxx_BlockToPage(uint32_t	BlockAddress);

bool 	W25qxx_IsEmptyPage(uint32_t Page_Address,uint32_t OffsetInByte,uint32_t NumByteToCheck_up_to_PageSize);
bool 	W25qxx_IsEmptySector(uint32_t Sector_Address,uint32_t OffsetInByte,uint32_t NumByteToCheck_up_to_SectorSize);
bool 	W25qxx_IsEmptyBlock(uint32_t Block_Address,uint32_t OffsetInByte,uint32_t NumByteToCheck_up_to_BlockSize);

void 	W25qxx_WriteByte(uint8_t pBuffer,uint32_t Bytes_Address);
void 	W25qxx_WritePage(uint8_t *pBuffer	,uint32_t Page_Address,uint32_t OffsetInByte,uint32_t NumByteToWrite_up_to_PageSize);
void 	W25qxx_WriteSector(uint8_t *pBuffer,uint32_t Sector_Address,uint32_t OffsetInByte,uint32_t NumByteToWrite_up_to_SectorSize);
void 	W25qxx_WriteBlock(uint8_t* pBuffer,uint32_t Block_Address,uint32_t OffsetInByte,uint32_t NumByteToWrite_up_to_BlockSize);

void 	W25qxx_ReadByte(uint8_t *pBuffer,uint32_t Bytes_Address);
void 	W25qxx_ReadBytes(uint8_t *pBuffer,uint32_t ReadAddr,uint32_t NumByteToRead);
void 	W25qxx_ReadPage(uint8_t *pBuffer,uint32_t Page_Address,uint32_t OffsetInByte,uint32_t NumByteToRead_up_to_PageSize);
void 	W25qxx_ReadSector(uint8_t *pBuffer,uint32_t Sector_Address,uint32_t OffsetInByte,uint32_t NumByteToRead_up_to_SectorSize);
void 	W25qxx_ReadBlock(uint8_t* pBuffer,uint32_t Block_Address,uint32_t OffsetInByte,uint32_t	NumByteToRead_up_to_BlockSize);
//############################################################################

uint32_t read_data_length();
uint32_t read_rfid_data_length();

uint16_t SFlash_read(char *data);
uint16_t SFlash_rfid_read(char *data);

void SFlash_write( uint8_t *data, uint32_t len);
void SFlash_rfid_write( uint8_t *data, uint32_t len);

void SFlash_pointer_write();
void SRfid_pointer_write();

void SFlash_pointer_read();
void SRfid_pointer_read();

uint8_t read_rfid_last_data(uint16_t log);

#ifdef __cplusplus
}
#endif

#endif

