#include "includes.h"

#define Log_Write_size 1024

/*******************************************************************************
* Function Name  : Log_CheckSum 
* Description    : 和校验取反，数据内容从SRAM中读取
*******************************************************************************/
uint8_t Log_CheckSum(uint32_t addr,uint8_t len)
{
	uint8_t data_sum = 0;
	for(uint8_t i = 0;i<len;i++)
	{
		data_sum += SRAM_Read_Byte(addr+i);
	}
	return ~data_sum;
}
/*******************************************************************************
* Function Name  : Data_CheckSum 
* Description    : 和校验取反
*******************************************************************************/
uint8_t Data_CheckSum(uint8_t* data,uint8_t len)
{
	uint8_t data_sum = 0;
	for(uint8_t i = 0;i<len;i++)
	{
		data_sum += data[i];
	}
	return ~data_sum;
}

/*******************************************************************************
* Function Name  : 日志保存功能
* Description    : 日志每一个小时将SRAM中的日志数据进行封装，
	封装就只是加上包头包尾及当前的年月日时，
*******************************************************************************/
uint8_t Log_write_sram(uint8_t data_type,uint8_t *buff,uint16_t len)
{
	uint16_t temp_date = 0;
	uint32_t Last_add = 0;
	uint32_t Log_Hour_Tick = SysTick_1ms - Log_Time_ms;		//2021-09-23  Log_Time_ms该变量在中断中有进行写操作，防止出错，禁止全局变量在中断与while中同时读写
	
	Log_Hour_Tick += RTC_DATA_Type_Cast_DEC(RTC_Raw_Data.minute)*60000;
	Log_Hour_Tick += RTC_DATA_Type_Cast_DEC(RTC_Raw_Data.hour)*3600000;

	uint8_t temp = 0;
	uint16_t data_len = len;
	
	if(data_len >= Log_Data_Len_MAX)	data_len = Log_Data_Len_MAX;		//限定数据长度
	uint16_t write_len = S_Log_Data + data_len + 1;
	/*第一步：读取日志写入地址*/
	Last_add = Get_Log_Current_Address();
	
	//当前地址是否有效，并且可以将该日志保存
	if((Last_add + write_len) >= SRAM_LOG_End_Address)		
	{
		Dbg_Println(DBG_BIT_SYS_STATUS_bit," SRAM Space is not enough");
		Last_add = SRAM_LOG_DATA_Address;
	}
	
	/*第二步：按照指定格式保存日志*/
	SRAM_Write_Byte(LOG_Data_Hand,Last_add + S_Log_Hand);		//数据头
	temp = SRAM_Read_Byte(SRAM_Flash_Serial_Number);
	SRAM_Write_Byte(temp,Last_add + S_Log_SN);					//数据序列号
	temp++;
	SRAM_Write_Byte(temp,SRAM_Flash_Serial_Number);				//将序列号刷新，并保存
	SRAM_Write_Word(write_len,Last_add + S_Log_Len);			//数据长度 2Byte
	SRAM_Write_Byte(0x00,Last_add + S_Log_Check);				//校验值清零
	
	temp_date = (RTC_DATA_Type_Cast_DEC(RTC_Raw_Data.year) << 10) + (RTC_DATA_Type_Cast_DEC(RTC_Raw_Data.month) << 5) + RTC_DATA_Type_Cast_DEC(RTC_Raw_Data.day);

	temp = (temp_date >> 8) & 0xFF;
	SRAM_Write_Byte(temp,Last_add + S_Log_Date_H);				//数据日期H - 年：4bit 月：4bit 
	temp = temp_date & 0xFF;
	SRAM_Write_Byte(temp,Last_add + S_Log_Date_L);				//数据日期L - 日：4bit 时：4bit
	SRAM_Write_Byte(data_type,Last_add + S_Log_Type);			//数据类型
	temp = Log_Hour_Tick & 0xFF;
	SRAM_Write_Byte(temp,Last_add + S_Log_Time8B);				//时间戳
	temp = (Log_Hour_Tick >> 8) & 0xFF;
	SRAM_Write_Byte(temp,Last_add + S_Log_Time16B);
	temp = (Log_Hour_Tick >> 16) & 0xFF;
	SRAM_Write_Byte(temp,Last_add + S_Log_Time24B);
	temp = (Log_Hour_Tick >> 24) & 0xFF;
	SRAM_Write_Byte(temp,Last_add + S_Log_Time32B);
	
	SRAM_Write_Buff(buff,data_len,Last_add + S_Log_Data);		//数据
	SRAM_Write_Byte(Log_Data_End,Last_add + S_Log_Data + data_len);	//数据尾
	
	/*计算数据校验*/
	temp = Log_CheckSum(Last_add,write_len);
	SRAM_Write_Byte(temp,Last_add + S_Log_Check);				//校验值
	
	/*第三：刷新日志写入地址*/
	Last_add = Last_add + write_len;
	Set_Log_Current_Address(Last_add);
	Dbg_Println(DBG_BIT_SYS_STATUS_bit,"SRAM LOG Addr : %08X",Last_add);
	return 0;
}


