/*
 * @Description: 存储模块-svc层
 * @Author: yangsw
 * @Date: 2021-05-20 18:35:04
 * @LastEditTime: 2022-06-17 16:17:42
 * @LastEditors: yangsw
 * @Reference:
 */

#include "svc_flash.h"
#include "../../log/svc/svc_log.h"
#include "../../util/util_data.h"
#include "../../util/util_time.h"
#include "../../cloud/svc/svc_cloud_protocol.h"
#include "../../cloud/svc/svc_cloud.h"
#include "../../bat/svc/svc_bat.h"
#include "../../lcd/svc/svc_lcd.h"
#include "../../com/svc/svc_com.h"
#include "../../pulse/svc/svc_pulse.h"

S_Flash_Data s_flash_data;

static E_Result_State Device_Security_init(S_Flash_Device_Security *ps_device_security);
static E_Result_State Device_Para_init(S_Flash_Device_Para *ps_device_para);
static E_Result_State Usage_Info_Init(void);
static E_Result_State Svc_Flash_Write_No_Erase(gw_u8 *data, gw_u32 write_addr, gw_u16 write_num);
static E_Result_State Svc_Flash_Check_Addr_Empty(gw_u32 u32Addr, gw_u16 u16Len);
static E_Result_State Read_Device_Security(S_Flash_Device_Security *security);
static E_Result_State Read_Device_Security_Bak(S_Flash_Device_Security *security);
static E_Result_State Write_Device_Security(S_Flash_Device_Security *security);
static E_Result_State Read_Device_Para(S_Flash_Device_Para *para);
static E_Result_State Read_Device_Para_Bak(S_Flash_Device_Para *para);
static E_Result_State Write_Device_Para(S_Flash_Device_Para *para);
static gw_u32 Svc_Flash_Calc_Day_Addr(gw_s32 s32DiffDay);
static E_Result_State Write_Day_Usage(S_Flash_Day_Usage *ps_day_usage);
static E_Result_State Read_Day_Usage(uint8_t pu8Time[3], S_Flash_Day_Usage *ps_day_data);
static gw_u32 Svc_Flash_Calc_Month_Addr(gw_s32 s32MonthDiff);
static E_Result_State Read_MonthUsage_Date(gw_u8 ppu8MonthSaveTime[2], S_Flash_Month_Usage *ps_month_data);
static E_Result_State Write_Month_Usage(S_Flash_Month_Usage *ps_month_usage);
static E_Result_State Svc_Flash_Read_Data_Check(gw_u8 *u8Data, gw_u32 u32Addr, gw_u16 u16Len);
static E_Result_State Svc_Flash_Write_Meter_Event(void);

#if POWERDOWN_EN
static E_Result_State Read_Powerdown_Usage(S_Flash_Day_Data *ps_day_data);
static E_Result_State Write_Powerdown_Usage(S_Flash_Day_Data *ps_day_data)
#endif



/**
 * @brief: 存储模块初始化
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Init(void)
{
#if FLASH_W25X_ENABLE
    Bsp_Flash_Init();
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Init();
#endif

    Svc_Flash_Power_Off();
    Bsp_Iwdg_Feed();
    
    S_Flash_Device_Security security_tem;
    S_Flash_Device_Para para_tem;
    
    Device_Security_init(&security_tem);
    Device_Para_init(&para_tem);
    Usage_Info_Init();
    
//    Svc_Flash_Write_Device_Para(&s_flash_data.s_para);
//    Svc_Flash_Write_Device_Security(&s_flash_data.s_security);
      
    if(Read_Device_Security_Repeat(&s_flash_data.s_security) == E_STATE_ERROR)
    {
      memcpy(&s_flash_data.s_security,&security_tem,sizeof(S_Flash_Device_Security));
    }
    if(Read_Device_Para_Repeat(&s_flash_data.s_para) == E_STATE_ERROR)
    {
      memcpy(&s_flash_data.s_para,&para_tem,sizeof(S_Flash_Device_Para));     
    }
    Bsp_Iwdg_Feed();
    
    Svc_Flash_Get_UploadTime(s_flash_data.s_para.pu8DayUploadTime);
    
#if POWERDOWN_EN
    if (s_flash_data.s_security.u8PowerDownFlag == 1)
    {
        Read_Powerdown_Usage(&s_flash_data.s_day_data); // 如果是掉电后复位，则读取掉电存储区的数据
    }
#endif
}

/**
 * @brief: 存储模块唤醒后的初始化
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Wakeup_Init(void)
{
#if FLASH_W25X_ENABLE
    Bsp_Flash_Init();
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Init();
#endif
    Svc_Flash_Power_Off();
}

/**
 * @brief: flash电源打开
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Power_On(void)
{
    Bsp_Flash_Init();
    Bsp_Flash_Power_On();
    Svc_Com_Delay_Ms(10, 64);
    Bsp_Iwdg_Feed();
}

/**
 * @brief: flash电源关闭
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Power_Off(void)
{
#if FLASH_W25X_ENABLE
    Bsp_Flash_Power_Off();
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Power_Off();
#endif
}

/**
 * @brief: flash重新启动
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Reset(void)
{
    Bsp_Flash_Power_Off();
    Svc_Com_Delay_Ms(5,64);
    Bsp_Flash_Power_On();
}

/**
 * @brief: 获取存储模块相关数据结构体指针
 * @param  {void}
 * @return {S_Flash_Data*} 存储模块相关数据结构体指针
 * @note:
 * @see:
 */
S_Flash_Data *Svc_Flash_Get_Data(void)
{
    return &s_flash_data;
}

/*------------------------------------------------------信息初始化------------------------------------------------------*/
/**
 * @brief: 设备安全信息初始化
 * @param  {void}
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 */
static E_Result_State Device_Security_init(S_Flash_Device_Security *ps_device_security)
{
    memset(ps_device_security, 0, sizeof(S_Flash_Device_Security));
    ps_device_security->u8Sig = FLASH_SIG_USED;
    memcpy(ps_device_security->pu8Key, "1234567812345678", 16);
    memcpy(ps_device_security->product_id, "1862986071908815", 16);
    memcpy(ps_device_security->pu8MeterNum, "1862986071908815", 16);
    /*厂家批号*/
    ps_device_security->u16FactoryBatchNum = FACTORY_NUM;
    ps_device_security->main_version = SW_MAIN_VER; // 软件主版本号
    ps_device_security->sub_version = SW_SUB_VER;   // 软件子版本号
    ps_device_security->u16PulseBaud = 4800;
    return E_STATE_SUCCESS;
}

/**
 * @brief: 设备参数初始化
 * @param  {void}
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 */
static E_Result_State Device_Para_init(S_Flash_Device_Para *ps_device_para)
{
    memset(ps_device_para, 0, sizeof(S_Flash_Device_Para));
    /*过流告警阀值，单位L/h，默认为水表口径对应Q4值，可设置。*/
    ps_device_para->u16LargeFlowThreshold = LARGE_FLOW_CUT;
    /*持续过流告警持续流量，单位L，可设置。*/
    ps_device_para->u16LargeFlowContinue = PLUSE_LARGE_ALARM_FLOW;
    /*反流告警阀值,单位L/h，默认DN15mm：40L/h、DN20mm：64 L/h、DN25mm：126L/h，可设置。*/
    ps_device_para->u16ReverseFlowThreshold = PLUSE_NEG_CUT;
    /*持续反流告警持续流量，单位L，可设置。*/
    ps_device_para->u16ReverseFlowDuration = PLUSE_NEG_ALARM_FLOW;
    /*小流告警阀值,单位L/h，可设置。*/
    ps_device_para->u16SmallFlowThreshold = PULSE_SMALL_CUT;
    /*持续小流告警持续流量，单位L，可设置。*/
    ps_device_para->u16SmallFlowContinue = PULSE_SMALL_ALARM_FLOW;
    /*电压告警阀值,0.01V*/
    ps_device_para->battery1_first_low_voltage_threshold = 3200;
    ps_device_para->battery1_second_low_voltage_threshold = 3000;
    /*上报重连次数,默认2次，可设置0-4次。*/
    ps_device_para->u8ReSendCnt = 2;
    /*周期上报离散起始时间,时间格式为YYMMDDHHMMSS*/
    ps_device_para->u16ReportStart = 2;
    /*周期上报离散结束时间,时间格式为YYMMDDHHMMSS*/
    ps_device_para->u16ReportInterval = 8;
    /*终端启停设置,1启用 0停用 （协议版本2不使用）*/
    ps_device_para->u8DayUptimeEnable = 0;
    /*周期上报频率,可设置为24的约数。例：1、2、3、4、6、8、12、24；当小于24时，周期上报离散起始时间、结束时间无意义*/
    ps_device_para->u32CommCycle = 1440;
    /*密集上报采样起始时间,设置起始整点，当天有效*/
    ps_device_para->u8DenseDataUploadStartTime = 0;
    /*周期采样间隔,30分钟（固化，不可修改）*/
    ps_device_para->u8CollectCycle = 30;
    /*上报重连等待时间,20分钟（固化，不可修改）*/
    ps_device_para->u16ReConnectTime = 20 * 60;
    /*密集采样间隔,5分钟（固化，不可修改）*/
    ps_device_para->u8DenseDataCollectCycle = 5;
    ps_device_para->u32MaxTotalUsage = 99999999;
    memcpy(ps_device_para->s_nb_info.pu8ServerIp, "221.229.214.202,5683", strlen("221.229.214.202,5683"));
    memcpy(ps_device_para->s_nb_info.pu8Apn, "\"cmmtm\"", strlen("\"cmmtm\""));
    /*月用量统计日*/
    ps_device_para->u8MonthUsageStatisticsDay = 1;
    return E_STATE_SUCCESS;
}

/**
 * @brief: 用量信息初始化
 * @param  {void}
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 */
static E_Result_State Usage_Info_Init(void)
{
    S_Flash_Usage_Info *ps_usage_info = &s_flash_data.s_usage_info;
    memset(ps_usage_info, 0, sizeof(S_Flash_Usage_Info));
    return E_STATE_SUCCESS;
}

