/*C*****************************************************************************
* NAME:         fRamDrive.c
*-------------------------------------------------------------------------------
*******************************************************************************/
/*_____ I N C L U D E S ______________________________________________________*/
	
//#define FRAM_INIT	  
	
	
#include "config.h"	 	//全局声明

volatile  s_uniGlobal_Typedef s_uniGlobal;


//参数初始化====================================================================
//密码

const u8 initFRam_Flag = 0x38;
const PrintInfo_Type InitPrintInfo={
                              "        Ho So Giao Dich         ",//交易记录
	                            "TEN CUA HANG:                   ",//地址
	                            "DIA CHI:                        ",//税号
															"MA SO THUE:                     ",//
															"                                ",
	                            "                                ",
	                            "SO VOL:                         ",//抢号
															"SO TIEN:                        ",//金额
															"SO LIT:                         ",//加油量
	                            "DONGIA:                         ",//单价
															"                                ",
															"NGAY:                           ",
															"                                ",
															"                                ",
	                            "                                ",
															"                                ",
															"                                ",
															"                                ",
															"                                ",
															"CAM ON & HEN GAP LAI QUY KHACH !",
                               }; 
const MD_Port_Data_Type  InitMD_Port_Data = {
  //BaudRate  StopBits  Parity_Even  POSType  GunNumber  MBCountTime   Display_Type
  { 9600,     1,        0,           0,       0,         10,           0             ,MD_RS485,{0,0,0,0,0,0,0,0,0,0}},
	{//Num  Addr        State            Standby[35]
		{0,   0,            0,             },
    {0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,             },
		{0,   0,            0,            },
		{0,   0,            0,            },
		{0,   0,            0,            },
		{0,   0,            0,            },
		{0,   0,            0,            },
		{0,   0,            0,            },
		{0,   0,            0,            },
	 }
};
/*typedef struct
{
  char CMD_SOCKA[50];
	char IMEI[20];
	char APN[40];
	char WiFIName[40];
	char WiFIPassWord[20];
}WirelessData_Type;*/