/*获取SRAM中日志当前写入地址*/
uint32_t Get_Log_Current_Address(void)
{
	uint32_t Last_addr = 0;
	uint8_t temp_d = 0;
	
	temp_d = SRAM_Read_Byte(SRAM_LOG_Start_Address+3);
	Last_addr = temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_LOG_Start_Address+2);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_LOG_Start_Address+1);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_LOG_Start_Address);
	Last_addr |= temp_d;
	
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	return Last_addr;
}

/*设置SRAM中日志当前写入地址*/
void Set_Log_Current_Address(uint32_t W_addr)
{
	uint32_t Last_addr = W_addr;
	uint8_t temp = 0;
	
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	
	temp = Last_addr & 0xFF;
	SRAM_Write_Byte(temp,SRAM_LOG_Start_Address);
	temp = (Last_addr >> 8) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_LOG_Start_Address+1);
	temp = (Last_addr >> 16) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_LOG_Start_Address+2);
	temp = (Last_addr >> 24) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_LOG_Start_Address+3);
}

/*设置SRAM中TFTP当前读日志地址*/
void SRAM_Set_TFTP_READ_LOG_Address(uint32_t r_addr)
{
	uint32_t Last_addr = r_addr;
	uint8_t temp = 0;
	
	/*判断地址是否合法*/
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	
	temp = Last_addr & 0xFF;
	SRAM_Write_Byte(temp,SRAM_TFTP_LOG_READ_Address);
	temp = (Last_addr >> 8) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_TFTP_LOG_READ_Address+1);
	temp = (Last_addr >> 16) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_TFTP_LOG_READ_Address+2);
	temp = (Last_addr >> 24) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_TFTP_LOG_READ_Address+3);
}

/*获取SRAM中TFTP当前读日志地址*/
uint32_t SRAM_Get_TFTP_READ_Log_Address(void)
{
	uint32_t Last_addr = 0;
	uint8_t temp_d = 0;
	
	temp_d = SRAM_Read_Byte(SRAM_TFTP_LOG_READ_Address+3);
	Last_addr = temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_TFTP_LOG_READ_Address+2);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_TFTP_LOG_READ_Address+1);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_TFTP_LOG_READ_Address);
	Last_addr |= temp_d;
	
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	return Last_addr;
}

/*设置SRAM中SD读日志起始地址*/
void SRAM_Set_SD_LOG_READ_Start_Address(uint32_t r_addr)
{
	uint32_t Last_addr = r_addr;
	uint8_t temp = 0;
	
	/*判断地址是否合法*/
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	
	temp = Last_addr & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_Start_Address);
	temp = (Last_addr >> 8) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_Start_Address+1);
	temp = (Last_addr >> 16) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_Start_Address+2);
	temp = (Last_addr >> 24) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_Start_Address+3);
}

/*获取SRAM中SD读日志起始地址*/
uint32_t SRAM_Get_SD_LOG_READ_Start_Address(void)
{
	uint32_t Last_addr = 0;
	uint8_t temp_d = 0;
	
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_Start_Address+3);
	Last_addr = temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_Start_Address+2);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_Start_Address+1);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_Start_Address);
	Last_addr |= temp_d;
	
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	return Last_addr;
}

/*设置SRAM中SD读日志结束地址*/
void SRAM_Set_SD_LOG_READ_End_Address(uint32_t r_addr)
{
	uint32_t Last_addr = r_addr;
	uint8_t temp = 0;
	
	/*判断地址是否合法*/
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	
	temp = Last_addr & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_End_Address);
	temp = (Last_addr >> 8) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_End_Address+1);
	temp = (Last_addr >> 16) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_End_Address+2);
	temp = (Last_addr >> 24) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_SD_LOG_READ_End_Address+3);
}

