#include "app_flash.h"
#include "bsp_wdt.h"
#include "exception.h"

/*************************************
 *DEFINITION
 */

#define FLASH_HEAD									0xAA5555AA

#define FLASH_TAIL_H								0xA5						//高位字节不能为0，因为结构体强制4字节对齐缘故，会导致解析错误。
#define FLASH_TAIL_L								0x55						//低字节随意，最好是0101组合

#define FLASH_ADDR_INFO_PAGENUM			1
#define FLASH_ADDR_STEP_PAGENUM 		2
#define FLASH_ADDR_BACKUP_PAGENUM 	1

#define MaxLength(a,b) 							a>b?a:b

/*********************************************************************
 * LOCAL VARIABLES
 */
 
static uint32_t info_zone;
static uint32_t step_zone;
static uint32_t backup_zone;
 
Flash_t 				mFlash;
FlashBackup_t 	mBackup;

/*********************************************************************
 * LOCAL FUCTIONS
 */

/**
 @brief crc16校验码
 @param crc - [in]		默认0
 @param buf - [in]		指向需要校验的数据
 @param len - [in]		校验数据的长度
 @return 返回crc16校验码
*/
static int CalCrc(int crc, const char *buf, int len)
{
    unsigned int byte;
    unsigned char k;
    unsigned short ACC,TOPBIT;

    unsigned short remainder = crc;
    TOPBIT = 0x8000;
    for (byte = 0; byte < len; ++byte)
    {
        ACC = buf[byte];
        remainder ^= (ACC <<8);
        for (k = 8; k > 0; --k)
        {
            if (remainder & TOPBIT)
            {
                remainder = (remainder << 1) ^0x8005;
            }
            else
            {
                remainder = (remainder << 1);
            }
        }
    }
    remainder=remainder^0x0000;
    return remainder;
}