//Tast URL http://test.joyfueling.com:8012/
// http://3.92.208.210:7011/
const POSData_Type          InitPOSData={
//
//{"AT+SOCKA=TCP,3.92.208.210,7011\r\n"},POS_Connect_Typ_Station};
{"joyfuel.joyfueling.com,7011","","","KFB-2.4G","KFB123456"},POS_Connect_Typ_Station};
const u8                    InitMD_Port_Num_Top = 0;
const ROM_UpData_Type       InitROM_UpData = {{0x06},900};//主程序最大450K
const u32                   InitPREXDATA_WaitUpNummber = 0;
const u32                   InitPREXDATA_TTC = 0;
const PREXDATA_Type initPrintLastRecord= {0,0,0,0,0,0,0,0,0};
const POSNetSetState_TypeDef  InitPOSNetSetState;
const MD_Multiplex_Port_Data_Type InitMD_Multiplex_Port_Data;//端口5，多路复用口PREXDATA_NowFrameLen
const WhiteList_Type              InitWhiteList;
const PREXDATA_Upload_Type        InitPREXDATA_Upload;
//==============================================================================
const framDataIndex FDITab[] = 
{	///FRAM数据1区(数据操作相对不频烦)	 
///	pInitData;			                 upData					                     pData				                        firstAdr;	                    len;			                  Group                         Tpye;	 //(注意,校验增加在数据包尾)	
  {(u8*)&initFRam_Flag,             (u8*)(&buf_FRam_Flag),              (u8*)(&TXHData.FRam_Flag),             FRam_Flag_FADR,              FRam_Flag_LEN,              FRam_Flag_Group,               CF_FRam_Flag},
	{(u8*)&InitROM_UpData,            (u8*)(&buf_ROM_UpData),             (u8*)(&TXHData.ROM_UpData),            ROM_UpData_FADR,             ROM_UpData_LEN,             ROM_UpData_Group,              CF_ROM_UpData},
  {(u8*)&InitMD_Port_Data,          (u8*)(&buf_MD_Port_Data),           (u8*)(&TXHData.MD_Port_Data),          MD_Port_Data_FADR,           MD_Port_Data_LEN,           MD_Port_Data_Group,            CF_MD_Port_Data},
  {(u8*)&InitPOSData,               (u8*)(&buf_POSData),                (u8*)(&TXHData.POSData),               POSData_FADR,                POSData_LEN,                POSData_Group,                 CF_POSData},
  {(u8*)&InitMD_Port_Num_Top,       (u8*)(&buf_MD_Port_Num_Top),        (u8*)(&TXHData.MD_Port_Num_Top),       MD_Port_Num_Top_FADR,        MD_Port_Num_Top_LEN,        MD_Port_Num_Top_Group,         CF_MD_Port_Num_Top},
  {(u8*)&InitPREXDATA_WaitUpNummber,(u8*)(&buf_PREXDATA_WaitUpNummber), (u8*)(&TXHData.PREXDATA_WaitUpNummber),PREXDATA_WaitUpNummber_FADR, PREXDATA_WaitUpNummber_LEN, PREXDATA_WaitUpNummber_Group,  CF_PREXDATA_WaitUpNummber},
	{(u8*)&InitPREXDATA_TTC,          (u8*)(&buf_PREXDATA_TTC),           (u8*)(&TXHData.PREXDATA_TTC),          PREXDATA_TTC_FADR,           PREXDATA_TTC_LEN,           PREXDATA_TTC_Group,            CF_PREXDATA_TTC},
  {(u8*)&InitPrintInfo,             (u8*)(&buf_PrintInfo),              (u8*)(&TXHData.PrintInfo),             PrintInfo_FADR,              PrintInfo_LEN,              PrintInfo_Group,               CF_PrintInfo},
  {(u8*)&initPrintLastRecord,       (u8*)(&buf_PrintLastRecord),        (u8*)(&TXHData.PrintLastRecord),       PrintLastRecord_FADR,        PrintLastRecord_LEN,        PrintLastRecord_Group,         CF_PrintLastRecord},
  {(u8*)&InitPOSNetSetState,        (u8*)(&buf_POSNetSetState),         (u8*)(&TXHData.POSNetSetState),        POSNetSetState_FADR,         POSNetSetState_LEN,         POSNetSetState_Group,          CF_POSNetSetState},
  {(u8*)&InitMD_Multiplex_Port_Data,(u8*)(&buf_MD_Multiplex_Port_Data), (u8*)(&TXHData.MD_Multiplex_Port_Data),MD_Multiplex_Port_Data_FADR, MD_Multiplex_Port_Data_LEN, MD_Multiplex_Port_Data_Group,  CF_MD_Multiplex_Port_Data},
  {(u8*)&InitWhiteList,             (u8*)(&buf_WhiteList),              (u8*)(&TXHData.WhiteList),             WhiteList_FADR,              WhiteList_LEN,              WhiteList_Group,               CF_WhiteList},
  {(u8*)&InitPREXDATA_Upload,       (u8*)(&buf_PREXDATA_Upload),        (u8*)(&TXHData.PREXDATA_Upload),       PREXDATA_Upload_FADR,        PREXDATA_Upload_LEN,        PREXDATA_Upload_Group,         CF_PREXDATA_Upload},
}; 
////==============================================================================

//F*****************************************************************************
//* NAME:    FRamDataCheck
//* PURPOSE: 校验函数
//* PARAMS: pData需要检验的数组地址，len数据长度
//* return:	 无
//******************************************************************************
u8 FRamDataCheck(volatile u8* pData, u16 len)
{
	u8 result;
	result = *pData;
	while(len--)
	{
		result += *pData++;
		};	

	return	result;
}
/****************************************************
函数名：FM_IO_Configuration
功能  ：FM存储部分用到的IO初始化
参数  ：无
返回值：无
****************************************************/
void FM_IO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ,ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
	
  /*!< Configure SPI1 pins: SCK   MOSI*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*!< Configure SPI1: MISO */
	 //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP; //modi
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
	
}