/*------------------------------------------------------flash基础操作------------------------------------------------------*/
/**
 * @brief: flash读取数据
 * @return {void}
 * @note:
 * @see:
 * @param {gw_u8} *out_buff 读取数据存储的地址指针
 * @param {gw_u32} read_addr 待读取数据flash存放地址
 * @param {gw_u16} read_num 读取数据字节数
 */
void Svc_Flash_Read(gw_u8 *out_buff, gw_u32 read_addr, gw_u16 read_num)
{
    Svc_Flash_Power_On();
#if FLASH_W25X_ENABLE
    Bsp_Flash_Read(out_buff, read_addr, read_num);
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Read(out_buff, read_addr, read_num);
#endif
}

/**
 * @brief: flash写数据
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {gw_u8*} data 待写数据存储的地址指针
 * @param {gw_u32} write_addr 数据flash存放地址
 * @param {gw_u16} write_num 写数据字节数
 */
E_Result_State Svc_Flash_Write(gw_u8 *data, gw_u32 write_addr, gw_u16 write_num)
{
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    Svc_Flash_Power_On();
#if FLASH_W25X_ENABLE
    Bsp_Flash_Write(data, write_addr, write_num);
    return E_STATE_SUCCESS;
#elif EEPROM_P24C_ENABLE
    if (Bsp_Eeprom_Write(data, write_addr, write_num) == E_STATE_SUCCESS)
    {
        return E_STATE_SUCCESS;
    }
#endif
}

/**
 * @brief: flash扇区擦除
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {gw_u32} erase_addr 擦除地址
 */
E_Result_State Svc_Flash_Erase_Sector(gw_u32 erase_addr)
{
    Svc_Flash_Power_On();
    gw_u32 secpos;
    gw_u32 u32Addr;
    u32Addr = erase_addr;
    secpos = u32Addr / FLASH_SECTOR_SIZE; // 扇区地址 0~511 for w25x16
#if FLASH_W25X_ENABLE
    Bsp_Flash_Erase_Sector(secpos);
    return E_STATE_SUCCESS;
#elif EEPROM_P24C_ENABLE
    if (Bsp_Eeprom_Erase_Sector(secpos) == E_STATE_SUCCESS)
    {
        return E_STATE_SUCCESS;
    }
#endif
}

/**
 * @brief: flash写数据，无擦除
 * @return {E_Result_State} 执行结果
 * @note: 无擦除，需保证写入位置为0xFF，不能跨扇区
 * @see:
 * @param {gw_u8*} data 待写数据存储的地址指针
 * @param {gw_u32} write_addr 数据flash存放地址
 * @param {gw_u16} write_num 写数据字节数
 */
static E_Result_State Svc_Flash_Write_No_Erase(gw_u8 *data, gw_u32 write_addr, gw_u16 write_num)
{
    gw_u32 u32BaseAddr = 0;
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    u32BaseAddr = write_addr / FLASH_SECTOR_SIZE;
    if ((write_addr + write_num) / FLASH_SECTOR_SIZE != u32BaseAddr)
    { // 跨扇区
        Svc_Log_Printf(LOG_ERROR, "%s->Out of sector!!", __FUNCTION__);
        return E_STATE_ERROR;
    }
    Svc_Flash_Power_On();
    Bsp_Flash_Write_No_Check(data, write_addr, write_num);
    return E_STATE_SUCCESS;
}

/**
 * @brief: 检查地址是否全为空（0xff）
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param  {gw_u32} u32Addr 地址
 * @param  {gw_u16} u16Len  需检查的长度
 */
static E_Result_State Svc_Flash_Check_Addr_Empty(gw_u32 u32Addr, gw_u16 u16Len)
{
    const gw_u8 u8Compare[10] = {0xff, 0xff, 0xff, 0xff, 0xff,
                                 0xff, 0xff, 0xff, 0xff, 0xff};
    gw_u8 u8Data[10] = {0};

    while (1)
    {
        if (u16Len > 10)
        {
            Svc_Flash_Read(u8Data, u32Addr, 10);
            u16Len -= 10;  // 剩余长度-10
            u32Addr += 10; // 地址+10
            if (memcmp(u8Data, u8Compare, 10))
            {
                return E_STATE_ERROR;
            }
        }
        else if (u16Len <= 10)
        {
            Svc_Flash_Read(u8Data, u32Addr, u16Len);
            if (memcmp(u8Data, u8Compare, u16Len))
            {
                return E_STATE_ERROR;
            }

            break;
        }
    }

    return E_STATE_SUCCESS;
}

/**
 * @brief: flash写OTA数据
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {gw_u8*} data 待写数据存储的地址指针
 * @param {gw_u32} write_addr 数据flash存放地址
 * @param {gw_u16} write_num 写数据字节数
 */
E_Result_State Svc_Flash_Write_Ota(gw_u8 *data, gw_u32 write_addr, gw_u16 write_num)
{
    gw_u32 secpos;
    gw_u16 secoff;
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    Svc_Flash_Power_On();
#if FLASH_W25X_ENABLE
    secpos = write_addr / FLASH_SECTOR_SIZE; // 扇区地址 0~511 for w25x16
    secoff = write_addr % FLASH_SECTOR_SIZE; // 在扇区内的偏移
    if (secoff == 0)
    { // 写扇区的第一个地址要擦除
        Bsp_Flash_Erase_Sector(secpos);
    }
    Bsp_Flash_Write_No_Check(data, write_addr, write_num);
    return E_STATE_SUCCESS;
#endif
}
/*------------------------------------------------------设备参数------------------------------------------------------*/
/**
 * @brief: flash擦除设备参数
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {void}
 */
E_Result_State Svc_Flash_Erase_Para(void)
{
    Svc_Flash_Erase_Sector(FLASH_DEVICE_PARA_ADDR);
    Svc_Flash_Erase_Sector(FLASH_DEVICE_PARA_BAK_ADDR);

    Svc_Flash_Erase_Sector(FLASH_DEVICE_SECURITY_ADDR);
    Svc_Flash_Erase_Sector(FLASH_DEVICE_SECURITY_BAK_ADDR);

    Svc_Flash_Erase_Sector(FLASH_MONTH_USAGE_ADDR);
    Svc_Flash_Erase_Sector(FLASH_MONTH_USAGE_ADDR + FLASH_SECTOR_SIZE);

    for (gw_u8 i = 0; i < 19; i++)
    {
        Svc_Flash_Erase_Sector(FLASH_USAGE_START_ADDR + i * FLASH_SECTOR_SIZE);
    }
    Svc_Flash_Erase_Sector(FLASH_POWERDOWN_SAVE_ADDR);

    Svc_Flash_Erase_Sector(FLASH_Meter_Event_ADDR);
    Svc_Flash_Erase_Sector(FLASH_Meter_Event_ADDR + FLASH_SECTOR_SIZE);

    return E_STATE_SUCCESS;
}

/**
 * @brief: 读取设备安全信息
 * @return {E_Result_State}
 * @note:
 * @see:
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
static E_Result_State Read_Device_Security(S_Flash_Device_Security *security)
{
    gw_u8 sum;
    Svc_Flash_Read((gw_u8 *)security, FLASH_DEVICE_SECURITY_ADDR, sizeof(S_Flash_Device_Security));
    /*标志检查*/
    if (security->u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    /*和校验检查*/
    sum = Util_Data_Check_Sum((gw_u8 *)security, (gw_u32)&security->u8CheckSum - (gw_u32)security);
    if (sum != security->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_INFO, "%s->read ok", __FUNCTION__);
    return E_STATE_SUCCESS;
}

#if FLASH_BAK_ENABLE
/**
 * @brief: 读取备份设备安全信息
 * @return {E_Result_State}
 * @note:
 * @see:
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
static E_Result_State Read_Device_Security_Bak(S_Flash_Device_Security *security)
{
    gw_u8 sum;
    gw_u8 *ptr = (gw_u8 *)security;
    Svc_Flash_Read(ptr, FLASH_DEVICE_SECURITY_BAK_ADDR, sizeof(S_Flash_Device_Security));
    /*标志检查*/
    if (security->u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    /*和校验检查*/
    sum = Util_Data_Check_Sum(ptr, (gw_u32)&security->u8CheckSum - (gw_u32)security);
    if (sum != security->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_INFO, "%s->read ok", __FUNCTION__);
    return E_STATE_SUCCESS;
}
#endif

/**
 * @brief: 写设备安全信息
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
static E_Result_State Write_Device_Security(S_Flash_Device_Security *security)
{
    gw_u8 *ptr = (gw_u8 *)security;

    security->u8CheckSum = Util_Data_Check_Sum(ptr, (gw_u32)&security->u8CheckSum - (gw_u32)security);
    /*写数据*/
    Svc_Flash_Write(ptr, FLASH_DEVICE_SECURITY_ADDR, sizeof(S_Flash_Device_Security));
#if FLASH_BAK_ENABLE
    /*写备份数据*/
    Svc_Flash_Write(ptr, FLASH_DEVICE_SECURITY_BAK_ADDR, sizeof(S_Flash_Device_Security));
#endif
    /*读写入数据进行校验*/
    S_Flash_Device_Security readSecurity;
    if (Read_Device_Security(&readSecurity) == E_STATE_ERROR)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->write fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 写设备安全参数-失败重写
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Security} *security 设备安全参数
 */
E_Result_State Svc_Flash_Write_Device_Security(S_Flash_Device_Security *security)
{
    gw_s8 i;
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    for (i = 0; i < FLASH_REPEAT_WRITE_NUM; i++)
    {
        if (Write_Device_Security(security) == E_STATE_SUCCESS)
        {
            s_flash_data.s_other.u8security_fail = 0;
            if (s_flash_data.s_other.u8para_fail == 0)
            {
                Svc_Flash_Clear_Device_Alarm(b15Save_Abn);
            }
            Svc_Log_Printf(LOG_DEBUG, "%s->write security ok", __FUNCTION__);
            return E_STATE_SUCCESS;
        }
        Svc_Flash_Reset();
    }
    Svc_Log_Printf(LOG_DEBUG, "%s->write security err", __FUNCTION__);
    s_flash_data.s_other.u8security_fail = 1;
    if (s_flash_data.s_other.u8para_fail == 0)
    {
        Svc_Flash_Set_Device_Alarm(b15Save_Abn);
    }
    return E_STATE_ERROR;
}