/****************************************************接口****************************************************/
void Flash_Initialize(void)
{
	uint8_t 	ret = 0;
	uint32_t* addr_R;
	uint32_t* BackupHead;
	
	Fstorage_FlashInit();
	
	SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone));
	SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone));
	SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone));
	
	uint32_t sucess = Flash_GetBackup(&mBackup);
	SEGGER_RTT_printf(0,"Flash_GetBackup (&mBackup):%d\n",sucess);
		
	if(mBackup.ErrorStartFlag >= 5){//连续五次重启的情况下，清空所有的flash数据
		Flash_DeleteAllInformation();
		Flash_DeleteAllStep();
		mBackup.ErrorStartFlag =0;
		Flash_SaveBackup();
		SEGGER_RTT_printf(0,"mBackup.ErrorStartFlag >= 5!!!!!!!!!!!\n");
		NVIC_SystemReset();
	}
	else{
		mBackup.ErrorStartFlag++;
		Flash_SaveBackup();
	}
	
	addr_R = (uint32_t*)info_zone;
	SEGGER_RTT_printf(0,"Flash head read(%04X).\n",*addr_R);
	if((*addr_R)!=FLASH_HEAD){  SEGGER_RTT_printf(0,"Flash first init(%04X),write infomation to flash.\n",*addr_R);
		memset((uint8_t*)(&mFlash),0,sizeof(Flash_t));
		mFlash.head = FLASH_HEAD;
		mFlash.m_struct_size = sizeof(mFlash);
		
		BackupHead = (uint32_t*)backup_zone;//备份区域有数据的话，拷贝备份区域的数据到information
		if((*BackupHead) == FLASH_HEAD){
			 uint8_t i=0;
			 for(int i=0;i<6;i++){
				 mFlash.macHost[i] =	mBackup.macAddr_L[i];	     //主机地址
				 mFlash.mClient.macAddr[i] = mBackup.macAddr_R[i];//从机地址
			 }
			 
			 SEGGER_RTT_printf(0,"Back macAddr_L:");for(i=0;i<6;i++){SEGGER_RTT_printf(0,"%02X:",mBackup.macAddr_L[i]);}SEGGER_RTT_printf(0,"\r\n");
			 SEGGER_RTT_printf(0,"Back macAddr_R:");for(i=0;i<6;i++){SEGGER_RTT_printf(0,"%02X:",mBackup.macAddr_R[i]);}SEGGER_RTT_printf(0,"\r\n");
			 
			 mFlash.mClient.hardVersion = mBackup.hardVersion;
			 mFlash.mClient.sotfVersion = mBackup.sotfVersion;
			 mFlash.mClient.isConfig = mBackup.isConfig;
			 SEGGER_RTT_printf(0,"Back Data:ifconfig:%d,hardVer:%d,backup.softversion:%d\n",mBackup.isConfig,mBackup.hardVersion,mBackup.sotfVersion);
		}else{
			 memset((uint8_t*)(&mBackup),0,sizeof(FlashBackup_t));
		   Flash_SaveBackup();
		}
		
		Flash_SaveInfomation();
		SEGGER_RTT_printf(0,"Flash head second read(%04X).\n",*addr_R);
		if((*addr_R)!=FLASH_HEAD){ 
			SEGGER_RTT_printf(0,"Flash write head fail.\n");
			Except_TxError(EXCEPT_FLASH,"Flash write head fail");
			ret = 1;
			return;
		}
		SEGGER_RTT_printf(0,"System reset...\n",*addr_R);
		for(uint8_t i =0;i<6;i++){
			nrf_delay_ms(500);
			feed_watchdog();
		}
		NVIC_SystemReset();
	}
	if(ret==0){
		sucess = Flash_GetInfomation(&mFlash);
		SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash):%d \n",sucess);
	}
	if(mFlash.mStep.stepCur[0]<mFlash.mStep.step[0])
		mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
	SEGGER_RTT_printf(0,"mFlash.mStep.num=%d\n",mFlash.mStep.num);
	SEGGER_RTT_printf(0,"mFlash.mStep.stepCur[0]=%d,mFlash.mStep.stepCur[1]=%d\n",mFlash.mStep.stepCur[0],mFlash.mStep.stepCur[1]);
	SEGGER_RTT_printf(0,"err code :%s\n",mFlash.mFlashLog.logData);
	
	SEGGER_RTT_printf(0,"Flash init ok.\n");
	
	mFlash.isHost = _IS_HOST;
	
	#ifdef PIN_SEL
	nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLUP);
	nrf_delay_ms(100);
	mFlash.isHost = (uint8_t)nrf_gpio_pin_read(PIN_SEL);
	if(1 == mFlash.isHost)nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLDOWN);
	else nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_NOPULL);
	#endif
	if(mFlash.isHost){
		SEGGER_RTT_printf(0,"======= Left  shooe ======= \n");
	}else{
		SEGGER_RTT_printf(0,"======= Right shooe ======= \n");
	}
	
	
	//TestHalFlashInterface();
}
 
/**
 @brief 存储步数
 @param 无
 @return 错误代码
*/
uint32_t Flash_SaveStep(void)
{
	uint32_t 				err_code;
	uint32_t 				flash_data;
	static uint32_t Max_Hour = PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM;
	
	if(mFlash.mStep.num < Max_Hour)
	{
		uint32_t step = app_step_GetStep_L() + app_step_GetStep_R(); //获取左右鞋步数
		flash_data =  ((step<<24 & 0xff000000) | (step<<8 & 0x00ff0000) | (step>>8 & 0x0000ff00) | (step>>24 & 0x000000ff));
		
		err_code = Zone_Write(step_zone + (mFlash.mStep.num * 4), &flash_data, 4);
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		
		mFlash.mStep.num++;
		mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
		mFlash.mStep.step[1] = mFlash.mStep.stepCur[1];		
	}
	else return ZONE_ERROR_WRITE_FAIL;
	return ZONE_OP_SUCCESS;
}

/**
 @brief 获取步数区域首地址
 @param 无
 @return 错误代码
*/
uint32_t Flash_GetStepZoneStartAddr(void)
{
	return step_zone;
}

/**
 @brief 获取步数区域数据
 @param 无
 @return 错误代码
*/
uint32_t Flash_GetStep(uint32_t destination_addr, uint32_t *pData, uint32_t dataLen)
{
	return Zone_Read(destination_addr,pData,dataLen);
}