/*获取SRAM中SD读日志结束地址*/
uint32_t SRAM_Get_SD_LOG_READ_End_Address(void)
{
	uint32_t Last_addr = 0;
	uint8_t temp_d = 0;
	
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_End_Address+3);
	Last_addr = temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_End_Address+2);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_End_Address+1);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_SD_LOG_READ_End_Address);
	Last_addr |= temp_d;
	
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	return Last_addr;
}

/*设置SRAM中FLASH当前读日志地址*/
void SRAM_Set_FLASH_READ_LOG_Address(uint32_t r_addr)
{
	uint32_t Last_addr = r_addr;
	uint8_t temp = 0;
	
	/*判断地址是否合法*/
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	
	temp = Last_addr & 0xFF;
	SRAM_Write_Byte(temp,SRAM_FLASH_LOG_READ_Address);
	temp = (Last_addr >> 8) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_FLASH_LOG_READ_Address+1);
	temp = (Last_addr >> 16) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_FLASH_LOG_READ_Address+2);
	temp = (Last_addr >> 24) & 0xFF;
	SRAM_Write_Byte(temp,SRAM_FLASH_LOG_READ_Address+3);
}

/*获取SRAM中FLASH当前读日志地址*/
uint32_t SRAM_Get_FLASH_READ_LOG_Address(void)
{
	uint32_t Last_addr = 0;
	uint8_t temp_d = 0;
	
	temp_d = SRAM_Read_Byte(SRAM_FLASH_LOG_READ_Address+3);
	Last_addr = temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_FLASH_LOG_READ_Address+2);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_FLASH_LOG_READ_Address+1);
	Last_addr |= temp_d;
	Last_addr <<= 8;
	temp_d = SRAM_Read_Byte(SRAM_FLASH_LOG_READ_Address);
	Last_addr |= temp_d;
	
	if((Last_addr < SRAM_LOG_DATA_Address) || (Last_addr > SRAM_LOG_End_Address)) Last_addr = SRAM_LOG_DATA_Address;
	return Last_addr;
}

/*获取Flash中日志当前保存地址*/
uint32_t Log_Get_Flash_Current_Address(void)
{
	uint8_t rev_buff[4] = {0};
	uint32_t rev_add = 0;
	
	Flash_Read(rev_buff,4,LOG_Flash_Start_Address);
	
	rev_add = rev_buff[3];
	rev_add <<= 8;
	rev_add |= rev_buff[2];
	rev_add <<= 8;
	rev_add |= rev_buff[1];
	rev_add <<= 8;
	rev_add |= rev_buff[0];

	if((rev_add < LOG_Flash_DATA_Address) || (rev_add > LOG_Flash_End_Address)) rev_add = LOG_Flash_DATA_Address;
	return rev_add;
}

/*设置Flash中日志当前保存地址*/
void Log_Set_Flash_Current_Address(uint32_t w_addr)
{
	uint8_t rev_buff[4] = {0};
	
	if((w_addr < LOG_Flash_DATA_Address) || (w_addr > LOG_Flash_End_Address)) w_addr = LOG_Flash_DATA_Address;
	
	rev_buff[0] = w_addr & 0xFF;
	rev_buff[1] = (w_addr >> 8) & 0xFF;
	rev_buff[2] = (w_addr >> 16) & 0xFF;
	rev_buff[3] = (w_addr >> 24) & 0xFF;
	
	Flash_Write(rev_buff,4,LOG_Flash_Start_Address);
}


/*Flash日志数据设置已满标志*/
void Log_set_Flash_overflow_flag(uint8_t overflow_state)
{
	Flash_Write(&overflow_state,1,LOG_Flash_Overflow_Address);
}

/*到时间将SRAM中的日志进一步打包，加上包头包尾，写入Flash中*/
#define Log_Preserve_Time	360	
uint32_t Log_Save_Tick = 0;