/**
 * @brief: 读设备参数
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Para} *para 设备参数
 */
static E_Result_State Read_Device_Para(S_Flash_Device_Para *para)
{
    gw_u8 sum;
    gw_u8 *ptr = (gw_u8 *)para;
    Svc_Flash_Read(ptr, FLASH_DEVICE_PARA_ADDR, sizeof(S_Flash_Device_Para));
    if (para->u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    sum = Util_Data_Check_Sum(ptr, (gw_u32)&para->u8CheckSum - (gw_u32)para);
    if (sum != para->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_INFO, "%s->read ok", __FUNCTION__);
    return E_STATE_SUCCESS;
}

#if FLASH_BAK_ENABLE
/**
 * @brief: 读备份设备参数
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Para} *para 设备参数
 */
static E_Result_State Read_Device_Para_Bak(S_Flash_Device_Para *para)
{
    gw_u8 sum;
    gw_u8 *ptr = (gw_u8 *)para;
    Svc_Flash_Read(ptr, FLASH_DEVICE_PARA_BAK_ADDR, sizeof(S_Flash_Device_Para));
    if (para->u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    sum = Util_Data_Check_Sum(ptr, (gw_u32)&para->u8CheckSum - (gw_u32)para);
    if (sum != para->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_INFO, "%s->read ok", __FUNCTION__);
    return E_STATE_SUCCESS;
}
#endif

/**
 * @brief: 写设备参数
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Para} *para 设备参数
 */
static E_Result_State Write_Device_Para(S_Flash_Device_Para *para)
{
    gw_u8 *ptr = (gw_u8 *)para;
    S_Flash_Device_Para readPara;
    para->u8Sig = FLASH_SIG_USED;
    para->u8CheckSum = Util_Data_Check_Sum(ptr, (gw_u32)&para->u8CheckSum - (gw_u32)para);
    Svc_Flash_Write(ptr, FLASH_DEVICE_PARA_ADDR, sizeof(S_Flash_Device_Para));
#if FLASH_BAK_ENABLE
    Svc_Flash_Write(ptr, FLASH_DEVICE_PARA_BAK_ADDR, sizeof(S_Flash_Device_Para));
#endif
    if (Read_Device_Para(&readPara) == E_STATE_ERROR)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->write fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 写设备参数-失败重写
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Para} *para 设备参数
 */
E_Result_State Svc_Flash_Write_Device_Para(S_Flash_Device_Para *para)
{
    gw_s8 i;
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    for (i = 0; i < FLASH_REPEAT_WRITE_NUM; i++)
    {
        if (Write_Device_Para(para) == E_STATE_SUCCESS)
        {
            s_flash_data.s_other.u8para_fail = 0;
            if (s_flash_data.s_other.u8security_fail == 0)
            {
                Svc_Flash_Clear_Device_Alarm(b15Save_Abn);
            }
            Svc_Log_Printf(LOG_DEBUG, "%s->write para ok", __FUNCTION__);
            return E_STATE_SUCCESS;
        }
        Svc_Flash_Reset();
    }
    s_flash_data.s_other.u8para_fail = 1;
    if (s_flash_data.s_other.u8security_fail == 0)
    {
        Svc_Flash_Set_Device_Alarm(b15Save_Abn);
    }
    Svc_Log_Printf(LOG_DEBUG, "%s->write para err", __FUNCTION__);
    return E_STATE_ERROR;
}

/**
 * @brief: 读设备参数-失败重读
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Para} *para 设备参数
 */
E_Result_State Read_Device_Para_Repeat(S_Flash_Device_Para *para)
{
    gw_s8 i;
    for (i = 0; i < FLASH_REPEAT_READ_NUM; i++)
    {
        if (Read_Device_Para(para) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
#if FLASH_BAK_ENABLE
        else if (Read_Device_Para_Bak(para) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
#endif
    }
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_DEBUG, "%s->read para err", __FUNCTION__);
    return E_STATE_ERROR;
}

/**
 * @brief: 读设备安全信息-失败重读
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
E_Result_State Read_Device_Security_Repeat(S_Flash_Device_Security *security)
{
    gw_s8 i;
    for (i = 0; i < FLASH_REPEAT_READ_NUM; i++)
    {
        if (Read_Device_Security(security) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
#if FLASH_BAK_ENABLE
        else if (Read_Device_Security_Bak(security) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
#endif
    }
    if (s_flash_data.u8flashCheckFail == 1) // 电池电压低，不能读写flash
    {
        Svc_Log_Printf(LOG_ERROR, "bat low!!");
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_DEBUG, "%s->read security err", __FUNCTION__);
    return E_STATE_ERROR;
}

/*------------------------------------------------------用量------------------------------------------------------*/
/**
 * @brief: 检查是否需要存储密集周期数据
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Check_Save_Dense_Usage(gw_u8 pu8CurTime[6])
{
    S_Flash_Dense_Usage *ps_dense_usage;
    ps_dense_usage = &s_flash_data.s_usage_info.s_day_usage.s_dense_usage;
    S_Flash_RealTime_Usage *ps_real_usage;
    ps_real_usage = &s_flash_data.s_usage_info.s_day_usage.s_realtime_usage;
    gw_u32 u32CurTime;
    gw_u16 u16Index;
    gw_u32 u32ForwardUsage;
    gw_u32 u32ReverseUsage;
    if (Svc_Cloud_Time_Is_Calibrate() == 0)
    { // 时间未校准的情况下不存储
        return;
    }
    u32CurTime = Util_Time_Date_To_Timestamp(pu8CurTime);
    if (pu8CurTime[3] < s_flash_data.s_para.u8DenseDataUploadStartTime)
    { // 密集采集还未到时间
        ps_dense_usage->u8DataNum = 0;
        return;
    }
    else if (pu8CurTime[3] > (s_flash_data.s_para.u8DenseDataUploadStartTime + 3))
    { // 已经超过4小时
        return;
    }

    if ((pu8CurTime[3] == s_flash_data.s_para.u8DenseDataUploadStartTime) && (ps_dense_usage->u8StartFlag == 0))
    { // 密集采集开始时间
        ps_dense_usage->u8StartFlag = 1;
        ps_dense_usage->u32LastForwardTotalUsage = ps_real_usage->u32ForwardTotalUsage; // 第0个数，不存储，第一个五分钟才是第一周期数据
        ps_dense_usage->u32LastReverseTotalUsage = ps_real_usage->u32ReverseTotalUsage;
    }
    if (pu8CurTime[4] % s_flash_data.s_para.u8DenseDataCollectCycle == 0)
    {                                                                                 // 每5分钟存储一次
        ps_dense_usage->u8TimeInterval = s_flash_data.s_para.u8DenseDataCollectCycle; // 这玩意有点多余
        if (ps_dense_usage->u8StartFlag == 0)                                         // 五分钟一次，防止同一分钟重复存储
        {
            return;
        }
        if (ps_dense_usage->u8SaveFlag == 1)
        {
            Svc_Log_Printf(LOG_INFO, "dense usage save");
            ps_dense_usage->u8SaveFlag = 0;
            // 水表密集周期数据
            u16Index = ((u32CurTime % 86400) - (s_flash_data.s_para.u8DenseDataUploadStartTime * 3600)) / 300;
            if (u16Index == 0)
            {
                memcpy(ps_dense_usage->pu8StartTime, pu8CurTime, 6);
            }
            ps_dense_usage->u8DataNum = u16Index + 1;
            u32ForwardUsage = ps_real_usage->u32ForwardTotalUsage - ps_dense_usage->u32LastForwardTotalUsage; // 累计正流量
            u32ForwardUsage = u32ForwardUsage / 1000;                                                         // 这里存储用方
            u32ReverseUsage = ps_real_usage->u32ReverseTotalUsage - ps_dense_usage->u32LastReverseTotalUsage; // 累计逆流量
            u32ReverseUsage = u32ReverseUsage / 1000;                                                         // 这里存储用方
            if (u32ForwardUsage > 65535)
            { // 大于65535，数据超限，异常
                ps_dense_usage->pu16ForwardUsage[u16Index] = 65535;
            }
            else
            {
                ps_dense_usage->pu16ForwardUsage[u16Index] = u32ForwardUsage;
            }
            if (u32ReverseUsage > 65535)
            {
                ps_dense_usage->pu16ReverseUsage[u16Index] = 65535;
            }
            else
            {
                ps_dense_usage->pu16ReverseUsage[u16Index] = u32ReverseUsage;
            }
        }
        if (ps_dense_usage->u8DataNum == 48)
        {
            ps_dense_usage->u8StartFlag = 0; // 已经集满4小时
        }
        ps_dense_usage->u32LastForwardTotalUsage = ps_real_usage->u32ForwardTotalUsage;
        ps_dense_usage->u32LastReverseTotalUsage = ps_real_usage->u32ReverseTotalUsage; // 更新上一次统计时的用量
    }
    else
    {
        ps_dense_usage->u8SaveFlag = 1;
    }
}

/**
 * @brief: 检查是否需要小时用量
 * @param  {gw_u8} pu8CurTime[6] 年，月，日，时，分，秒
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Check_Save_Hour_Usage(gw_u8 pu8CurTime[6])
{
    S_Flash_Day_Usage *ps_day_usage;
    ps_day_usage = &s_flash_data.s_usage_info.s_day_usage;
    S_Flash_RealTime_Usage *ps_real_usage;
    ps_real_usage = &s_flash_data.s_usage_info.s_day_usage.s_realtime_usage;
    gw_u32 u32Usage;
    gw_u8 u8Hour;
    if (Svc_Cloud_Time_Is_Calibrate() == 0)
    { // 时间未校准的情况下不存储
        return;
    }
    if (Svc_Cloud_Time_Check() == E_CHECK_FAIL)
    {
        return;
    }
    if (pu8CurTime[4] == 0)
    {
        if (ps_day_usage->u8SaveFlag == 1)
        {
            Svc_Log_Printf(LOG_INFO, "hour usage save");
            ps_day_usage->u8SaveFlag = 0;
            u32Usage = ps_real_usage->u32ForwardTotalUsage - ps_day_usage->u32LastTotalUsage; // 区间用量
            u8Hour = pu8CurTime[3];
            if (u8Hour != 0)
            {
                u8Hour -= 1; // 比如12点整是保存11点这一小时的数据
            }
            else
            {
                u8Hour = 23; // 0点整是保存前一天23点这一小时的数据
            }
            ps_day_usage->pu16Data[u8Hour] = u32Usage;

            if (pu8CurTime[3] == 0) // 0点保存用量
            {
                gw_u8 u8Time[3] = {0};
                S_Bat s_bat;
                s_bat = Svc_Bat_Get_Data();
                Util_Time_Cal_Date(pu8CurTime, -1, u8Time);                      // 计算前一天的日期
                memcpy(s_flash_data.s_para.s_usage_index.pu8CurDate, u8Time, 3); // 保存存储日期
                ps_real_usage->u16BatVoltage = s_bat.u16BatValtage;              // 电池电压
                memcpy(ps_real_usage->pu8UsageCollectTime, pu8CurTime, 6);       // 水表采集时间
                if (s_flash_data.u8flashCheckFail == 1)                          // 电池电压低，不能读写flash
                {
                    Svc_Log_Printf(LOG_ERROR, "bat low!!");
                    return ;
                }
                if (Svc_Flash_Write_Day_Usage(ps_day_usage) == E_STATE_SUCCESS)
                {
                    memset(ps_day_usage->pu16Data, 0, 24);
                }
                Svc_Flash_Write_Device_Para(&s_flash_data.s_para); // 保存索引
            }
        }
    }
    else
    {
        ps_day_usage->u8SaveFlag = 1;
    }
}

/**
 * @brief: 计算用量地址
 * @param  {gw_s32} s32DiffDay 与起始存储日期天数的差值
 * @return {gw_u32} 地址
 * @note:  不涉及扇区擦除，每个扇区存100天的用量，共2个扇区
 * @see:
 */
static gw_u32 Svc_Flash_Calc_Day_Addr(gw_s32 s32DiffDay)
{
    gw_u32 u32Addr = FLASH_No_Data_ADDR; // 将地址初始化为无数据区
    gw_u8 u8SectorIndex;
    gw_u8 u8AddrIndex;
    if ((s32DiffDay < 0) && (s32DiffDay >= (0 - FLASH_DAY_USAGE_SECTOR_NUM * FLASH_DAY_USAGE_SECTOR_SUM)))
    {
        s32DiffDay = 0 - s32DiffDay;
        if (s32DiffDay % FLASH_DAY_USAGE_SECTOR_NUM == 0)
        {
            u8SectorIndex = FLASH_DAY_USAGE_SECTOR_SUM - s32DiffDay / FLASH_DAY_USAGE_SECTOR_NUM;
            u8AddrIndex = 0;
        }
        else
        {
            u8SectorIndex = FLASH_DAY_USAGE_SECTOR_NUM - s32DiffDay / FLASH_DAY_USAGE_SECTOR_NUM;
            u8AddrIndex = FLASH_DAY_USAGE_SECTOR_NUM - s32DiffDay % FLASH_DAY_USAGE_SECTOR_NUM;
        }
        u32Addr = FLASH_USAGE_START_ADDR + u8AddrIndex * FLASH_DAY_USAGE_SIZE;
        u32Addr += u8SectorIndex * FLASH_SECTOR_SIZE;
    }

    else if (s32DiffDay >= 0 && s32DiffDay < FLASH_DAY_USAGE_SECTOR_NUM * FLASH_DAY_USAGE_SECTOR_SUM)
    {
        u8SectorIndex = s32DiffDay / FLASH_DAY_USAGE_SECTOR_NUM; // 第u8SectorIndex个扇区
        u8AddrIndex = s32DiffDay % FLASH_DAY_USAGE_SECTOR_NUM;   // 第u8AddrIndex天

        u32Addr = FLASH_USAGE_START_ADDR + u8AddrIndex * FLASH_DAY_USAGE_SIZE;
        u32Addr += u8SectorIndex * FLASH_SECTOR_SIZE;
    }
    return u32Addr;
}

/**
 * @brief: 写日用量,失败重写
 * @param  {void}
 * @return {void}
 * @note:小时用量、累计用量、密集用量
 * @see:
 */
E_Result_State Svc_Flash_Write_Day_Usage(S_Flash_Day_Usage *ps_day_usage)
{
    for (gw_u8 i = 0; i < FLASH_REPEAT_WRITE_NUM; i++)
    {
        if (Write_Day_Usage(ps_day_usage) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
        Svc_Flash_Reset();
    }
    return E_STATE_ERROR;
}

/**
 * @brief: 写日用量
 * @param  {void}
 * @return {void}
 * @note:小时用量、累计用量、密集用量
 * @see:
 */
static E_Result_State Write_Day_Usage(S_Flash_Day_Usage *ps_day_usage)
{
    gw_u32 u32WriteAddr;
    gw_u16 u16Temp = 0;
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    S_Flash_Usage_Index *ps_usage_index;
    ps_usage_index = &s_flash_data.s_para.s_usage_index;
    gw_s32 s32DayDiff;
    gw_u8 pu8CurTime[6];
    memcpy(pu8CurTime, ps_cloud->s_manage.pu8CurTime, 6);

    /*判断是否是首次存储数据*/
    if ((ps_usage_index->pu8StartDate[0] == 0) && (ps_usage_index->pu8StartDate[1] == 0) && (ps_usage_index->pu8StartDate[2] == 0))
    {
        /*计算最新用量数据的存储地址*/
        u32WriteAddr = FLASH_USAGE_START_ADDR;
        memcpy(ps_usage_index->pu8StartDate, pu8CurTime, 3);
    }
    else
    {
        // 计算当前时间和第一次存储时间的天数跨度
        s32DayDiff = Util_Time_Diff_Day(pu8CurTime, ps_usage_index->pu8StartDate);
        // 时间跨度为负数，说明时间倒退，有异常
        if (s32DayDiff < 0)
        {
            Svc_Log_Printf(LOG_ERROR, "%s->s32DayDiff: %d <0!", __FUNCTION__, s32DayDiff);
            return E_STATE_ERROR;
        }
        // 计算数据写入地址
        u32WriteAddr = Svc_Flash_Calc_Day_Addr(s32DayDiff);
        if (s32DayDiff >= FLASH_DAY_USAGE_SECTOR_NUM * FLASH_DAY_USAGE_SECTOR_SUM) // 重新写入第一扇区
        {
            memcpy(ps_usage_index->pu8StartDate, pu8CurTime, 3);
            s32DayDiff = 0;
            u32WriteAddr = FLASH_USAGE_START_ADDR;
        }
        u16Temp = s32DayDiff / FLASH_USAGE_SECTOR_NUM;
    }
    if (s32DayDiff % FLASH_DAY_USAGE_SECTOR_NUM == 0) // 如果是每个扇区的第一天，则先擦除这个扇区
    {
        uint16_t u16Secoff_Addr = (FLASH_USAGE_START_ADDR + FLASH_SECTOR_SIZE * u16Temp);
        Svc_Flash_Erase_Sector(u16Secoff_Addr);
    }
    // 检查地址数据是否为0xff，防止写入失败或改变原有的数据
    if (Svc_Flash_Check_Addr_Empty(u32WriteAddr, FLASH_DAY_USAGE_SIZE) == E_STATE_ERROR)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->Address 0x%lX has data!!!\r\n", __FUNCTION__, u32WriteAddr);
        return E_STATE_ERROR;
    }
    ps_day_usage->u8Sig = FLASH_SIG_USED;
    ps_day_usage->u8CheckSum = Util_Data_Check_Sum((gw_u8 *)ps_day_usage, FLASH_DAY_USAGE_SIZE - 1);
    Svc_Flash_Write_No_Erase((gw_u8 *)ps_day_usage, u32WriteAddr, FLASH_DAY_USAGE_SIZE);

    /*回读校验*/
    S_Flash_Day_Usage read_back;
    Svc_Flash_Read((gw_u8 *)&read_back, u32WriteAddr, FLASH_DAY_USAGE_SIZE);
    if (read_back.u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig err", __FUNCTION__);
        return E_STATE_ERROR;
    }
    if (Util_Data_Check_Sum((gw_u8 *)&read_back, FLASH_DAY_USAGE_SIZE - 1))
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 按日期读用量信息-失败重读
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Day_Data} *usage_info 用量信息
 */
E_Result_State Svc_Flash_Read_Day_Usage(uint8_t pu8Time[3], S_Flash_Day_Usage *ps_day_data)
{
    int8_t i;
    for (i = 0; i < FLASH_REPEAT_READ_NUM; i++)
    {
        if (Read_Day_Usage(pu8Time, ps_day_data) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
        Svc_Flash_Reset();
    }
    return E_STATE_ERROR;
}

/**
 * @brief: 读取对应日期的日用量
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {gw_u8} pu8Time[3] 需要读取信息的日期
 * @param {S_Flash_Day_Data} *ps_day_data 用量信息
 */
static E_Result_State Read_Day_Usage(uint8_t pu8Time[3], S_Flash_Day_Usage *ps_day_data)
{
    gw_u32 u32ReadAddr;
    gw_s32 s32DayDiff;
    S_Flash_Usage_Index *ps_usage_index;
    ps_usage_index = &s_flash_data.s_para.s_usage_index;
    S_Flash_Day_Usage ps_day_usage_temp;

    /*计算对应日期的存储地址*/
    s32DayDiff = Util_Time_Diff_Day(pu8Time, ps_usage_index->pu8StartDate);
    if ((s32DayDiff < (0 - 180)) || (s32DayDiff >= FLASH_DAY_USAGE_SECTOR_NUM * FLASH_DAY_USAGE_SECTOR_SUM))
    {
        Svc_Log_Printf(LOG_ERROR, "%s->the time not receive", __FUNCTION__);
        return E_STATE_ERROR;
    }
    u32ReadAddr = Svc_Flash_Calc_Day_Addr(s32DayDiff);
    /*读用量数据*/
    Svc_Flash_Read((gw_u8 *)&ps_day_usage_temp, u32ReadAddr, FLASH_DAY_USAGE_SIZE);
    if (ps_day_usage_temp.u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig err", __FUNCTION__);
        return E_STATE_ERROR;
    }
    if (Util_Data_Check_Sum((gw_u8 *)&ps_day_usage_temp, FLASH_DAY_USAGE_SIZE - 1))
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/*------------------------------------------------------月用量------------------------------------------------------*/
/**
 * @brief: 计算月用量地址
 * @param  {gw_s32} s32DiffDay 与起始存储日期天数的差值
 * @return {gw_u32} 地址
 * @note:  不涉及扇区擦除，每个扇区存100天的用量，共2个扇区
 * @see:
 */
static gw_u32 Svc_Flash_Calc_Month_Addr(gw_s32 s32MonthDiff)
{
    gw_u32 u32Addr = FLASH_No_Data_ADDR; // 将地址初始化为无数据区
    if (s32MonthDiff < 0)
    {
        s32MonthDiff = 0 - s32MonthDiff;
        s32MonthDiff = 72 - s32MonthDiff; //读的位置和写的位置是相对的
    }
    if ((s32MonthDiff >= 0) && (s32MonthDiff < 36))
    {
        u32Addr = FLASH_MONTH_USAGE_ADDR + s32MonthDiff * Size_Month_Usage;
    }
    else if ((s32MonthDiff >= 36) && (s32MonthDiff < 72))
    {
        u32Addr = FLASH_MONTH_USAGE_ADDR + FLASH_SECTOR_SIZE + s32MonthDiff * Size_Month_Usage;
    }
    return u32Addr;
}

/**
 * @brief: 读取对应月用量
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {gw_u8} ppu8MonthSaveTime[3] 需要读取信息的日期
 * @param {S_Flash_Day_Data} *ps_day_data 用量信息
 */
static E_Result_State Read_MonthUsage_Date(gw_u8 ppu8MonthSaveTime[2], S_Flash_Month_Usage *ps_month_data)
{
    gw_u32 u32ReadAddr;
    gw_s32 s32MonthDiff;
    gw_u8 pu8TempTime[2];
    pu8TempTime[0] = ppu8MonthSaveTime[0]; // 读取月份
    pu8TempTime[1] = ppu8MonthSaveTime[1];
    /*计算对应日期的存储地址*/
    s32MonthDiff = Util_Time_Diff_Month(pu8TempTime, s_flash_data.s_para.s_usage_index.pu8MonthSaveTime); // 计算需要读取的时间与最新一次存储时间的差
    if (s32MonthDiff < 0)                                                                                 // 时间差为负数，则该时间还未存储
    {
        Svc_Log_Printf(LOG_ERROR, "%s->the time not receive", __FUNCTION__);
        return E_STATE_ERROR;
    }
    u32ReadAddr = Svc_Flash_Calc_Month_Addr(s32MonthDiff);
    Svc_Flash_Read((gw_u8 *)ps_month_data, u32ReadAddr, Size_Month_Usage);
    if (ps_month_data->u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig err", __FUNCTION__);
        return E_STATE_ERROR;
    }
    if (Util_Data_Check_Sum((gw_u8 *)ps_month_data, Size_Month_Usage - 1) != ps_month_data->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 读取月用量
 * @return {E_Result_State}
 * @note:
 * @see:
 * @param {S_Flash_Month_Usage} *ps_month_usage 用量信息
 */
E_Result_State Svc_Flash_Read_Month_Usage(gw_u8 ppu8MonthSaveTime[2], S_Flash_Month_Usage *ps_month_usage)
{
    // 起始年份检查
    if (s_flash_data.s_para.s_usage_index.u8StartMonth[0] == 0)
    { // 说明没有保存过存储起始年份
        Svc_Log_Printf(LOG_INFO, "%s->The starting year has not been saved!!", __FUNCTION__);
        memset(ps_month_usage, 0, sizeof(ps_month_usage)); // 全部填0
        return E_STATE_ERROR;
    }
    gw_s8 i;
    for (i = 0; i < FLASH_REPEAT_READ_NUM; i++)
    {
        if (Read_MonthUsage_Date(ppu8MonthSaveTime, ps_month_usage) == E_STATE_SUCCESS)
        {
            return E_STATE_SUCCESS;
        }
    }
    return E_STATE_ERROR;
}

/**
 * @brief: 写月用量信息
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Month_Usage} *ps_month_usage 用量信息
 */
static E_Result_State Write_Month_Usage(S_Flash_Month_Usage *ps_month_usage)
{
    gw_u32 u32WriteAddr;
    gw_s32 s32MonthDiff; // 与第一次存储的月份差值
    S_Flash_Usage_Index *ps_usage_index;
    ps_usage_index = &s_flash_data.s_para.s_usage_index;
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();
    // 起始年份检查
    if ((ps_usage_index->u8StartMonth[0]) && (ps_usage_index->u8StartMonth[1]))
    {
        ps_usage_index->u8StartMonth[0] = ps_cloud->s_manage.pu8CurTime[0];
        ps_usage_index->u8StartMonth[1] = ps_cloud->s_manage.pu8CurTime[1];
        Svc_Flash_Erase_Sector(FLASH_MONTH_USAGE_ADDR);
    }
    // 计算地址
    else
    {
        s32MonthDiff = Util_Time_Diff_Month(ps_cloud->s_manage.pu8CurTime, ps_usage_index->u8StartMonth);
        u32WriteAddr = Svc_Flash_Calc_Month_Addr(s32MonthDiff);
        if (u32WriteAddr == FLASH_MONTH_USAGE_ADDR)
        {
            Svc_Flash_Erase_Sector(FLASH_MONTH_USAGE_ADDR);
        }
        else if (u32WriteAddr == FLASH_MONTH_USAGE_ADDR + FLASH_SECTOR_SIZE)
        {
            Svc_Flash_Erase_Sector(FLASH_MONTH_USAGE_ADDR + FLASH_SECTOR_SIZE);
        }
    }
    // 检查地址数据是否为0xff，防止写入失败或改变原有的数据
    if (Svc_Flash_Check_Addr_Empty(u32WriteAddr, Size_Month_Usage) == E_STATE_ERROR)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->Address 0x%lX has data!!!\r\n", __FUNCTION__, u32WriteAddr);
        return E_STATE_ERROR;
    }
    // 数据写入
    ps_month_usage->u8Sig = FLASH_SIG_USED;
    ps_month_usage->u8CheckSum = Util_Data_Check_Sum((gw_u8 *)ps_month_usage, Size_Month_Usage - 1);
    Svc_Flash_Write_No_Erase((gw_u8 *)ps_month_usage, u32WriteAddr, Size_Month_Usage);
    /*回读校验*/
    S_Flash_Month_Usage ps_read_back;
    Svc_Flash_Read((gw_u8 *)&ps_read_back, u32WriteAddr, Size_Month_Usage);
    if (ps_read_back.u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig err", __FUNCTION__);
        return E_STATE_ERROR;
    }
    if (Util_Data_Check_Sum((gw_u8 *)&ps_read_back, Size_Month_Usage - 1) != ps_month_usage->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 写月用量信息-失败重写
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Month_Usage} *ps_month_usage 用量信息
 */
E_Result_State Svc_Flash_Write_Month_Usage(S_Flash_Month_Usage *ps_month_usage)
{
    gw_s8 i;
    for (i = 0; i < FLASH_REPEAT_WRITE_NUM; i++)
    {
        if (Write_Month_Usage(ps_month_usage) == E_STATE_SUCCESS)
        {
            Svc_Log_Printf(LOG_DEBUG, "%s->write month usage ok", __FUNCTION__);
            return E_STATE_SUCCESS;
        }
        Svc_Flash_Reset();
    }
    return E_STATE_ERROR;
}
/**
 * @brief: 检查是否需要存储月用量
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Flash_Check_Save_Month_Usage(gw_u8 pu8CurTime[6])
{
    S_Flash_Month_Usage *ps_month_usage;
    ps_month_usage = &s_flash_data.s_usage_info.s_month_usage;
    gw_u8 pu8LastTime[2] = {0};
    gw_u32 u32MonthUsage;
    S_Flash_RealTime_Usage *ps_real_usage;
    ps_real_usage = &s_flash_data.s_usage_info.s_day_usage.s_realtime_usage;
    S_Flash_Usage_Index *ps_usage_index;
    ps_usage_index = &s_flash_data.s_para.s_usage_index;
    if (Svc_Cloud_Time_Is_Calibrate() == 0)
    { // 时间未校准的情况下不存储
        return;
    }
    if (Svc_Cloud_Time_Check() == E_CHECK_FAIL)
    {
        return;
    }
    if (s_flash_data.u8flashCheckFail == 1)
    {
        return;
    }
    if ((pu8CurTime[2] == s_flash_data.s_para.u8MonthUsageStatisticsDay) && (pu8CurTime[3] == 0) && (pu8CurTime[4] == 0))
    { // 统计日0点0分，保存上个月用量
        if (ps_month_usage->u8SaveFlag == 1)
        { // 这个月还未存储过，需要存储
            Svc_Log_Printf(LOG_INFO, "month usage save");
            ps_month_usage->u8SaveFlag = 0;
            Util_Time_Cal_Month(pu8CurTime, -1, pu8LastTime);                                                 // 计算上一个月份
            u32MonthUsage = ps_real_usage->u32ForwardTotalUsage - s_flash_data.s_para.u32LastMonthTotalUsage; // 计算当前总用量和上一次统计时的总用量差值，即上个月的使用量
            ps_month_usage->u32monthusage = u32MonthUsage / 1000;                                             // 存储的是方                                                                          // 记录用量
            ps_usage_index->pu8MonthSaveTime[0] = pu8LastTime[0];                                             // 存储日期
            ps_usage_index->pu8MonthSaveTime[1] = pu8LastTime[1];                                             // 记录月份
            s_flash_data.s_para.u32LastMonthTotalUsage = ps_real_usage->u32ForwardTotalUsage;                 // 更新上一次统计时的总用量
            Svc_Flash_Write_Month_Usage(ps_month_usage);
            Svc_Flash_Write_Device_Para(&s_flash_data.s_para); // 保存索引
        }
    }
    else
    {
        ps_month_usage->u8SaveFlag = 1;
    }
}

/**
 * @brief: 计算日常上报时间
 * @param  {upload_time}
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 */
void Svc_Flash_Get_UploadTime(gw_u8 *upload_time)
{
    S_Flash_Device_Para *ps_device_para = &s_flash_data.s_para;

    gw_u32 u32DiscreteStart;
    gw_u32 u32DiscreteMaxTime;
    gw_u8 u8TempStr[3];
    gw_u8 pu8TempTime[3]; // 时，分，秒
    gw_u16 u16TempStr;
    gw_u32 u32UploadTime;
    gw_u32 u32Temp;

    u8TempStr[0] = s_flash_data.s_security.product_id[13];
    u8TempStr[1] = s_flash_data.s_security.product_id[14];
    u8TempStr[2] = s_flash_data.s_security.product_id[15];

    u16TempStr = Util_Data_String_To_Uint16(u8TempStr, 3);
    ps_device_para->u16ReportInterval = 8;
    ps_device_para->u16ReportStart = 2;

    u32DiscreteStart = ps_device_para->u16ReportStart * 60 * 60;                        // 单位秒//起始上报时间
    u32DiscreteMaxTime = (ps_device_para->u16ReportInterval % 100) * 60 * 60;           // 单位秒//上报区间的最大值
    u32UploadTime = u32DiscreteStart + ((u16TempStr % 180) * 120) % u32DiscreteMaxTime; // 生成上报时间戳
    u32Temp = u32UploadTime;
    pu8TempTime[0] = u32Temp / 3600 % 24; // 时
    u32Temp = u32Temp % 3600;
    pu8TempTime[1] = u32Temp / 60; // 分
    pu8TempTime[2] = u32Temp % 60; // 秒

    upload_time[0] = pu8TempTime[0];
    upload_time[1] = pu8TempTime[1];
    upload_time[2] = pu8TempTime[2];
    Svc_Log_Print("Svc_Flash_Get_UploadTime %d %d %d", upload_time[0], upload_time[1], upload_time[2]);
}

/*------------------------------------------------------掉电时存储------------------------------------------------------*/
#if POWERDOWN_EN
/**
 * @brief: 上电后，读取掉电时保存的用量
 * @return {E_Result_State}
 * @note:
 * @see:
 * @param {S_Flash_Day_Data } *ps_day_data 用量信息
 */
static E_Result_State Read_Powerdown_Usage(S_Flash_Day_Data *ps_day_data)
{
    gw_u8 sum;
    gw_u8 *ptr = (gw_u8 *)ps_day_data;
    Svc_Flash_Read(ptr, FLASH_POWERDOWN_SAVE_ADDR, sizeof(S_Flash_Day_Data));
    /*标志检查*/
    if (ps_day_data->u8Sig != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    /*和校验检查*/
    sum = Util_Data_Check_Sum(ptr, (gw_u32)&ps_day_data->u8CheckSum - (gw_u32)ps_day_data);
    if (sum != ps_day_data->u8CheckSum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    Svc_Log_Printf(LOG_INFO, "%s->read ok", __FUNCTION__);
    return E_STATE_SUCCESS;
}

/**
 * @brief: 写用量
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Day_Data } *ps_day_data 用量信息
 */
static E_Result_State Write_Powerdown_Usage(S_Flash_Day_Data *ps_day_data)
{
    //    gw_u8 sum;
    gw_u8 *ptr = (gw_u8 *)ps_day_data;
    S_Flash_Day_Data *ps_read_day_data;
    ps_day_data->u8Sig = FLASH_SIG_USED;
    ps_day_data->u8CheckSum = Util_Data_Check_Sum(ptr, (gw_u32)&ps_day_data->u8CheckSum - (gw_u32)ps_day_data);
    Svc_Flash_Write((gw_u8 *)ps_day_data, FLASH_POWERDOWN_SAVE_ADDR, FLASH_DAY_USAGE_SIZE);
    ps_read_day_data = (S_Flash_Day_Data *)Svc_Com_Get_Buf();
    /*回读校验*/
    if (Svc_Flash_ReadDay_Data_Check(ps_read_day_data, FLASH_POWERDOWN_SAVE_ADDR) == E_STATE_ERROR)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->write usage fail", __FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 写用量
 * @return {E_Result_State} 执行结果
 * @note:
 * @see:
 * @param {S_Flash_Day_Data } *ps_day_data 用量信息
 */
E_Result_State Svc_Flash_Write_Powerdown_Usage(S_Flash_Day_Data *ps_day_data)
{
    gw_s8 i;
    for (i = 0; i < FLASH_REPEAT_WRITE_NUM; i++)
    {
        if (Write_Powerdown_Usage(ps_day_data) == E_STATE_SUCCESS)
        {
            Svc_Log_Printf(LOG_DEBUG, "%s->write usage ok", __FUNCTION__);
            return E_STATE_SUCCESS;
        }
    }
    return E_STATE_ERROR;
}
#endif

/*------------------------------------------------------事件记录------------------------------------------------------*/
/**
 * @brief: 读数据
 * @return {E_Result_State} 执行结果
 * @note:  带校验，不会读取备用地址
 * @see:   测试ok - yess220527
 * @param {gw_u8} *u8Data 头指针
 */
static E_Result_State Svc_Flash_Read_Data_Check(gw_u8 *u8Data, gw_u32 u32Addr, gw_u16 u16Len)
{
    gw_u8 u8Sum = 0;

    Svc_Flash_Read(u8Data, u32Addr, u16Len);
    // 对比写标识
    if (u8Data[0] != FLASH_SIG_USED)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sig fail", __FUNCTION__);
        return E_STATE_ERROR;
    }

    // 对比校验
    u8Sum = Util_Data_Check_Sum(u8Data, u16Len - 1);
    if (u8Data[u16Len - 1] != u8Sum)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->check sum fail", __FUNCTION__);
        return E_STATE_ERROR;
    }

    return E_STATE_SUCCESS;
}

/**
 * @brief: 写flash存储表端事件
 * @return {void}
 * @note:
 * @see:
 * @param
 */
static E_Result_State Svc_Flash_Write_Meter_Event(void)
{
    gw_u32 u32Addr = 0;                                        // 主地址
    gw_u16 *u16Count = &s_flash_data.s_security.u16EventCount; // 获取存储计数
    S_Flash_Meter_Event s_read;
    S_Flash_Meter_Event *meter_event = &s_flash_data.s_meter_event;

    if (s_flash_data.u8flashCheckFail)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->POWER DOWN!!", __FUNCTION__);
        return E_STATE_ERROR;
    }

    if (s_flash_data.s_security.u8Enable_EventCount != 1)
    { // 说明还未存储过
        (*u16Count) = 0;
    }

    // 计算地址
    if ((*u16Count) < 256)
    { // 存第一块扇区
        u32Addr = FLASH_Meter_Event_ADDR + (*u16Count) * Size_Meter_Event;
    }
    else
    { // 存第二块扇区
        u32Addr = FLASH_Meter_Event_ADDR + (*u16Count - 256) * Size_Meter_Event;
        u32Addr += FLASH_SECTOR_SIZE;
    }
    if ((*u16Count) >= 512) // 从第一块扇区开始存储
    {
        (*u16Count) = 0;
        u32Addr = FLASH_Meter_Event_ADDR;
    }
    Svc_Flash_Power_On();  
    // 扇区擦除
    if ((*u16Count) == 0)
    {
        gw_u16 u16Secoff = FLASH_Meter_Event_ADDR / FLASH_SECTOR_SIZE;
        Bsp_Flash_Erase_Sector(u16Secoff);
    }
    else if ((*u16Count) == 256)
    { // 擦除第二块扇区
        gw_u16 u16Secoff = (FLASH_Meter_Event_ADDR + FLASH_SECTOR_SIZE) / FLASH_SECTOR_SIZE;
        Bsp_Flash_Erase_Sector(u16Secoff);
    }

    (*u16Count)++; // 需要先增加计数，再return
    if ((*u16Count) >= 256)
    {
        s_flash_data.s_security.u8Exceed256 = 1;
    }
    s_flash_data.s_security.u8Enable_EventCount = 1;
    Svc_Flash_Write_Device_Security(&s_flash_data.s_security); // 保存计数

    // 检查地址数据是否为0xff，防止写入失败或改变原有的数据
    if (Svc_Flash_Check_Addr_Empty(u32Addr, sizeof(&s_flash_data.s_meter_event)) == E_STATE_ERROR)
    {
        Svc_Log_Printf(LOG_WARNING, "%s->Address 0x%lX has data!!!\r\n", __FUNCTION__, u32Addr);
        return E_STATE_ERROR;
    }

    // 数据写入
    Svc_Flash_Write_No_Erase((gw_u8 *)meter_event, u32Addr, Size_Meter_Event);

    // 校验
    if (Svc_Flash_Read_Data_Check((gw_u8 *)&s_read, u32Addr, Size_Meter_Event) == E_STATE_ERROR)
    { // 写入失败
        Svc_Log_Printf(LOG_ERROR, "%s->write fail!!", __FUNCTION__);
        return E_STATE_ERROR;
    }

    return E_STATE_SUCCESS;
}

/**
 * @brief: 存储表端事件
 * @return {void}
 * @note:
 * @see:
 * @param {E_Flash_Meter_Event} e_event 事件类型
 */
void Svc_Flash_Save_Meter_Event(E_Flash_Meter_Event e_event)
{
    if (Svc_Cloud_Time_Is_Calibrate() == 0)
    { // 时间未校准的情况下不存储
        return;
    }

    gw_u8 u8i = 0;
    gw_u8 u8Time[6] = {0};
    S_Flash_Meter_Event *p_meter_event = &s_flash_data.s_meter_event;
    S_Cloud *ps_cloud_data;
    ps_cloud_data = Svc_Cloud_Get_Data();
    memcpy(u8Time, ps_cloud_data->s_manage.pu8CurTime, 6);

    // 获取时间
    if (e_event == E_Event_Reset)
    {
        Util_Time_Timestamp_To_Time(s_flash_data.s_other.u32RstTimeStamp, u8Time); // 时间戳转日期
        p_meter_event->u8Retain = s_flash_data.s_other.u8RstReason;                // 保存复位原因
    }
    else
    {
        Util_Time_Timestamp_To_Time(ps_cloud_data->s_manage.u32CurTime, u8Time); // 时间戳转日期
    }

    // 写内容
    p_meter_event->u8Sig = FLASH_SIG_USED;
    p_meter_event->e_event = e_event;
    for (u8i = 0; u8i < 6; u8i++)
    {
        p_meter_event->u8BCDTime[u8i] = Util_Data_Decimal_To_Bcd(u8Time[u8i]); // 以BCD码的形式存储时间
    }
    p_meter_event->u8CheckSum = Util_Data_Check_Sum((gw_u8 *)p_meter_event, Size_Meter_Event - 1);
    
    Svc_Log_Printf(LOG_DEBUG, "%s->save event 0X%04x!!!", __FUNCTION__,e_event);
    
    // 存数据
    Svc_Flash_Write_Meter_Event();
    Svc_Flash_Power_Off();
}

/**
 * @brief: BCD码的时间转换为时间戳
 * @return {void}
 * @note:
 * @see:
 * @param {E_Flash_Meter_Event} e_event 事件类型
 */
gw_u32 Svc_Flash_BCD_To_TimeStamp(gw_u8 u8BCDTime[])
{
    gw_u8 u8Time[6];
    gw_u8 u8i = 0;

    for (u8i = 0; u8i < 6; u8i++)
    {
        u8Time[u8i] = Util_Data_Bcd_To_Decimal(u8BCDTime[u8i]);
    }

    return Util_Time_Date_To_Timestamp(u8Time);
}

/**
 * @brief: 读时间段事件记录
 * @return {gw_u8}u8ActLen 实际条数（本帧记录条数，还未处理//<<<<<<<<<<<<<<<<<<<）
 * @note: 未读取备用地址数据
 * @see:
 * @param {E_Flash_Meter_Event} e_event 事件类型
 * @param {gw_u8} u8BCDStart[]  起始时间
 * @param {gw_u8} u8BCDEnd[]    结束时间
 * @param {gw_u8} u8Len         记录条数
 * @param {gw_u8} u8EventData[]     数据
 */
gw_u8 Svc_Flash_Time_Quantum_Meter_Event(E_Flash_Meter_Event e_event, gw_u8 u8BCDStart[], gw_u8 u8BCDEnd[], gw_u8 u8Len, gw_u8 u8EventData[])
{
    gw_u16 u16Index = 0; // 读取事件的位置，u16Index是读取第一个位置的数据
    gw_u8 u8Flag = 0;    // 0-从第一扇区遍历，1-从第二扇区遍历
    gw_u8 u8ActLen = 0;  // 实际条数
    gw_u16 u16i = 0;
    gw_u32 u32Now = 0;
    gw_u32 u32Start = Svc_Flash_BCD_To_TimeStamp(u8BCDStart); // 起始时间的时间戳
    gw_u32 u32End = Svc_Flash_BCD_To_TimeStamp(u8BCDEnd);
    const gw_u8 u8EntryLen = 9;                                         // 一个条目的长度为9字节，协议中定义
    const gw_u16 u16EventCount = s_flash_data.s_security.u16EventCount; // 事件存储位置

    if (s_flash_data.s_security.u8Enable_EventCount != 1)
    { // 表示还未存储过事件
        Svc_Log_Printf(LOG_ERROR, "%s->The event has not been saved!!!", __FUNCTION__);
        u8ActLen = Meter_Event_Entry_Len_Max;
        memset(u8EventData, 0, u8EntryLen * u8ActLen); // 将数据填0
        return u8ActLen;
    }

    //  Svc_Log_Printf(LOG_INFO,"%s->Event:%04X \r\n",__FUNCTION__,e_event);

    if (u16EventCount <= 256 && s_flash_data.s_security.u8Exceed256)
    { // 需要从第二扇区开始读取，最新的还在第一扇区，第二扇区有数据
        u8Flag = 1;
        u16Index = 256;
    }

    for (u16i = 0; u16i < 512; u16i++) // 在两个扇区遍历
    {
        S_Flash_Meter_Event s_meter_event;
        gw_u32 u32Addr = 0;

        Bsp_Iwdg_Feed(); // 喂狗<<

        u16Index++;

        if (u8Flag)
        { // 从第二扇区开始遍历的
            if (u16Index >= 512)
            { // u16Index=512 时准备读取的是第513条位置的数据，所以用>=
                u16Index -= 512;
                u8Flag = 0; // 使后面都进入else分支，当 u16Index >= u16EventCount 时跳出循环
            }
        }
        else
        { // 从第一扇区开始遍历的，或者第二扇区已经遍历完了
            if (u16Index >= u16EventCount)
            { // 因为 u16EventCount=1 时表示存了一条数据，u16Index=1 时准备读取的是第二条数据，所以用>=
                break;
            }
        }

        // 计算地址
        if (u16Index < 256)
        { // 第一个扇区
            u32Addr = FLASH_Meter_Event_ADDR + u16Index * Size_Meter_Event;
        }
        else
        { // 第二个扇区
            u32Addr = FLASH_Meter_Event_ADDR + (u16Index - 256) * Size_Meter_Event;
            u32Addr += FLASH_SECTOR_SIZE;
        }

        //    Svc_Log_Printf(LOG_INFO,"%s->u16Index=%u, u32Addr=%lu \r\n",__FUNCTION__,u16Index, u32Addr);        //打印位置和地址 23.4.17yess - test

        if (Svc_Flash_Read_Data_Check((gw_u8 *)&s_meter_event, u32Addr, Size_Meter_Event) == E_STATE_ERROR)
        { // 读取失败
            //      Svc_Log_Printf(LOG_ERROR,"%s->Failed to read meter event!! u16Index=%u \r\n",__FUNCTION__, u16Index);
            continue;
        }

        u32Now = Svc_Flash_BCD_To_TimeStamp(s_meter_event.u8BCDTime);
        //    Svc_Log_Printf_u8Array((char const*)__FUNCTION__,"Time", s_meter_event.u8BCDTime, 6);               //打印时间  23.4.17yess - test

        // 时间判断
        if (u32Now >= u32Start && u32Now <= u32End) // 时间符合要求
        {

            if (s_meter_event.e_event == e_event || e_event == E_Event_All) // 指定事件或所有事件
            {
                //        Svc_Log_Printf(LOG_INFO,"%s->Event:%04X \r\n",__FUNCTION__,e_event);
                memcpy(&u8EventData[u8EntryLen * u8ActLen], &s_meter_event.e_event, u8EntryLen);
                u8ActLen++;
            }
        }
        else if (u32Now > u32End)
        {
            break;
        }

        // 条数限制
        if (u8ActLen >= Meter_Event_Entry_Len_Max)
        {
            break;
        } // 限制上报的最大条目数，防止内存不够用
        if (u8ActLen >= u8Len)
        {
            break;
        }
    }

    Svc_Flash_Power_Off();
    return u8ActLen;
}

/**
 * @brief: 读最新事件记录    s_flash_data.s_other.u8Exceed256
 * @return {gw_u8}u8ActLen      实际条数（本帧记录条数，续传还未处理//<<<<<<<<<<<<<<<<<<<）
 * @note:
 * @see:
 * @param {E_Flash_Meter_Event} e_event 事件类型
 * @param {gw_u8} u8Len                 读取条数
 * @param {gw_u8} u8EventData[]         数据
 */
gw_u8 Svc_Flash_New_Meter_Event(E_Flash_Meter_Event e_event, gw_u8 u8Len, gw_u8 u8EventData[])
{
    gw_u8 u8ActLen = 0;
    const gw_u16 u16EventCount = s_flash_data.s_security.u16EventCount; // 事件存储位置
    gw_u16 u16Backwards = u16EventCount - 1;                            // 倒走计数
    gw_u16 u16i = 0;
    const gw_u8 u8EntryLen = 9; // 一个条目的长度为9字节，协议中定义
    gw_u8 u8Flag = 0;

    if (s_flash_data.s_security.u8Enable_EventCount != 1)
    { // 表示还未存储过事件
        Svc_Log_Printf(LOG_ERROR, "%s->The event has not been saved!!!", __FUNCTION__);
        u8ActLen = u8Len;
        memset(u8EventData, 0, u8EntryLen * u8ActLen); // 将数据填0
        return u8ActLen;
    }

    for (u16i = 0; u16i < 512; u16i++)
    {
        S_Flash_Meter_Event s_meter_event;
        gw_u32 u32Addr = 0;

        Bsp_Iwdg_Feed(); // 喂狗<<

        // 计算地址
        if (u16Backwards < 256)
        {
            u32Addr = FLASH_Meter_Event_ADDR + u16Backwards * Size_Meter_Event;
        }
        else
        {
            u32Addr = FLASH_Meter_Event_ADDR + (u16Backwards - 256) * Size_Meter_Event;
            u32Addr += FLASH_SECTOR_SIZE;
        }

        //    Svc_Log_Printf(LOG_INFO,"%s->u16Backwards=%u, u32Addr=%lu \r\n",__FUNCTION__,u16Backwards, u32Addr);        //打印地址23.4.17yess - test

        // 读取数据并赋值
        if (Svc_Flash_Read_Data_Check((gw_u8 *)&s_meter_event, u32Addr, Size_Meter_Event) == E_STATE_SUCCESS)
        {                               // 读取成功
            if (e_event == E_Event_All) // 所有事件
            {
                //        Svc_Log_Printf_u8Array((char const*)__FUNCTION__,"Time", s_meter_event.u8BCDTime, 6);                   //打印时间  23.4.17yess - test
                memcpy(&u8EventData[u8EntryLen * u8ActLen], &s_meter_event.e_event, u8EntryLen);
                u8ActLen++;
            }
            else
            {
                if (s_meter_event.e_event == e_event) // 指定事件
                {
                    memcpy(&u8EventData[u8EntryLen * u8ActLen], &s_meter_event.e_event, u8EntryLen);
                    u8ActLen++;
                }
            }
        }
        else
        { // 读取失败，跳过
            Svc_Log_Printf(LOG_ERROR, "%s->Failed to read meter event!!", __FUNCTION__);
        }

        // 条数限制
        if (u8ActLen >= Meter_Event_Entry_Len_Max)
        {
            break;
        } // 限制上报的最大条目数，防止内存不够用
        if (u8ActLen >= u8Len)
        {
            break;
        }

        // 倒走计数
        if (u16Backwards)
        { // 因为起始时 u16Backwards=u16EventCount-1，u16EventCount 为1~256时为第一扇区，所以 u16Backwards 为0~255时为第一扇区
            u16Backwards--;
            if (u16Backwards == 255 && u8Flag == 1)
            {
                break;
            } // 说明是从第一扇区开始遍历，再遍历过第二扇区，下一个为第一扇区的尾
            // u16Backwards=255，u8Flag!=1时，继续往下减
        }
        else
        { // u16Backwards=0 时，说明已经读取过 u16Backwards=0 时的地址
            if (u16EventCount > 256)
            {
                break;
            } // 说明从第二扇区开始，遍历到第一扇区头
            else
            {
                if (s_flash_data.s_security.u8Exceed256 == 1) // 在第一扇区已遍历完，但是第二扇区也有数据
                {
                    u8Flag = 1;
                    u16Backwards = 512 - 1;
                }
                else
                {
                    break;
                }
            }
        }
    }

    Svc_Flash_Power_Off();
    return u8ActLen;
}

/**
 * @brief: 设置运行状态
 * @return
 * @note:
 * @see:
 * @param
 */
void Svc_Flash_Set_Device_Alarm(gw_u32 u32State_Bit)
{
//    E_Upload_Reason upload_reason;
    switch (u32State_Bit)
    {
    case b0Pwoer1:
        Svc_Lcd_Display_Set_Err(E_Lcd_Err_Power_Low);
//        upload_reason = E_UR_Lowpower; // 一级低压
        break;
    case b1Power2: // 二级低压不上报
        Svc_Lcd_Display_Set_Err(E_Lcd_Err_Power_Solow);
        break;
    case b13Reverse_Flow:
        Svc_Lcd_Display_Set_Err(E_Lcd_Reveres_Flow);
//        upload_reason = E_Lcd_ReveFlow;
        break;
    case b15Save_Abn:
        Svc_Lcd_Display_Set_Err(E_Lcd_Save_Abn);
//        upload_reason = E_UR_Save_Abn;
        break;
    case b16Key_Abn:
        Svc_Lcd_Display_Set_Err(E_Lcd_Key_Abn);
//        upload_reason = E_UR_Key_Abn;
        break;
    case b17Large_Flow:
        Svc_Lcd_Display_Set_Err(E_Lcd_Large_Flow);
//        upload_reason = E_UR_LargeFlow;
        break;
    case b18Small_Flow:
        Svc_Lcd_Display_Set_Err(E_Lcd_Small_Flow);
//        upload_reason = E_UR_SmallFlow;
        break;
    case b20Temp_Hig:
        Svc_Lcd_Display_Set_Err(E_Lcd_Temp_Hight);
//        upload_reason = E_UR_HIGHT_TEMP;
        break;
    case b21Temp_Low:
        Svc_Lcd_Display_Set_Err(E_Lcd_Temp_Low);
//        upload_reason = E_UR_LOW_TEMP;
        break;
    case b25Power_Down:
        Svc_Lcd_Display_Set_Err(E_Lcd_Power_Down);
//        upload_reason = E_UR_PowerUp;
        break;
    case b26Blank_Pipe:
        Svc_Lcd_Display_Set_Err(E_Lcd_Blank_Pipe);
//        upload_reason = E_UR_Blank_Pipe;
        break;
    case b29Time_Chip:
        Svc_Lcd_Display_Set_Err(E_Lcd_Time_Chip);
//        upload_reason = E_UR_Time_Chip;
        break;
    case b30Temp_Sensor:
        Svc_Lcd_Display_Set_Err(E_Lcd_Temp_Sensor);
//        upload_reason = E_UR_Temp_Sensor;
        break;
    default:
        break;
    }
    s_flash_data.s_security.s_state.u32device_alarm |= u32State_Bit;
    if (Svc_Flash_IsUpload_Alarm(u32State_Bit) == 0) // 该类型今天未曾上报（只会在周期上报或按键清除）
    {
        if ((u32State_Bit != b1Power2) || (u32State_Bit != b4Power2Back) || (u32State_Bit != b25Power_Down)) // 二级低压不上报
        {
            Svc_Flash_Set_Upload_Alarm(u32State_Bit);
            Svc_Cloud_Post_Event(E_CLOUD_EVENT_DEVICE_INFO_UPLOAD);
//            Svc_Lcd_Display_Upload_Reason(upload_reason, 6);
        }
    }
}

/**
 * @brief: 清除运行状态位
 * @return
 * @note:
 * @see:
 * @param
 */
void Svc_Flash_Clear_Device_Alarm(gw_u32 u32State_Bit)
{
    switch (u32State_Bit)
    {
    case b0Pwoer1:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Err_Power_Low);
        break;
    case b1Power2:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Err_Power_Solow);
        break;
    case b13Reverse_Flow:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Reveres_Flow);
        break;
    case b15Save_Abn:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Save_Abn);
        break;
    case b16Key_Abn:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Key_Abn);
        break;
    case b17Large_Flow:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Large_Flow);
        break;
    case b18Small_Flow:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Small_Flow);
        break;
    case b20Temp_Hig:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Temp_Hight);
        break;
    case b21Temp_Low:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Temp_Low);
        break;
    case b25Power_Down:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Power_Down);
        break;
    case b26Blank_Pipe:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Blank_Pipe);
        break;
    case b29Time_Chip:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Time_Chip);
        break;
    case b30Temp_Sensor:
        Svc_Lcd_Display_Clear_Err(E_Lcd_Temp_Sensor);
        break;
    default:
        break;
    }
    s_flash_data.s_security.s_state.u32device_alarm &= ~u32State_Bit;
}