/**
 @brief 删除所有步数
 @param 无
 @return 错误代码
*/
uint32_t Flash_DeleteAllStep(void)
{
	mFlash.mStep.num = 0;
	return Zone_Erase(step_zone);
}

/**
 @brief 删除所有的信息区域
 @param 无
 @return 错误代码
*/
uint32_t Flash_DeleteAllInformation(void)
{
	return Zone_Erase(info_zone);
}

/**
 @brief 存储基本信息
 @param 无
 @return 错误代码
*/
uint32_t Flash_SaveInfomation(void)
{
	uint32_t 	err_code;
	uint32_t 	zone_bytes;
	Flash_t	 	temp_flash;
	int32_t  	offset;
	uint16_t 	crc;
	uint8_t		tail_h;
	
	memset(&temp_flash,0,sizeof(temp_flash));
	
	err_code = Zone_GetByteSize(info_zone, &zone_bytes);
	if(err_code != ZONE_OP_SUCCESS)return err_code;
	
	//从区域尾开始找起，找到最新的帧尾
	for(offset = zone_bytes - 1; offset >= 0; offset--)
	{
		err_code = Zone_Read(info_zone + offset, (uint32_t*)&tail_h, 1);
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		
		if(tail_h == FLASH_TAIL_H)break;
	}
	//重新获取crc16校验码
	mFlash.tail_crc16 = 0;
	mFlash.m_struct_size = sizeof(mFlash);
	mFlash.head = FLASH_HEAD;
	crc = CalCrc(0, (char*)&mFlash, sizeof(mFlash));//计算得到的16位CRC校验码
	mFlash.tail_crc16 = (uint32_t)((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
	//写入
	if(offset < 0){	//意味着整个区域是干净的，直接写开头。
		err_code = Zone_Write(info_zone, (uint32_t*)&mFlash, sizeof(mFlash));
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		SEGGER_RTT_printf(0,"write zone all clear,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16);
	}else{
		//这里要偏移才能对齐成员
		offset++;		
		//获取最新的帧尾
		err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16), (uint32_t*)&temp_flash.tail_crc16, sizeof(temp_flash.tail_crc16));
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		//获取最新的帧长度
		err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16) - sizeof(temp_flash.m_struct_size) , (uint32_t*)&temp_flash.m_struct_size, sizeof(temp_flash.m_struct_size));
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		//因为结构体强制4字节对齐缘故，所以tail_crc16未必是真实存储的帧尾，后面可能带一些数据为0的填充字节。所以要做校准。
//		uint32_t pad_len = temp_flash.m_struct_size - ((uint32_t)&temp_flash.tail_crc16 + sizeof(temp_flash.tail_crc16) - (uint32_t)&temp_flash.head);
		
		uint32_t pad_len = 0;
//		SEGGER_RTT_printf(0,"save info_zone:0x%x offset:%d pad_len:%d temp_flash.m_struct_size:%d\n",info_zone,offset,pad_len,temp_flash.m_struct_size);
		if(offset + pad_len < temp_flash.m_struct_size)pad_len = temp_flash.m_struct_size - offset;
		err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head));
		if(err_code != ZONE_OP_SUCCESS)return err_code;
//		SEGGER_RTT_printf(0,"save >>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size);
		while(temp_flash.head != FLASH_HEAD){
			pad_len++;
			err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head));
			if(err_code != ZONE_OP_SUCCESS)return err_code;
//			SEGGER_RTT_printf(0,"save >>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size);
//			nrf_delay_ms(5);
		}

		err_code = Zone_Write(info_zone + offset + pad_len, (uint32_t*)&mFlash, sizeof(mFlash));
//		if(err_code == ZONE_OP_SUCCESS)SEGGER_RTT_printf(0,"write zone forward ,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16);
		if(err_code != ZONE_OP_SUCCESS){	//如果写失败了
			//擦除该区域
			err_code = Zone_Erase(info_zone);
			if(err_code != ZONE_OP_SUCCESS)return err_code;
			//写在开头
			err_code = Zone_Write(info_zone, (uint32_t*)&mFlash, sizeof(mFlash));
			if(err_code != ZONE_OP_SUCCESS)return err_code;
//			SEGGER_RTT_printf(0,"write zone all erase ,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16);
		}
	}
	
	return ZONE_OP_SUCCESS;
}



