#include "includes.h"

E_PARA_INFO g_eeprom;

E_MCU_DEV_INFO g_mcu_dev;

U8_T EEPROM_CheckSum(U8_T *data,U16_T len)
{
	U8_T data_sum = 0;
	
	for(U16_T i = 0;i<len;i++)
	{
		data_sum += data[i];
	}
	return data_sum;
}

void EEPROM_Init(void){
	U8_T rev = 0;
	EnIFCClk; //使能 IFC 时钟
	IFC->MR |= 0x10002; //高速模式，延迟 2 个周期
	
	delay_nms(10);
	
	memset(&g_eeprom,0,sizeof(E_PARA_INFO));	
	
	rev = EEPROM_ReadParaInfo(&g_eeprom);
	if(rev == 0x00){
		//读取成功，开始校验以下参数
		EEPROM_Validate_ParaInfo(&g_eeprom);
	}else{
		//读取失败，恢复默认参数
		EEPROM_Default_ParaInfo(&g_eeprom);

		Dbg_Println(DBG_BIT_SYS_STATUS,"Para Info Use Default:%d",g_eeprom.pipe_flag);
	}	
	
}


U8_T EEPROM_ReadParaInfo(E_PARA_INFO *info){
	U8_T read_info[6];
	U8_T para_data[EEPROM_APP_DATA_Size_Max];
	U16_T read_len = 0;
	
	memset(read_info,0,sizeof(read_info));
	memset(para_data,0,sizeof(para_data));
	
	ReadDataArry_U8(EEPROM_ParaInfo_Address,4,read_info);
	
	if(read_info[0] == EEPROM_APP_SVAE_FLAG){
		read_len = read_info[2];
		read_len <<= 8;
		read_len |= read_info[1];
		
		if(read_len <= EEPROM_APP_DATA_Size_Max){
			
			ReadDataArry_U8(EEPROM_ParaInfo_Address+EEPROM_Offset_Data,read_len,para_data);
			if(EEPROM_CheckSum(para_data,sizeof(E_PARA_INFO)) == read_info[3]){
				//校验成功
				memcpy((uint8_t *)info,para_data,sizeof(E_PARA_INFO));
				
				return 0x00;
			}
		}
	}
	
	return 0x01;
}

U8_T EEPROM_WriteParaInfo(E_PARA_INFO *info){
	U8_T save_data[EEPROM_APP_DATA_Size_Max + 6];
	U16_T save_len = sizeof(E_PARA_INFO);
	
	if(save_len >= EEPROM_APP_DATA_Size_Max) save_len = EEPROM_APP_DATA_Size_Max;
	
	save_data[0] = EEPROM_APP_SVAE_FLAG;
	save_data[1] = save_len & 0xFF;
	save_data[2] = (save_len >> 8) & 0xFF;
	
	memcpy(&save_data[4],(uint8_t *)info,save_len);
	
	save_data[3] = EEPROM_CheckSum(&save_data[4],save_len);
	
	save_len+=4;
	
	Page_ProgramData(EEPROM_ParaInfo_Address,save_len,save_data);
	
	return 0;
}

U8_T EEPROM_ClearParaInfo(void){
	U8_T save_data[EEPROM_APP_DATA_Size_Max+10];
	UINT16 save_len = sizeof(E_PARA_INFO);
	
	if(save_len >= EEPROM_APP_DATA_Size_Max)	save_len = EEPROM_APP_DATA_Size_Max;
	
	save_len += 4;
	memset(save_data,0xFF,save_len);

	Page_ProgramData(EEPROM_ParaInfo_Address,save_len,save_data);
	
	return 0;
}

