/*
*********************************************************************************************************
*                                       IAR Development Kits
*                                              on the
*
*                                    M451
*
* Filename      : spi_fram.h
* Version       : V1.00
* Programmer(s) : Qian Xianghong
*********************************************************************************************************
*/

#ifndef  USER_SPI_FRAM_PRESENT
#define  USER_SPI_FRAM_PRESENT

#include "type.h"

// FRAM存储规划如下：
// 0~21: 	升级进度记录（含标志位、CRC等)
// 22~4117: 最近的升级数据（4K缓存，还未写入SFlash中）

// ---------- GPS ----------
// 4118~4125: GPS循环缓冲记录（含标志位、CRC等)
// 4126~16290: GPS记录（每条15字节，共810 + 1条，12165字节，按4秒一个点，可保存54分钟

// ---------- GPRS (因为时间戳为相对时间，故掉电不保留GPRS记录）----------
// 16291~16298: GPRS循环缓冲记录（含标志位、CRC等)
// 16299~32098: GPRS记录（每条158字节，最多可99 + 1条，15800字节）

// ---------- BD_GPRS (因为时间戳为相对时间，故掉电不保留GPRS记录）----------
// 32099~32106: BD_GPRS循环缓冲记录（含标志位、CRC等)
// 32107~32580: BD_GPRS记录（每条158字节，最多可存2 + 1条，474字节）
// 32581~32656: 阿里云密钥记录（长度为76字节）

// 32657~32767: 保留（共111字节）

// GPS记录条数(最多可存810+1条)
#define FRAM_GPS_DATA_COUNT		810
// GPRS记录条数（最多可存99+1条）
#define FRAM_GPRS_DATA_COUNT	99
// BD-GPRS记录条数（最多可存2+1条）
#define FRAM_BD_GPRS_DATA_COUNT	2

// 存储起始地址
#define FRAM_UPGRADE_INFO_BASE 	0
#define FRAM_UPGRADE_DATA_BASE 	22	// =0+22

// ---------- 槽车-GPS ----------
#define FRAM_GPS_INFO_BASE		4118 // =22+4096
#define FRAM_GPS_DATA_BASE		4126 // =4118+8

// ---------- GPRS(因为时间戳为相对时间，故掉电不保留GPRS记录） ----------
#define FRAM_GPRS_INFO_BASE		16291 // =4126+15*811
#define FRAM_GPRS_DATA_BASE		16299 // =16291+8

// 北斗队列循环缓冲
#define FRAM_GPRS_BD_INFO_BASE	32099 // =16299+158*100
#define FRAM_GPRS_BD_DATA_BASE	32107 // =32099+8

// 阿里云密钥存储位置
#define FRAM_ALIYUN_SECRET_BASE	32581 // =32107+158*3

// 铁电存储容量: 32K bytes
#define FRAM_SIZE	32768ul

// 初始化引脚
void FRAM_Init();

// 打开设备和允许中断
void FRAM_Open();

void FRAM_ReadID();
uint8_t FRAM_WriteEN();
uint16_t FRAM_BufferWrite(uint32_t Addr, uint8_t *buf, uint32_t nbytes);
uint16_t FRAM_BufferRead(uint32_t Addr, uint8_t *buf, uint32_t nbytes);
uint32_t FRAM_BufferVerify(uint32_t Addr, uint8_t *buf, uint32_t nbytes);
void FRAM_Sleep(uint8_t sleep);

#pragma pack(push, 1)

typedef struct
{
	uint16_t check; // 标志位，必须为0x55AA
	volatile uint16_t rdPtr;
	volatile uint16_t wtPtr;
	uint16_t crc;	// 校验位
} loopbuff_info_t;

typedef struct
{
	loopbuff_info_t info;
	uint16_t itemSize;
	uint16_t maxItemCount;
	uint32_t info_base;
	union
	{
		uint32_t data_base;
		uint8_t *data;
	};
} loopbuff_t;

#pragma pack(pop)

// 循环缓冲实现部分

void LoopBuff_Create(loopbuff_t *lpbuf, uint16_t itemSize, uint16_t maxItemCount, uint32_t info_base, uint32_t data_base);

void LoopBuff_Clear(loopbuff_t *lpbuf);
uint16_t LoopBuff_GetCount(loopbuff_t *lpbuf);
uint16_t LoopBuff_GetNextPtr(loopbuff_t *lpbuf, uint16_t ptr);
void LoopBuff_PutItem(loopbuff_t *lpbuf, uint8_t *item);
void LoopBuff_RemoveItems(loopbuff_t *lpbuf, uint16_t count);
uint32_t LoopBuff_GetDataPos(loopbuff_t *lpbuf, uint16_t ptr);
uint8_t *LoopBuff_GetDataPtr(loopbuff_t *lpbuf, uint16_t ptr);

// 从FRAM读取记录（前面2个字节为标志0x55AA，最后两个字节为crc）
uint32_t FRAM_LoadInfo(uint32_t Addr, uint8_t *buf, uint32_t nbytes);
// 保存记录到FRAM中（前面2个字节为标志0x55AA，最后两个字节为crc）
uint32_t FRAM_SaveInfo(uint32_t Addr, uint8_t *buf, uint32_t nbytes);

#endif