/**
 * @brief: 检查运行状态位
 * @return
 * @note:报警了：1，没有报警：0
 * @see:
 * @param
 */
gw_u32 Svc_Flash_IsDevice_Alarm(gw_u32 u32State_Bit)
{
    return (s_flash_data.s_security.s_state.u32device_alarm & u32State_Bit) != 0;
}

/**
 * @brief: 设置已上报状态
 * @return
 * @note:
 * @see:
 * @param
 */
void Svc_Flash_Set_Upload_Alarm(gw_u32 u32State_Bit)
{
    s_flash_data.s_other.u32UploadAlarm |= u32State_Bit;
}

/**
 * @brief: 清除已上报状态位
 * @return
 * @note:
 * @see:
 * @param
 */
void Svc_Flash_Clear_Upload_Alarm(gw_u32 u32State_Bit)
{
    s_flash_data.s_other.u32UploadAlarm &= ~u32State_Bit;
}

/**
 * @brief: 清除所有已上报状态位
 * @return
 * @note:
 * @see:
 * @param
 */
void Svc_Flash_Clear_AllUpload_Alarm(void)
{
    s_flash_data.s_other.u32UploadAlarm = 0;
}

/**
 * @brief: 检查已上报状态位
 * @return
 * @note:曾上报过：1，未上报过：0
 * @see:
 * @param
 */