/*******************************************************************************
* Function Name  : Log_Write_Flash
* Description    : 将SRAM中日志信息保存到Flash中
* Return         : None
*******************************************************************************/
void Log_Write_Flash(void)
{
	uint32_t Last_add = 0,retain_size = 0,read_size = Log_Write_size,read_add = 0;
	uint32_t Flash_add = 0,surplus_size = 0;
	uint32_t w_num = 0;
	uint8_t	overflow_flag = 0;
	
	Last_add = Get_Log_Current_Address();						//获取SRAM中日志保存结束地址
	read_add = SRAM_Get_FLASH_READ_LOG_Address();				//获取SRAM中Flash读取日志地址
	if(Last_add > read_add)
	{
		retain_size = Last_add - read_add;							//获取SRAM中日志保存大小 - 也就是需要写入的大小
	}else if(Last_add < read_add)	
	{
		retain_size = SRAM_LOG_End_Address - read_add;
		retain_size += Last_add - SRAM_LOG_DATA_Address;
	}
	
	/*写入限定条件 二者满足其一便可保存，都不满足便不保存
		条件1：保存长度大于4096字节
		条件2：保存时间间隔超过24小时
	*/
	if((retain_size < 4096) && (SysTick_1s - Log_Save_Tick < 86400))	{
		Dbg_Println(DBG_BIT_SYS_STATUS_bit,"LOG 未达存储需求!");
		return;
	}
	Log_Save_Tick = SysTick_1s;
	
	Flash_add = Log_Get_Flash_Current_Address();				//获取Flash日志写入地址
	surplus_size = LOG_Flash_End_Address - Flash_add;			//获取Flash日志剩余保存空间
	
	Dbg_Println(DBG_BIT_SYS_STATUS_bit,"LOG start_read_add:0x%08X  Flash Read Addr:0x%08X start_Flash_add:0x%08X  retain_size:0x%08X",Last_add,read_add,Flash_add,retain_size);
	
	if(retain_size != 0)
	{
		w_num = retain_size / Log_Write_size;	//正常写次数
		w_num++;
		Dbg_Println(DBG_BIT_SYS_STATUS_bit,"w_num : %d",w_num);
		
		if(retain_size <= Log_Write_size) read_size = retain_size;		//可以一次完成写入
		if(read_size >= surplus_size) read_size = surplus_size;			//当前空间不满足Log_Write_size写入大小，
		
		if((read_add + read_size) > SRAM_LOG_End_Address)	read_size = SRAM_LOG_End_Address - read_add;

		uint8_t Log_Temporary_Buff[Log_Write_size+3] = {0};
		
		while(w_num--)
		{
			WDT_Feed();
			
			SRAM_DMA_Read_Buff(&Log_Temporary_Buff[1],read_size,read_add);
			Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Flash_Write Flash_add:0x%08X SRAM_Addr:0x%08X write_size:0x%08X",Flash_add,read_add,read_size);
			if((overflow_flag == 1) && (Flash_add == LOG_Flash_DATA_Address))		//保存写满标志位
			{
				overflow_flag = 0;
				Log_Temporary_Buff[0] = 1;
				Flash_Write(Log_Temporary_Buff,read_size+1,Flash_add-1);
			}else {
				Flash_Write(&Log_Temporary_Buff[1],read_size,Flash_add);
			}
			Flash_add += read_size;				//Flash写地址偏移
			read_add += read_size;				//SRAM读地址偏移
		
			
			if(retain_size == read_size) 
			{
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"LOG_Flash Write Complete!");
				break;
			}		
			else 
			{
				surplus_size -= read_size;			//Flash日志保存剩余空间
				retain_size -= read_size;
				
				if(read_add >= SRAM_LOG_End_Address)			//SRAM空间已经读取到结束地址，返回起始地址继续读
				{
					Dbg_Println(DBG_BIT_SYS_STATUS_bit,"LOG_SRAM_End_Address:0x%08X",read_add);
					read_add = SRAM_LOG_DATA_Address;	
					w_num++;		//写次数加一
				}
				if(Flash_add >= LOG_Flash_End_Address) 			//Flash空间已写满，返回起始地址继续写
				{
					Dbg_Println(DBG_BIT_SYS_STATUS_bit,"LOG_Flash_End_Address:0x%08X",Flash_add);
					overflow_flag = 1;
					Flash_add = LOG_Flash_DATA_Address;
					surplus_size = LOG_Flash_End_Address - LOG_Flash_DATA_Address;
					w_num++;		//写次数加一
				}
				
				if(retain_size > Log_Write_size)	read_size = Log_Write_size;
				else read_size = retain_size;
				if(read_size >= surplus_size) read_size = surplus_size;
				
				if((read_add + read_size) > SRAM_LOG_End_Address)	read_size = SRAM_LOG_End_Address - read_add;
				
			}
		}
		
		Dbg_Println(DBG_BIT_SYS_STATUS_bit,"LOG Flash END_add:0x%08X",Flash_add);
		Log_Set_Flash_Current_Address(Flash_add);				//保存Flash写入地址
		SRAM_Set_FLASH_READ_LOG_Address(Last_add);				//SRAM中Flash读日志地址归位
	}
}