/**
 @brief 获取基本信息
 @param 无
 @return 错误代码
*/
uint32_t Flash_GetInfomation(Flash_t *pflash)
{
	uint32_t 	err_code;
	uint32_t 	zone_bytes;
	Flash_t	 	temp_flash;
	int32_t  	offset;
	uint16_t 	crc;
	uint8_t		tail_h;
	
	memset(&temp_flash,0,sizeof(temp_flash));
	
	SEGGER_RTT_printf(0,"Zone_GetByteSize(info_zone, &zone_bytes):%d\n",zone_bytes);
	
	err_code = Zone_GetByteSize(info_zone, &zone_bytes);
	if(err_code != ZONE_OP_SUCCESS)return err_code;
	
	SEGGER_RTT_printf(0,"Zone_GetByteSize(info_zone, &zone_bytes):%d\n",zone_bytes);
	
	//从区域尾开始找起，找到最新的帧尾
	for(offset = zone_bytes - 1; offset >= 0; offset--)
	{
		err_code = Zone_Read(info_zone + offset, (uint32_t*)&tail_h, 1);
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		
		if(tail_h == FLASH_TAIL_H)break;
	}
	
	//意味着整个区域是干净的
	if(offset < 0){
		memset(pflash,0,sizeof(Flash_t));
		pflash->head = FLASH_HEAD;
		pflash->m_struct_size = sizeof(Flash_t);				//这里是包括填充字节的
		crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码，这里注意，有可能会将填充的字节也拿来做运算
		pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;		//这里最后才加，是因为不知道填充字节的个数
		SEGGER_RTT_printf(0,"read zone all clear,pflash->tail_crc16:0x%x\r\n",pflash->tail_crc16);
		return ZONE_OP_SUCCESS;
	}
	//这里要偏移才能对齐成员
	offset++;		
	//获取最新的帧尾
	err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16), (uint32_t*)&temp_flash.tail_crc16, sizeof(temp_flash.tail_crc16));
	if(err_code != ZONE_OP_SUCCESS)return err_code;
	//获取最新的帧长度
	err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16) - sizeof(temp_flash.m_struct_size) , (uint32_t*)&temp_flash.m_struct_size, sizeof(temp_flash.m_struct_size));
	if(err_code != ZONE_OP_SUCCESS)return err_code;
	//因为结构体强制4字节对齐缘故，所以tail_crc16未必是真实存储的帧尾，后面可能带一些数据为0的填充字节。所以要做校准。

	
//  uint32_t pad_len = temp_flash.m_struct_size - ((uint32_t)&temp_flash.tail_crc16 + sizeof(temp_flash.tail_crc16) - (uint32_t)&temp_flash.head);
	uint32_t pad_len = 0;
//	SEGGER_RTT_printf(0,"get info_zone:0x%x offset:%d pad_len:%d temp_flash.m_struct_size:%d\n",info_zone,offset,pad_len,temp_flash.m_struct_size);
	if(offset + pad_len < temp_flash.m_struct_size)pad_len = temp_flash.m_struct_size - offset;
	err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head));
	if(err_code != ZONE_OP_SUCCESS)return err_code;
//	SEGGER_RTT_printf(0,">>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size);
	while(temp_flash.head != FLASH_HEAD){
		pad_len++;
		err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head));
		if(err_code != ZONE_OP_SUCCESS)return err_code;
//		SEGGER_RTT_printf(0,">>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size);
//		nrf_delay_ms(5);
	}

		