gw_u32 Svc_Flash_IsUpload_Alarm(gw_u32 u32State_Bit)
{
    return (s_flash_data.s_other.u32UploadAlarm & u32State_Bit) != 0;
}

/**
 * @brief: 时间校准后的flash操作
 * @return
 * @note:
 * @see:
 * @param
 */
void Svc_Flash_Time_Calibrate_Deal(gw_s32 s32DiffTime)
{
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();
    gw_u32 u32Last_HourSaveTime;                         // 上一次存储累积量的时间戳
    s_flash_data.s_other.u32RstTimeStamp += s32DiffTime; // 复位时间补偿，用于复位事件记录
    gw_u32 u32Time;
    u32Time = ps_cloud->s_manage.u32CurTime;
    /*首次上电标志为1说明不是第一次上电，需补偿复位时间和事件记录*/
    if (s_flash_data.s_security.first_poweron == 1)
    {
        if (s_flash_data.s_other.u8RstTS_En == 0) // u8RstTS_En不存储，为0表示发生了复位
        {
            s_flash_data.s_other.u8RstTS_En = 1;
            Svc_Flash_Save_Meter_Event(E_Event_Reset);
        }
    }
    u32Last_HourSaveTime = Util_Time_Date_To_Timestamp(s_flash_data.s_usage_info.s_day_usage.s_realtime_usage.pu8UsageCollectTime);
    if (u32Last_HourSaveTime > u32Time)
    { // 倒走
        return;
    }
    if (u32Time / (24 * 3600) != u32Last_HourSaveTime / (24 * 3600)) // 不在同一天
    {                                                                /*时间倒走不需要考虑，存储时会判断一次*/
        
    }
}