U8_T EEPROM_Validate_ParaInfo(E_PARA_INFO *info){
	U8_T i=0;
	
	//以下为本地参数
	
//	//温差
//	if(info->temp_diff > 18 ){
//		info->temp_diff = EEPROM_TempDifference_Default;		//默认
//	}
//	Dbg_Println(DBG_BIT_SYS_STATUS,"Para Info temp_diff %d",info->temp_diff);
//	
//	//温度显示单位
//	if(info->temp_select > 0x02 ){
//		info->temp_select = EEPROM_TempSelect_Default;				//默认保护电流为10A
//	}
//	
//	
//	if(info->backlight_en >= 0x02)
//	{
//		info->backlight_en = 0x00;
//	}
//	
//	if(info->pipe_flag > 0x02)
//	{
//		info->pipe_flag = 0x00;
//	}
//	
//	if((info->dev_addr == 0x00) || (info->dev_addr == 0xff))
//	{
//		info->dev_addr = 0x01;
//	}
//	
//	//按键灵敏度
//	if(info->key_sens_level > 2)
//	{
//		info->key_sens_level = EEPROM_TouchLevel_Default;    //默认中灵敏度
//	}
//	
//	//显示语言
//	if(info->langue_select > 2)
//	{
//		info->langue_select = EEPROM_LangueSelect_Default;//默认中英文混合
//	}	
	
	//设备端口类型
	if(info->dev_port > 2)                 //2024-12-16
	{
		info->dev_port = POLLING_PORT;                       //默认轮训端口
	}
	
	
	Dbg_Println(DBG_BIT_SYS_STATUS,"Para Info temp unit:%d  backlight_en:%d  key_sens_level:%d device_addr:%d  device_port:%d",\
	info->temp_select,info->backlight_en,info->key_sens_level,info->dev_addr,info->dev_port);
	
	return 0;
}

/*恢复默认值*/
void EEPROM_Default_ParaInfo(E_PARA_INFO *info){
	info->dev_addr = 0x01;
	info->pipe_flag = 0x00;
	info->temp_diff = EEPROM_TempDifference_Default;
	info->temp_select = EEPROM_TempSelect_Default;
	info->backlight_en = 0x00;
	info->key_sens_level = EEPROM_TouchLevel_Default;
	info->langue_select = EEPROM_LangueSelect_Default;	
	info->dev_port = POLLING_PORT;                          //2024-12-16
	
}



/*************<- boot ->****************/
/*******************************************************************************
* Function Name  : EEPROM_ReadMCUDevInfo 
* Description    : 从EEPROM中读取设备信息
*******************************************************************************/
U8_T EEPROM_ReadMCUDevInfo(E_MCU_DEV_INFO *info)
{
	U8_T read_info[6];
	U8_T para_data[EEPROM_DATA_Size_Max];
	U16_T read_len = 0;
	
	memset(read_info,0,sizeof(read_info));
	memset(para_data,0,sizeof(para_data));
	
	ReadDataArry_U8(EEPROM_MCUDevInfo_Address,4,read_info);
	
	if(read_info[0] == EEPROM_SVAE_FLAG){
		read_len = read_info[2];
		read_len <<= 8;
		read_len |= read_info[1];
		
		if(read_len <= EEPROM_DATA_Size_Max){
			
			ReadDataArry_U8(EEPROM_MCUDevInfo_Address+EEPROM_Offset_Data,read_len,para_data);
			if(EEPROM_CheckSum(para_data,sizeof(E_MCU_DEV_INFO)) == read_info[3]){
				//校验成功
				memcpy((uint8_t *)info,para_data,sizeof(E_MCU_DEV_INFO));
				
#if DBG_LOG_EN
				Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevAddr:%d",g_mcu_dev.dev_addr);
				Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevType:%d",g_mcu_dev.dev_type);
				Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevBootVer:%d",g_mcu_dev.dev_boot_ver);
				Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevAppVer:%d",g_mcu_dev.dev_app_ver);
				Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevNameLen:%d",g_mcu_dev.dev_name_len);
				Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevName:%s",g_mcu_dev.dev_name);
#endif
				return 0x00;
			}
		}
	}
	
	return 0x01;
}