//	SEGGER_RTT_printf(0,"read pad_len 0x%x info_zone + offset + pad_len - temp_flash.m_struct_size:0x%x\r\n",pad_len,info_zone + offset + pad_len - temp_flash.m_struct_size);
	//获取最新的帧
	if(temp_flash.m_struct_size <= (sizeof(temp_flash.tail_crc16)+sizeof(temp_flash.m_struct_size)+pad_len))return ZONE_ERROR_READ_FAIL;
	err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size , (uint32_t*)&temp_flash, temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len);
	if(err_code != ZONE_OP_SUCCESS)return err_code;
	//判断一下是否正确读取到最新的帧
	if(temp_flash.m_struct_size <= (sizeof(temp_flash.tail_crc16)+sizeof(temp_flash.m_struct_size)+pad_len))//证明结构体被修改了
	{
		//校验没通过
		SEGGER_RTT_printf(0,"struct change,read crc fail :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF);
		memset(pflash,0,sizeof(Flash_t));
		pflash->head = FLASH_HEAD;
		pflash->m_struct_size = sizeof(Flash_t);
		//将备份区域的数据拷贝
		FlashBackup_t	 	temp_backup;
		Flash_GetBackup(&temp_backup);
		for(int i=0;i<6;i++){
			pflash->mClient.macAddr[i] = temp_backup.macAddr_R[i];
			pflash->macHost[i] = temp_backup.macAddr_L[i];
	  }
		pflash->mClient.isConfig = temp_backup.isConfig;
		pflash->mClient.hardVersion = temp_backup.hardVersion;
		pflash->mClient.sotfVersion = temp_backup.sotfVersion;
		crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码
		pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
		err_code = Zone_Erase(info_zone);
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		err_code = Flash_SaveInfomation();
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		return ZONE_OP_SUCCESS;
	}
	
	
	//校验数据
	Flash_t	crc_buf;//单纯做一个缓冲区
	memset(&crc_buf,0,sizeof(crc_buf));
	char *buf = (char*)&crc_buf;
	//获取成员head ~ m_struct_size
//	SEGGER_RTT_printf(0,"crc_buf:%d temp_flash.m_struct_size:%d,temp_flash.tail_crc16:%d\n",sizeof(crc_buf),temp_flash.m_struct_size,sizeof(temp_flash.tail_crc16));
//	SEGGER_RTT_printf(0,"sizeof(temp_flash.m_struct_size):%d,pad_len:%d\n",sizeof(temp_flash.m_struct_size),pad_len);
	memcpy(buf,&temp_flash,temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len);
//	SEGGER_RTT_printf(0,"read pad_len:%d,info_zone:0x%x,offset:%d,pad_len:%d,temp_flash.m_struct_size:%d\r\n",pad_len,info_zone,offset,pad_len,temp_flash.m_struct_size);
//	SEGGER_RTT_printf(0,"2:buf:0x%x sizeof(temp_flash.m_struct_size):%d\n",buf + temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len,sizeof(temp_flash.m_struct_size));
	memcpy(buf + temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len,(uint32_t*)&temp_flash.m_struct_size,sizeof(temp_flash.m_struct_size));
	//计算得到的16位CRC校验码
	crc = CalCrc(0, buf, temp_flash.m_struct_size);
	
	
	if(crc == (temp_flash.tail_crc16 & 0xFFFF)){
//		SEGGER_RTT_printf(0,"read crc success :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF);
		temp_flash.head = FLASH_HEAD;
		temp_flash.m_struct_size = sizeof(temp_flash);
		temp_flash.tail_crc16 = 0;
		crc = CalCrc(0, (char*)&temp_flash, sizeof(temp_flash));//计算得到的16位CRC校验码
		temp_flash.tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
		*pflash = temp_flash;//校验通过
	}
	else{
		//校验没通过
//		SEGGER_RTT_printf(0,"read crc fail :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF);
		memset(pflash,0,sizeof(Flash_t));
		pflash->head = FLASH_HEAD;
		pflash->m_struct_size = sizeof(Flash_t);
		//将备份区域的数据拷贝
		FlashBackup_t	 	temp_backup;
		Flash_GetBackup(&temp_backup);
		for(int i=0;i<6;i++){
			pflash->mClient.macAddr[i] = temp_backup.macAddr_R[i];
			pflash->macHost[i] = temp_backup.macAddr_L[i];
	  }
		pflash->mClient.isConfig = temp_backup.isConfig;
		pflash->mClient.hardVersion = temp_backup.hardVersion;
		pflash->mClient.sotfVersion = temp_backup.sotfVersion;
		crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码
		pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
		err_code = Zone_Erase(info_zone);
		if(err_code != ZONE_OP_SUCCESS)return err_code;
		err_code = Flash_SaveInfomation();
		if(err_code != ZONE_OP_SUCCESS)return err_code;
	}
	
	
	return ZONE_OP_SUCCESS;
}