/*******************************************************************************
* Function Name  : LOG_Data_Seek
* Description    : 查找日志数据，并输出
* Return         : None
*******************************************************************************/
void LOG_Data_Seek(uint8_t* data,uint32_t len)
{
	uint16_t date_temp = 0;
	uint8_t Log_Len = 0,Log_Data_Len = 0;
	uint32_t hour_tick = 0,min_tick = 0,sec_tick = 0,ms_tick = 0,temp = 0;
	
	for(uint32_t i = 0;i<len;i++)
	{
		if(data[i] == LOG_Data_Hand)
		{
			//Dbg_Print(DBG_BIT_SYS_STATUS_bit,"查找到LOG_Data_Hand %d..\n",i);
			Log_Len = data[i+S_Log_Len];

			if((Data_CheckSum(&data[i],Log_Len) == 0x00) && (data[i + Log_Len - 1] == Log_Data_End))
			{
				Log_Data_Len = Log_Len - S_Log_Data - 1;	//获取数据长度
				
				hour_tick = data[i+S_Log_Time32B];
				hour_tick = hour_tick << 8;
				hour_tick |= data[i+S_Log_Time24B];
				hour_tick = hour_tick << 8;
				hour_tick |= data[i+S_Log_Time16B];
				hour_tick = hour_tick << 8;
				hour_tick |= data[i+S_Log_Time8B];

				//Dbg_Print(DBG_BIT_SYS_STATUS_bit,"hour_tick:%08X buff:%02X%02X%02X%02X\r\n",hour_tick,data[i+S_Log_Time32B],data[i+S_Log_Time24B],data[i+S_Log_Time16B],data[i+S_Log_Time8B]);
				
				temp = hour_tick;
				hour_tick = temp/3600000;
				temp = temp%3600000;
				min_tick = temp/60000;
				temp = temp%60000;
				sec_tick = temp/1000;
				ms_tick = temp%1000;

				date_temp = (data[i+S_Log_Date_H]<<8) + data[i+S_Log_Date_L];
				Dbg_Print(DBG_BIT_SYS_STATUS_bit,"%d-%d-%d %d:%d:%d %dms LOG Data: ",(date_temp >> 10),((date_temp) >> 5)& 0x1F,(date_temp & 0x1F),hour_tick,min_tick,sec_tick,ms_tick);
				for(uint32_t j = 0;j<Log_Data_Len;j++)
				{
					Dbg_Print(DBG_BIT_SYS_STATUS_bit,"%02X,",data[i+S_Log_Data+j]);
				}
				Dbg_Print(DBG_BIT_SYS_STATUS_bit,"\n");
				i += Log_Len - 1;
			}
		}
	}
}