/****************************************************
函数名：FM_SPI_Configuration
功能  ：FM存储部分用到的SPI初始化
参数  ：无
返回值：无
****************************************************/
void FM_SPI_Configuration(void)
{
	/* SPI1 configuration */ 
	SPI_InitTypeDef  SPI_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
	SPI_I2S_DeInit(SPI1);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//???
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//8?????
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//?????SCK?1
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//??????2???????
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS????
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//???
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//????
  SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC???
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//????
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_Cmd(SPI1, ENABLE);
	
}

/****************************************************
函数名：FM_SPI2_SendByte
功能  ：FM存储部分用到的SPI发送函数
参数  ：dt 要发送的数据
返回值：无
****************************************************/
u8 FM_SPI1_SendByte(u8 dt)
{
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI1, dt);
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    return SPI_I2S_ReceiveData(SPI1);
}

/****************************************************
函数名：FM_ReadData
功能  ：读取指定地址的数据
参数  ：*pBuff：读取缓存
        addr  ：读取的地址
        Len   ：数据长度
返回值：无
****************************************************/
void FM_ReadData(u8 *pBuff,u32 addr,u16 Len)
{
	u16 i = 0;
	CLI();
	FM_CS_EN;
	FM_SPI1_SendByte(0x03);
	FM_SPI1_SendByte((u8)(addr>>16));
  FM_SPI1_SendByte((u8)(addr>>8));
  FM_SPI1_SendByte((u8)addr);
	for(i = 0;i < Len;i ++)
	{
		*pBuff = FM_SPI1_SendByte(0x00);
		pBuff ++;
		}
	FM_CS_DIS;
	SEI();
}