/**
 @brief 存储备份信息
 @param 无
 @return 错误代码
*/
uint32_t Flash_SaveBackup(void)
{
	uint32_t 				err_code;
	mBackup.head = FLASH_HEAD;
	err_code =  Zone_Erase(backup_zone);
	if(err_code != ZONE_OP_SUCCESS)return err_code;
	err_code = Zone_Write(backup_zone, (uint32_t*)&mBackup, sizeof(mBackup));
	return err_code;
}

/**
 @brief 获取备份信息
 @param 无
 @return 错误代码
*/
uint32_t Flash_GetBackup(FlashBackup_t *pbackup)
{
	uint32_t 				err_code;
	err_code = Zone_Read(backup_zone, (uint32_t*)pbackup, sizeof(FlashBackup_t));
	return err_code;
}

/**
 @brief 保存日志信息
 @param[in] id    Fault identifier. See @ref NRF_FAULT_IDS.
 @param[in] pc    The program counter of the instruction that triggered the fault, or 0 if
                  unavailable.
 @param[in] info  Optional additional information regarding the fault. The value of the @p id
                  parameter dictates how to interpret this parameter. Refer to the documentation
                  for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
                  details about interpreting @p info.
 @return 错误代码
*/
uint32_t Flash_SaveLog(uint32_t id, uint32_t pc, uint32_t info)
{
	memset((uint8_t*)(&mFlash.mFlashLog),0,sizeof(FlashLog));
	mFlash.mFlashLog.Errorflag =1;
	switch (id)
 {
	#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
					case NRF_FAULT_ID_SD_ASSERT:
							memcpy(mFlash.mFlashLog.logData,"SD: ASSERTION FAILED\r\n",MaxLength(sizeof("SD: ASSERTION FAILED\r\n"),sizeof(mFlash.mFlashLog.logData)));
							break;
					case NRF_FAULT_ID_APP_MEMACC:
							memcpy(mFlash.mFlashLog.logData,"SD: INVALID MEMORY ACCESS\r\n",MaxLength(sizeof("SD: INVALID MEMORY ACCESS\r\n"),sizeof(mFlash.mFlashLog.logData)));
							break;
	#endif
					case NRF_FAULT_ID_SDK_ASSERT:
					{
							assert_info_t * p_info = (assert_info_t *)info;
							sprintf((char *)mFlash.mFlashLog.logData,"ASSERTION FAILED %s:%u\r\n",
														p_info->p_file_name,
														p_info->line_num);
							break;
					}
					case NRF_FAULT_ID_SDK_ERROR:
					{
							error_info_t * p_info = (error_info_t *)info;
						  
						  sprintf((char *)mFlash.mFlashLog.logData,"error:%u,%s:%u\r\n",
														p_info->err_code,
														p_info->p_file_name,
														p_info->line_num);
							SEGGER_RTT_printf(0,">>>>>err code :%d,%s",p_info->err_code,mFlash.mFlashLog.logData);

							break;
					}
					default:
							sprintf((char *)mFlash.mFlashLog.logData,"UNKNOWN FAULT 0x%08X\n", pc);
							break;
	}
 
	return Flash_SaveInfomation();
}

/**
 @brief 返回主机标志位
 @param 无
 @return 主机标志位
*/
uint8_t Get_isHost(void)
{
	return mFlash.isHost;
}




/**
 @brief 测试halflash接口
 @param 无
 @return 无
*/
void TestHalFlashInterface(void)
{
	
	Fstorage_FlashInit();
	
	SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone));
	SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone));
	SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone));

	SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash):%d \n",Flash_GetInfomation(&mFlash));
	SEGGER_RTT_printf(0,"Flash_GetInfomation(&mBackup):%d \n",Flash_GetBackup(&mBackup));
	
	
	uint32_t i; 
//	Flash_t m_testflash;
//	FlashBackup_t m_testbackup;
	