/*******************************************************************************
* Function Name  : EEPROM_WriteMCUDevInfo 
* Description    : 将设备信息写入到EEPROM中
*******************************************************************************/
U8_T EEPROM_WriteMCUDevInfo(E_MCU_DEV_INFO *info)
{
	U8_T save_data[EEPROM_DATA_Size_Max + 6];
	U16_T save_len = sizeof(E_MCU_DEV_INFO);
	
	if(save_len >= EEPROM_DATA_Size_Max) save_len = EEPROM_DATA_Size_Max;
	
	save_data[0] = EEPROM_SVAE_FLAG;
	save_data[1] = save_len & 0xFF;
	save_data[2] = (save_len >> 8) & 0xFF;
	
	memcpy(&save_data[4],(uint8_t *)info,save_len);
	
	save_data[3] = EEPROM_CheckSum(&save_data[4],save_len);
	
	save_len+=4;
	
	Page_ProgramData(EEPROM_MCUDevInfo_Address,save_len,save_data);
	
	return 0;
}

/*******************************************************************************
* Function Name  : EEPROM_Default_MCUDevInfo 
* Description    : EEPROM中参数恢复默认值，且将默认参数保存至EEPROM中
*******************************************************************************/
void EEPROM_Default_MCUDevInfo(E_MCU_DEV_INFO *info)
{
#if (Project_Area == 0x01)
	/*Boot 区域*/
	info->dev_addr = 0x00;
	info->dev_type = 0x00;
	info->dev_app_ver = 0x00;
	info->dev_boot_ver = Project_FW_Version;
	info->dev_name_len = sizeof(Peoject_Name);

	memset((char *)info->dev_name,0,EEPROM_DEV_NAME_Size);
	memcpy((char *)info->dev_name,(char *)Peoject_Name,info->dev_name_len);

	EEPROM_WriteMCUDevInfo(info);
#elif (Project_Area == 0x02)
	/*APP 区域*/
	info->dev_addr = 0x01;
	info->dev_type = Project_Type;
	info->dev_app_ver = Project_FW_Version;
	info->dev_name_len = sizeof(Peoject_Name);

	memset((char *)info->dev_name,0,EEPROM_DEV_NAME_Size);
	memcpy((char *)info->dev_name,(char *)Peoject_Name,info->dev_name_len);

	EEPROM_WriteMCUDevInfo(info);
#endif
}

/*******************************************************************************
* Function Name  : EEPROM_Validate_MCUDevInfo 
* Description    : 校验从EEPROM 中读取的参数是否正确，如果不正确的话，便将当前正确的参数写入
		APP区域中，判断APP参数与EEPROM中记录的是否一致
		Boot区域中，判断Boot参数与EEPROM中记录的是否一致
*******************************************************************************/
void EEPROM_Validate_MCUDevInfo(E_MCU_DEV_INFO *info)
{
#if (Project_Area == 0x01)
	/*Boot 区域*/
	U8_T save_flag = 0;

	if(info->dev_boot_ver != Project_FW_Version)
	{
		info->dev_boot_ver = Project_FW_Version;
		save_flag = 0x01;
	}

	if(save_flag == 0x01)
	{
		EEPROM_WriteMCUDevInfo(info);
	}
#elif (Project_Area == 0x02)
	/*APP 区域*/
	U8_T save_flag = 0;

	if(info->dev_app_ver != Project_FW_Version)
	{
		info->dev_app_ver = Project_FW_Version;
		save_flag = 0x01;
	}

	if(info->dev_type != Project_Type)
	{
		info->dev_type = Project_Type;
		save_flag = 0x01;
	}

	if(info->dev_name_len != sizeof(Peoject_Name))
	{
		info->dev_name_len = sizeof(Peoject_Name);
		save_flag = 0x01;
	}

	if(strncmp((char *)info->dev_name,(char *)Peoject_Name,sizeof(Peoject_Name)))
	{
		memcpy((char *)info->dev_name,(char *)Peoject_Name,info->dev_name_len);
		save_flag = 0x01;
	}

	if(save_flag == 0x01)
	{
		EEPROM_WriteMCUDevInfo(info);
	}
#endif
}