/*******************************************************************************
* Function Name  : Log_Read_Flash
* Description    : 将Flash中日志全部读取出来串口输出
* Return         : None
*******************************************************************************/
void Log_Read_Flash(void)
{
	uint32_t Flash_add = 0,retain_size = 0,w_num = 0,read_size = Log_Write_size;
	uint32_t read_add = LOG_Flash_DATA_Address;
	uint8_t Log_Temporary_Buff[Log_Write_size+3] = {0};
	
	Flash_Read(Log_Temporary_Buff,1,LOG_Flash_Overflow_Address);
	
	if(Log_Temporary_Buff[0] == 0x01)		//保存满了，全部读取出来
	{
		retain_size = LOG_Flash_End_Address - LOG_Flash_DATA_Address;
	}else {
		Flash_add = Log_Get_Flash_Current_Address();
		retain_size = Flash_add - LOG_Flash_DATA_Address;
	}

	w_num = retain_size / Log_Write_size;
	w_num++;
	
	if(retain_size <= Log_Write_size) read_size = retain_size;
	if(read_size == 0)	return ;
	while(w_num--)
	{
		WDT_Feed();
		
//		Dbg_Print(DBG_BIT_SYS_STATUS_bit,"\r\nLOG read_add:0x%08X ,read_size:0x%08X\r\n",read_add,read_size);
		Flash_Read(Log_Temporary_Buff,read_size,read_add);
		Dbg_Print(DBG_BIT_SYS_STATUS_bit,"Flash_Read:");
		for(uint32_t i = 0;i<read_size;i++)
		{
			Dbg_Print(DBG_BIT_SYS_STATUS_bit,"%02X,",Log_Temporary_Buff[i]);
		}
		Dbg_Print(DBG_BIT_SYS_STATUS_bit,"\r\n");
		
		LOG_Data_Seek(Log_Temporary_Buff,read_size);
		
		if(read_size == retain_size) break;		
		else {
			retain_size -= read_size;	//剩余字节递减
			read_add += read_size;		//读地址偏移
			if(retain_size > Log_Write_size)	read_size = Log_Write_size;
			else read_size = retain_size;
		}
	}
}

/*******************************************************************************
* Function Name  : LOG_Save_Device_Change
* Description    : 保存设备变化数据 - 长度最大200Byte
* Return         : None
*******************************************************************************/
void LOG_Save_Device_Action(uint8_t type,uint8_t addr,uint16_t loop,uint16_t state)
{
	uint8_t temp_buf[10];
	memset(temp_buf,0,sizeof(temp_buf));
	
	temp_buf[0] = type;
	temp_buf[1] = addr;
	temp_buf[2] = loop&0xFF;
	temp_buf[3] = (loop>>8)&0xFF;
	temp_buf[4] = state&0xFF;
	temp_buf[5] = (state>>8)&0xFF;
	
	Log_write_sram(Log_Type_Device_Change,temp_buf,0x06);
}

/*******************************************************************************
* Function Name  : LOG_Save_Device_Change
* Description    : 保存设备变化数据 - 长度最大200Byte
* Return         : None
*******************************************************************************/
void LOG_Save_Device_Change(uint32_t data_addr, uint16_t data_len)
{
	uint16_t temp_len = data_len;
	if(temp_len > 200)	temp_len = 200;
	uint8_t temp_data[temp_len];
	
	memset(temp_data,0,sizeof(temp_data));
	SRAM_Read_Buff(temp_data,temp_len,data_addr);
	Log_write_sram(Log_Type_Device_Change,temp_data,temp_len);
}