//	//测试基本信息和备份信息的写入和读取
//	for(i=0;i<10000;i++)
//	{
//		mFlash.mStep.num = i;
//		SEGGER_RTT_printf(0,"Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
//		
//		mBackup.hardVersion = i;
//		SEGGER_RTT_printf(0,"Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
//	}
//	
//	SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
//	SEGGER_RTT_printf(0,"m_testflash:%d \n",m_testflash.mStep.num);
//	
//	SEGGER_RTT_printf(0,"Flash_GetBackup[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
//	SEGGER_RTT_printf(0,"m_testbackup:%d \n",m_testbackup.hardVersion);
	
	//测试步数信息的写入和读取
	for(i=0;i<(PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM+100);i++)
	{
		mFlash.mStep.stepCur[0] = 0;
		mFlash.mStep.stepCur[1] = i;
		SEGGER_RTT_printf(0,"Flash_SaveStep[%d]:%d \n\n",i,Flash_SaveStep());
	}
	
	uint8_t checkflash[4] = {0};
	for(i=0;i<(PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM);i+=4)
	{
//		Zone_Read(step_zone + i, (uint32_t*)&step, 4);
//		SEGGER_RTT_printf(0,"step[%d]:0x%x ",i,step);
		Zone_Read(step_zone + i,(uint32_t*)&checkflash[0], 4);
		SEGGER_RTT_printf(0,"checkflash[%d]:%02x,%02x,%02x,%02x ",i,checkflash[0],checkflash[1],checkflash[2],checkflash[3]);
		if(i%5 == 0)SEGGER_RTT_printf(0,"\n");
		nrf_delay_ms(5);
	}

	
	
	
	
	
	
	

////uint32_t Flash_SaveStep(void);
//////存储基本信息
////uint32_t Flash_SaveInfomation(void);
//////存储备份信息
////uint32_t Flash_SaveBackup(void);
//////获取基本信息
////uint32_t Flash_GetInfomation(Flash_t *pflash);
//////获取备份信息
////uint32_t Flash_GetBackup(FlashBackup_t *pbackup);
//	
//	uint32_t i;
//	Flash_t m_testflash;
//	FlashBackup_t m_testbackup;

//	Fstorage_FlashInit();
//	
//	#define INFO_PAGE_SIZE			1
//	#define BACKUP_PAGE_SIZE		1
//	#define STEP_PAGE_SIZE			2
//	
//	static uint32_t info_index;
//	static uint32_t backup_index;
//	static uint32_t step_index;
//	
//	Zone_Init(INFO_PAGE_SIZE, &info_index);
//	Zone_Init(BACKUP_PAGE_SIZE, &backup_index);
//	Zone_Init(STEP_PAGE_SIZE, &step_index);
//	
//	SEGGER_RTT_printf(0,"info_index=%d backup_index=%d step_index=%d\n",info_index,backup_index,step_index);
//	
//	
//	
//	while(1);
//	
//	//测试基本信息和备份信息的写入和读取
//	for(i=0;i<10000;i++)
//	{
//		mFlash.mStep.num = i;
//		SEGGER_RTT_printf(0,"Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
//		
//		mBackup.hardVersion = i;
//		SEGGER_RTT_printf(0,"Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
//	}
//	
//	SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
//	SEGGER_RTT_printf(0,"m_testflash:%d \n",m_testflash.mStep.num);
//	
//	SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
//	SEGGER_RTT_printf(0,"m_testbackup:%d \n",m_testbackup.hardVersion);


//	//测试步数信息的写入和读取
//	for(i=0;i<1500;i++)
//	{
//		mFlash.mStep.num = i;
//		mFlash.mStep.stepCur[0] = i;
//		mFlash.mStep.stepCur[1] = i+i;
//		
//		SEGGER_RTT_printf(0,"Flash_SaveStep[%d]:%d \n\n",i,Flash_SaveStep());
//	}
//	uint32_t checkflash[750];
//	Read_N_Byte_flash(FLASH_ADDR_STEP , (uint32_t*)checkflash, sizeof(checkflash));
//	
//	for(i=0;i<750;i++)
//	{
//		SEGGER_RTT_printf(0,"checkflash[%d]:0x%x ",i,checkflash[i]);
//		if(i%5 == 0)SEGGER_RTT_printf(0,"\n");
//		nrf_delay_ms(5);
//	}

	
	
	SEGGER_RTT_printf(0,"TestHalFlashInterface done !!!!!!!\n");
}