/****************************************************
函数名：FM_WriteData
功能  ：写取指定地址的数据
参数  ：*pBuff：数据缓存
        addr  ：写入的地址
        Len   ：数据长度
返回值：无
****************************************************/
void FM_WriteData(u8 *pBuff,u32 addr,u16 Len)
{
	u16 i = 0;
	CLI();
	FM_CS_EN;
	FM_SPI1_SendByte(0x06);
	FM_CS_DIS;
	FM_CS_EN;
	FM_SPI1_SendByte(0x02);
	FM_SPI1_SendByte((u8)(addr>>16));
  FM_SPI1_SendByte((u8)(addr>>8));
  FM_SPI1_SendByte((u8)addr);
	for(i = 0;i < Len;i ++)
	{
		FM_SPI1_SendByte(*pBuff);
		pBuff ++;
		}
	FM_CS_DIS;
	SEI();
}
/****************************************************
函数名：FM_Init
功能  ：FM存储部分初始化
参数  ：无
返回值：无
****************************************************/
u16 iiii = 0;//搞不清楚，必须是全局变量才行(可能存在隐患，标注一下)
void FM_Init(void)
{
	u16 i = 0,j = 0;
	u8* pBuff;
	u8 Temp_Buff[1300];
	u8 Temp = 0;
	u32 Fristflag = 0,delay = 0;
  FM_IO_Configuration();  //FM相关IO初始化
	FM_SPI_Configuration(); //FM相关SPI初始化
	//for(delay = 0;delay<0xfffff;delay++);//无意义延时，等待铁电稳定
	delay_ms(10);
	pBuff = (u8*)&Fristflag;
	{
 		FM_CS_EN;
    FM_SPI1_SendByte(0x06);  //写使能
	  FM_CS_DIS;
	  FM_CS_EN;
    FM_SPI1_SendByte(0x01);  //清除保护位
    FM_SPI1_SendByte(0x00);
		FM_CS_DIS;
    }
	if((FDITab[FramItemEnd - 1].firstAdr + FDITab[FramItemEnd - 1].len * FDITab[FramItemEnd - 1].Group) > 0x20000)
	{
	  __breakpoint(0);  // halt program execution here  
		while(1);
	  }
#ifdef		FRAM_INIT   //初始化
		for(iiii = 0;iiii< FramItemEnd;iiii ++)  //开机写入默认存储内容
		{
			for(i = 0;i < FDITab[iiii].Group;i ++)
			{
				for(j = 0;j < FDITab[iiii].len-checkLen_1;j ++)
					Temp_Buff[j]=*(FDITab[iiii].upData+j) = *(FDITab[iiii].pInitData+j);
				
				Temp = FRamDataCheck(Temp_Buff,FDITab[iiii].len - checkLen_1);
				FM_WriteData(uniGlobal.Global,FDITab[iiii].firstAdr+FDITab[iiii].len*i,                            FDITab[iiii].len-checkLen_1);
				FM_WriteData(&Temp,           FDITab[iiii].firstAdr+FDITab[iiii].len+FDITab[iiii].len*i-checkLen_1,checkLen_1);
			 }
		 }
#endif
	if(SWF8 == SWF_ON)
	{
	  FM_Data_Init();
	  }
		 
	for(iiii = 0;iiii< FramItemEnd;iiii ++)  //开机获取存储内容
  {
		for(i = 0;i < FDITab[iiii].Group;i ++)
		{
			if(FMItemRead(iiii,i) == 0)
			{
	  	  
			 }
	    }
	  }
	
	TXHData.SystemErr = TXHData.PREXDATA_WaitUpNummber;
}
void PCBEncryption(void)
{
	STM32CPU.v.id[0] = *(u32*)0x1fff7a10;
	STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4);
	STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8);
  TXHData.Encryption[0] = CRC_Check(&STM32CPU.v.byte[0],6);
	TXHData.Encryption[1] = CRC_Check(&STM32CPU.v.byte[1],6);
	TXHData.Encryption[2] = CRC_Check(&STM32CPU.v.byte[2],8);
	TXHData.Encryption[3] = CRC_Check(&STM32CPU.v.byte[3],8);
	FM_WriteData((u8*)TXHData.Encryption,Encryption_FADR,sizeof(TXHData.Encryption));
}
void PCBEncryption_Check(void)
{
	STM32CPU.v.id[0] = *(u32*)0x1fff7a10;
	STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4);
	STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8);
	FM_ReadData((u8*)TXHData.Encryption,Encryption_FADR,sizeof(TXHData.Encryption));
  if(TXHData.Encryption[0] != CRC_Check(&STM32CPU.v.byte[0],6)) TXHData.ErrState.Flag.e_errPCBCheck = 1;
	if(TXHData.Encryption[1] != CRC_Check(&STM32CPU.v.byte[1],6)) TXHData.ErrState.Flag.e_errPCBCheck = 1;
	if(TXHData.Encryption[2] != CRC_Check(&STM32CPU.v.byte[2],8)) TXHData.ErrState.Flag.e_errPCBCheck = 1;
	if(TXHData.Encryption[3] != CRC_Check(&STM32CPU.v.byte[3],8)) TXHData.ErrState.Flag.e_errPCBCheck = 1;
}
void FM_Data_Init(void)
{
	u16 i = 0,j = 0;
	u8 Temp_Buff[1300];
	u8 Temp = 0;
	u8 BackTemp = 0;
	FMItemRead(CF_ROM_UpData,0);
	BackTemp = TXHData.ROM_UpData.ROM_UpData_State.State;//IAP初始化的时候用过了，不能重复初始化
	for(iiii = 0;iiii< FramItemEnd;iiii ++)  //开机写入默认存储内容
	{
		for(i = 0;i < FDITab[iiii].Group;i ++)
		{
			for(j = 0;j < FDITab[iiii].len-checkLen_1;j ++)
				Temp_Buff[j]=*(FDITab[iiii].upData+j) = *(FDITab[iiii].pInitData+j);
			
			Temp = FRamDataCheck(Temp_Buff,FDITab[iiii].len - checkLen_1);
			FM_WriteData(uniGlobal.Global,FDITab[iiii].firstAdr+FDITab[iiii].len*i,                            FDITab[iiii].len-checkLen_1);
			FM_WriteData(&Temp,           FDITab[iiii].firstAdr+FDITab[iiii].len+FDITab[iiii].len*i-checkLen_1,checkLen_1);
		 }
	 }
	TXHData.ROM_UpData.ROM_UpData_State.State = BackTemp;
	FMItemWrite(CF_ROM_UpData,0);
}
u8	FMItemWrite(FramItem Type, u16 Group)
{
	u16 i = 0,j = 0,k = 0;
	u8 Temp_Buff[1300];
	u8 Temp = 0;
	if(Group >= FDITab[Type].Group)
	  return 0;
	if(TXHData.PowerDown.State == 0 && FMItemRead(CF_FRam_Flag,0) == 1)
	{
		for(i = 0;i < FDITab[Type].len;i ++)
		{
			*(FDITab[Type].upData + i) = *(FDITab[Type].pData + i + (FDITab[Type].len-1)*Group);
			Temp_Buff[i] = *(FDITab[Type].upData + i);
		 }
		for(j = 0;j < 6;j ++)
		{
			FM_WriteData(uniGlobal.Global,FDITab[Type].firstAdr+FDITab[Type].len*Group,FDITab[Type].len-1);
			Temp = FRamDataCheck(Temp_Buff,FDITab[Type].len - checkLen_1);
			FM_WriteData(&Temp,FDITab[Type].firstAdr+FDITab[Type].len+FDITab[Type].len*Group-1,checkLen_1);
			
			if(FMItemRead(Type,Group) == 1)
			{
				  return 1;
			  }
			delay_ms(100);
		  }
	  }
//	pGun.ErrState[0].Flag.e_errFramParameter = 1;  //存储器错误公共错误，只判断一个
//	pGun.ErrState[1].Flag.e_errFramParameter = 1;  //存储器错误公共错误，只判断一个
	return 0;
}