/*******************************************************************************
* Function Name  : LOG_Save_Global_Parameters
* Description    : 保存全局参数
* Return         : None
*******************************************************************************/
void LOG_Save_Global_Parameters(void)
{
	static uint32_t polling_tick = 0;
	uint8_t log_len = 0;
	uint8_t log_buff[22];
	memset(log_buff,0,22);

	/*2025-09-08 修改
		全局变量定期查看变量是否发生变化
			取电状态、睡眠模式状态、全局色温、全局亮度、无卡取电中的有无人状态
	*/
	if(SysTick_1ms - polling_tick >= 2000)
	{
		polling_tick = SysTick_1ms;
		
		if( (DevActionGlobal.DevActionU64Cond.EleState != DevActionGlobal.Last_EleState)	
			|| (DevActionGlobal.DimGlobalValue != DevActionGlobal.Last_DimGlobalValue)	
			|| (DevActionGlobal.CCTValue != DevActionGlobal.Last_CCTValue)	
			|| (DevActionGlobal.SleepMode_State != DevActionGlobal.Last_SleepMode_State)	
			|| (DevActionGlobal.SleepLight_State != DevActionGlobal.Last_SleepLight_State)	
			|| (DevActionGlobal.Person_Detected != DevActionGlobal.Last_Person_Detected)
			|| (DevActionGlobal.CardState != DevActionGlobal.Last_CardState)
			|| (DevActionGlobal.Rs485CardType != DevActionGlobal.Last_Rs485CardType)
            || (DevActionGlobal.DevActionU64Cond.NeightState != DevActionGlobal.Last_NeightState)		)
		{
			DevActionGlobal.Last_EleState = DevActionGlobal.DevActionU64Cond.EleState;
			DevActionGlobal.Last_DimGlobalValue = DevActionGlobal.DimGlobalValue ;
			DevActionGlobal.Last_CCTValue = DevActionGlobal.CCTValue;
			DevActionGlobal.Last_SleepMode_State = DevActionGlobal.SleepMode_State;
			DevActionGlobal.Last_SleepLight_State = DevActionGlobal.SleepLight_State;
			DevActionGlobal.Last_Person_Detected = DevActionGlobal.Person_Detected;
			DevActionGlobal.Last_CardState = DevActionGlobal.CardState;
			DevActionGlobal.Last_Rs485CardType = DevActionGlobal.Rs485CardType;
			DevActionGlobal.Last_NeightState = DevActionGlobal.DevActionU64Cond.NeightState;
			
			log_len = 0x00;
			log_buff[log_len++] = 0xA8;			//保存标志位
			log_buff[log_len++] = 0x00;			//数据长度
			log_buff[log_len++] = 0x00;			//数据校验位
			
			log_buff[log_len++] = DevActionGlobal.Last_EleState;							//取电状态
			log_buff[log_len++] = (DevActionGlobal.Last_DimGlobalValue & 0xFF);				//全局亮度
			log_buff[log_len++] = ((DevActionGlobal.Last_DimGlobalValue >> 8) & 0xFF);		//全局亮度
			log_buff[log_len++] = (DevActionGlobal.Last_CCTValue & 0xFF);					//全局色温
			log_buff[log_len++] = ((DevActionGlobal.Last_CCTValue >> 8) & 0xFF);			//全局色温
			log_buff[log_len++] = DevActionGlobal.Last_SleepMode_State;						//睡眠模式
			log_buff[log_len++] = DevActionGlobal.Last_SleepLight_State;					//睡眠灯光状态
			log_buff[log_len++] = DevActionGlobal.Last_Person_Detected;						//无卡取电中，有无人状态
			log_buff[log_len++] = DevActionGlobal.Last_CardState;
			log_buff[log_len++] = DevActionGlobal.Last_Rs485CardType;
			log_buff[log_len++] = DevActionGlobal.Last_NeightState;
			
			log_buff[1] = log_len;			//数据长度
			log_buff[2] = CheckSum(log_buff,log_len);			//计算校验值
			
			Dbg_Println(DBG_BIT_SYS_STATUS_bit,"%s %d",__func__,DevActionGlobal.Last_Person_Detected);
			
			SRAM_DMA_Write_Buff(log_buff,log_len,SRAM_PowerOn_Restore_StartAddr );
		}
	}
}