u8	FMItemRead(FramItem Type, u16 Group)
{
	volatile  u16 ii = 0,j = 0;
	u8 Temp_Buff[1300];
	u8 Temp = 0;
	
	if(Group >= FDITab[Type].Group)
	  return 0;
	for(j = 0;j < 6;j ++)
	{
		/****************************/
		FM_ReadData(uniGlobal.Global,FDITab[CF_FRam_Flag].firstAdr,1);
		*(Temp_Buff) = *(FDITab[CF_FRam_Flag].upData);

		if(*(Temp_Buff) == 0x38)
		{	
			FM_ReadData(uniGlobal.Global,FDITab[Type].firstAdr+FDITab[Type].len*Group,FDITab[Type].len);
			for(ii = 0;ii < FDITab[Type].len;ii ++)
				*(Temp_Buff+ii) = *(FDITab[Type].upData+ii);
			Temp = FRamDataCheck(Temp_Buff,FDITab[Type].len - checkLen_1);
			if(Temp == Temp_Buff[FDITab[Type].len - checkLen_1])
			{
				for(ii = 0;ii < FDITab[Type].len - checkLen_1;ii ++)
				{
					*(FDITab[Type].pData+ii+(FDITab[Type].len-1)*Group) = *(FDITab[Type].upData+ii);
				  }
				return 1;
			  }
      }
		delay_ms(100);
	}
//	pGun.ErrState[0].Flag.e_errFramParameter = 1;  //存储器错误公共错误，只判断一个
//	pGun.ErrState[1].Flag.e_errFramParameter = 1;  //存储器错误公共错误，只判断一个

	return 0;
}