/*上电后，读取外部SRAM中的参数信息 */
uint8_t SRAM_PowerOn_Restore_ParaInfo(void)
{
	uint8_t log_len = 0;
	uint8_t log_buff[22];
	uint16_t temp_val = 0;
	memset(log_buff,0,22);
	
	SRAM_DMA_Read_Buff(log_buff,20,SRAM_PowerOn_Restore_StartAddr );
	
	if(log_buff[0] == 0xA8)		//校验标志位
	{
		if(log_buff[1] == 0x0E)	//校验数据长度
		{
			if(CheckSum(log_buff,0x0E) == 0x00)
			{
				log_len = 0x03;
				DevActionGlobal.Last_EleState = log_buff[log_len++];
				
				temp_val = log_buff[log_len++];
				temp_val <<= 8;
				temp_val |= log_buff[log_len++];
				DevActionGlobal.Last_DimGlobalValue = temp_val;
				
				temp_val = log_buff[log_len++];
				temp_val <<= 8;
				temp_val |= log_buff[log_len++];
				DevActionGlobal.Last_CCTValue = temp_val;
				
				DevActionGlobal.Last_SleepMode_State = log_buff[log_len++];
				
				DevActionGlobal.Last_SleepLight_State = log_buff[log_len++];
				
				DevActionGlobal.Last_Person_Detected = log_buff[log_len++];
				
				DevActionGlobal.Last_CardState = log_buff[log_len++];
				
				DevActionGlobal.Last_Rs485CardType  = log_buff[log_len++];
				
				DevActionGlobal.Last_NeightState  = log_buff[log_len++];
				
				DevActionGlobal.DevActionU64Cond.EleState = DevActionGlobal.Last_EleState;
				DevActionGlobal.DimGlobalValue = DevActionGlobal.Last_DimGlobalValue;
				DevActionGlobal.CCTValue = DevActionGlobal.Last_CCTValue;
				DevActionGlobal.SleepMode_State = DevActionGlobal.Last_SleepMode_State;
				DevActionGlobal.SleepLight_State = DevActionGlobal.Last_SleepLight_State;
				DevActionGlobal.Person_Detected = DevActionGlobal.Last_Person_Detected;
				DevActionGlobal.CardState= DevActionGlobal.Last_CardState;
				DevActionGlobal.Rs485CardType= DevActionGlobal.Last_Rs485CardType;
				DevActionGlobal.DevActionU64Cond.NeightState = DevActionGlobal.Last_NeightState;
				
				DevActionGlobal.sram_save_flag = 0xA8;
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_EleState:%d ",DevActionGlobal.Last_EleState);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_DimGlobalValue:%d ",DevActionGlobal.Last_DimGlobalValue);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_CCTValue:%d ",DevActionGlobal.Last_CCTValue);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_SleepMode_State:%d ",DevActionGlobal.Last_SleepMode_State);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_SleepLight_State:%d ",DevActionGlobal.Last_SleepLight_State);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_Person_Detected:%d ",DevActionGlobal.Last_Person_Detected);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_CardState:%d ",DevActionGlobal.Last_CardState);
				Dbg_Println(DBG_BIT_SYS_STATUS_bit,"Last_NeightState:%d ",DevActionGlobal.Last_NeightState);
				
				return 0x00;
			}
		}
	}
	
	DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;   //默认非睡眠（默认非睡眠时调试口打印的值是NightModeOpen）
	DevActionGlobal.SleepMode_State = 0x00; 						//默认开背光
	
	/*RCU根据MCU复位状态进行设备初始化 - 
		保存标志位成立的情况下，如果是看门狗复位、软件复位、外部手动复位，将之前保存的状态进行设备初始化
		否则采用默认状态初始化(默认状态可通过RCU_POWER_Deivce_State_Init 宏定义 修改默认初始化状态)
	*/
	if( (SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) == 0x01) || (SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) == 0x03) || (SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) == 0x05) )
	{
		/*如果看门狗复位的话，上电默认为有人*/
		DevActionGlobal.DevActionU64Cond.EleState = 0x01;	
	}else {
		/*如果不是看门狗复位的话，上电默认为无人*/
#if RCU_POWER_Deivce_State_Init			
		DevActionGlobal.DevActionU64Cond.EleState = 0x01;
#else
		DevActionGlobal.DevActionU64Cond.EleState = 0x02;
#endif		
	}
	
	return 0x01;
}

/*******************************************************************************
* Function Name  : Retain_Flash_Register_Data
* Description    : 保存项目寄存器值
* Return         : None
*******************************************************************************/
void Retain_Flash_Register_Data(void)
{
	uint8_t temp = 0,temp1 = 0;
	uint16_t i = 0;
	
	memset(Global_Large_Buff,0,Register_OFFSET_LEN);
	
	Flash_Read(Global_Large_Buff,Register_OFFSET_LEN,FLASH_Register_Start_ADDRESS);
	
	for(i = 0;i<Register_OFFSET_LEN;i++)
	{
		temp1 = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS+i);
		if(temp1 != Global_Large_Buff[i])
		{
			Global_Large_Buff[i] = temp1;
			temp++;
		}
	}
	
	/*将数据保存到Flash中*/
	if(temp != 0x00)	
	{
		Flash_Write(Global_Large_Buff,Register_OFFSET_LEN,FLASH_Register_Start_ADDRESS);
	}
}

/*******************************************************************************
* Function Name  : Read_Flash_Register_Data
* Description    : 读取项目寄存器值
* Return         : None
*******************************************************************************/
void Read_Flash_Register_Data(void)
{
	memset(Global_Large_Buff,0,Register_OFFSET_LEN);
	
	Flash_Read(Global_Large_Buff,Register_OFFSET_LEN,FLASH_Register_Start_ADDRESS);
	SRAM_DMA_Write_Buff(Global_Large_Buff,Register_OFFSET_LEN,SRAM_Register_Start_ADDRESS);
}





