/*
 * @Author       : stark1898y 1658608470@qq.com
 * @Date         : 2024-09-05 10:24:05
 * @LastEditors  : stark1898y 1658608470@qq.com
 * @LastEditTime : 2024-09-08 11:51:17
 * @FilePath     : \JT-DT-YD4N02A_RTT_MRS-4G\bsp\inc\bsp_flash.h
 * @Description  :
 *
 * Copyright (c) 2024 by yzy, All Rights Reserved.
 */
#ifndef __BSP_FLASH_H__
#define __BSP_FLASH_H__

#include "board.h"
#include "rtdef.h"
#include "bsp_hr.h"

#define FLASH_PAGE_SIZE           (256U)
#define FLASH_PAGE_HR_RECORD_NUM  (25U)
#define FLASH_HR_ONE_RECORD_SIZE  (10U)

#define HR_ALARM_MAX_NUM          (200)
#define HR_ALARM_RCY_MAX_NUM      (200)
#define HR_FAULT_MAX_NUM          (100)
#define HR_FAULT_RCY_MAX_NUM      (100)
#define HR_POWER_FAILURE_MAX_NUM  (50)
#define HR_POWER_ON_MAX_NUM       (50)
#define HR_SENSOR_FAILURE_MAX_NUM (1)

#define HR_ALARM_PAGES            (9U) // 8 + 1 page
#define HR_ALARM_RCY_PAGES        (9U) // 8 + 1 page
#define HR_FAULT_PAGES            (5U) // 4 + 1 page
#define HR_FAULT_RCY_PAGES        (5U) // 4 + 1 page
#define HR_POWER_FAILURE_PAGES    (3U) // 2 + 1 page
#define HR_POWER_ON_PAGES         (3U) // 2 + 1 page
#define HR_SENSOR_FAILURE_PAGES   (1U) // 1 page

#define FLASH_CONFIG_INFO_PAGES   (1U)

#define HR_RECORD_FRAME_HEADER    (0xAA55U)
#define HR_RECORD_FRAME_LEN       (10U)

#define FLASH_START_ADDR          (0x08000000U)
#define FALSH_SIZE_KB             (256U)

// FLASH_CONFIG
#define FLASH_LAST_PAGE_START_ADDR         (FLASH_START_ADDR + (FALSH_SIZE_KB * 1024U) - FLASH_PAGE_SIZE)
#define FLASH_CONFIG_INFO_START_ADDR       FLASH_LAST_PAGE_START_ADDR
#define FLASH_FACTORY_TIME_START_ADDR      FLASH_CONFIG_INFO_START_ADDR

#define FLASH_HR_SENSOR_FAILURE_START_ADDR (FLASH_FACTORY_TIME_START_ADDR - FLASH_PAGE_SIZE)
#define FLASH_HR_POWER_ON_START_ADDR       (FLASH_HR_SENSOR_FAILURE_START_ADDR - FLASH_PAGE_SIZE * HR_POWER_ON_PAGES)
#define FLASH_HR_POWER_FAILURE_START_ADDR  (FLASH_HR_POWER_ON_START_ADDR - FLASH_PAGE_SIZE * HR_POWER_FAILURE_PAGES)
#define FLASH_HR_FAULT_RCY_START_ADDR      (FLASH_HR_POWER_FAILURE_START_ADDR - FLASH_PAGE_SIZE * HR_FAULT_RCY_PAGES)
#define FLASH_HR_FAULT_START_ADDR          (FLASH_HR_FAULT_RCY_START_ADDR - FLASH_PAGE_SIZE * HR_FAULT_PAGES)
#define FLASH_HR_ALARM_RCY_START_ADDR      (FLASH_HR_FAULT_START_ADDR - FLASH_PAGE_SIZE * HR_ALARM_RCY_PAGES)
#define FLASH_HR_ALARM_START_ADDR          (FLASH_HR_ALARM_RCY_START_ADDR - FLASH_PAGE_SIZE * HR_ALARM_PAGES)

#define FLASH_FACTOR_TIME_NUM (6U)//这是通过脱机烧录器进行写入的，所以必须要保证这一页不含有效数据
// #define FLASH_FACTOR_TIME_NUM_ADDR   (FLASH_HR_ALARM_START_ADDR + FLASH_PAGE_SIZE)//
#define FLASH_FACTOR_TIME_NUM_ADDR     0x08032000

/*系统配置信息*/
// 产品有效期
#define FLASH_EXPIRATION_TIME_START_ADDR (FLASH_FACTORY_TIME_START_ADDR + sizeof(TuFlashProductTimeLimitFrame))
#define FLASH_EXPIRATION_TIME_LEN        (sizeof(TuFlashProductTimeLimitFrame))

// 硬件版本号
#define FLASH_HW_VER_ADDR (FLASH_EXPIRATION_TIME_START_ADDR + FLASH_EXPIRATION_TIME_LEN)
#define FLASH_HW_VER_LEN  (1)

// 软件版本号
#define FLASH_SW_VER_ADDR (FLASH_HW_VER_ADDR + FLASH_HW_VER_LEN)
#define FLASH_SW_VER_LEN  (1)

// 报警阈值低值
#define FLASH_ALARM_L_VALUE_ADDR (FLASH_SW_VER_ADDR + FLASH_SW_VER_LEN)
#define FLASH_ALARM_L_VALUE_LEN  (1)

// 报警阈值高值
#define FLASH_ALARM_H_VALUE_ADDR (FLASH_ALARM_L_VALUE_ADDR + FLASH_ALARM_L_VALUE_LEN)
#define FLASH_ALARM_H_VALUE_LEN  (1)

/*温度报警阈值*/
#define FLASH_TEMP_ALARM_THRESHOLD_ADDR (FLASH_ALARM_H_VALUE_ADDR + FLASH_ALARM_H_VALUE_LEN)
#define FLASH_TEMP_ALARM_THRESHOLD_LEN  (1)

// 上传周期
#define FLASH_IOT_UPLOAD_CYCLE_ADDR (FLASH_TEMP_ALARM_THRESHOLD_ADDR + FLASH_TEMP_ALARM_THRESHOLD_LEN)
#define FLASH_IOT_UPLOAD_CYCLE_LEN  (2)

// 重试次数
#define FLASH_IOT_RETRY_ADDR (FLASH_IOT_UPLOAD_CYCLE_ADDR + FLASH_IOT_UPLOAD_CYCLE_LEN)
#define FLASH_IOT_RETRY_LEN  (1)


/*电磁阀功能开启*/
#define FLASH_EMAGNETIC_SWITCH_ADDR (FLASH_IOT_RETRY_ADDR + FLASH_IOT_RETRY_LEN)
#define FLASH_EMAGNETIC_SWITCH_LEN  (1)

/*继电器功能开启*/
#define FLASH_RELAY_SWITCH_ADDR         (FLASH_EMAGNETIC_SWITCH_ADDR + FLASH_EMAGNETIC_SWITCH_LEN)
#define FLASH_RELAY_SWITCH_LEN          (1)

//imei
#define FLASH_IOT_IMEI_ADDR (FLASH_RELAY_SWITCH_ADDR + FLASH_RELAY_SWITCH_LEN)
#define FLASH_IOT_IMEI_LEN  (15)

// imsi
#define FLASH_IOT_IMSI_ADDR (FLASH_IOT_IMEI_ADDR + FLASH_IOT_IMEI_LEN)
#define FLASH_IOT_IMSI_LEN  (15)

// iccid
#define FLASH_IOT_ICCID_ADDR (FLASH_IOT_IMSI_ADDR + FLASH_IOT_IMSI_LEN)
#define FLASH_IOT_ICCID_LEN  (20)

/*工作时长记录*/
#define FLASH_WORK_TIME_ADDR (FLASH_IOT_ICCID_ADDR + FLASH_IOT_ICCID_LEN)
#define FLASH_WORK_TIME_LEN  (2)//单位：天

/*正式平台服务器地址*/
#define FLASH_SERVER_ADDR_ADDR (FLASH_WORK_TIME_ADDR + FLASH_WORK_TIME_LEN)
#define FLASH_SERVER_LEN       (6) //FF.FF.FF.FF:FFFF





#define FLASH_INIT_FLAG_ADDR            (FLASH_CONFIG_INFO_START_ADDR + 254)

#define FLASH_FIRST_INIT_VALUE          (0xA2A2U)
#define FLASH_SYS_PRODUCT_VALUE         (0xA3A3U)
#define FLASH_SYS_USER_VALUE            (0xA4A4U)

#define FLASH_CONFIG_INFO_FRAME_HEADER  (0xA5A5U)

#define FLASH_PRODUCT_TIME_FRAME_HEADER (0xA5U)

typedef enum
{
    kFactoryTimeId = 0U,
    kExpirationTimeId
} TeFlashProductTimeLimitId;

typedef struct __attribute__((packed))
{
    uint8_t header;
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
    uint8_t second;
} TsFlashProductTimeLimitFrame;

typedef union
{
    uint8_t buf[sizeof(TsFlashProductTimeLimitFrame)];
    TsFlashProductTimeLimitFrame Struct;
} TuFlashProductTimeLimitFrame;

// TODO:报警阈值
typedef struct __attribute__((packed))
{
    uint16_t header;
    uint16_t value;
} TsFlashMqAlarmFrame;

typedef union
{
    uint8_t buf[sizeof(TsFlashMqAlarmFrame)];
    TsFlashMqAlarmFrame Struct;
} TuFlashMqAlarmFrame;

typedef struct __attribute__((packed))
{
    uint16_t header;
    uint16_t index;
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
} TsFlashHrRecordFrame;

typedef union
{
    uint8_t buf[HR_RECORD_FRAME_LEN];
    TsFlashHrRecordFrame Struct;
} TuFlashHrRecordFrame;

typedef struct
{
    uint8_t alarm;
    uint8_t alarm_rcy;
    uint8_t fault;
    uint8_t fault_rcy;
    uint8_t power_failure;
    uint8_t power_on;
    uint8_t sensor_failure;
} TsTotalRecords;

extern TsTotalRecords TotalRecords;

typedef enum
{
    kRecordAlarm = 0,     // at least 200
    kRecordAlarmRcy,      // at least 200
    kRecordFault,         // at least 100
    kRecordFaultRcy,      // at least 100
    kRecordPowerDown,     // at least 50
    kRecordPowerOn,       // at least 50
    kRecordSensoEndOfLife // at least 1
} TeRecord;

/*用于枚举Flash配置信息*/
typedef enum
{
    kHwVerId = 0U,
    kSwVerId,
    kAlarmLValueId,
    kAlarmHValueId,
    kIotUploadCycleId,
    kIotRetryId,
    kTempAlarmThresholdId, // 温度报警阈值
    kEmagneticSwitchId,    // 电磁阀功能开启
    kRelaySwitchId,        // 继电器功能开启
    kIotImeiId,
    kIotImsiId,
    kIotIccidId,
    kCnt
} TeFlashCfgInfoId;

/*系统配置信息*/
typedef struct __attribute__((packed))
{
    rt_uint8_t hw_ver;           // 硬件版本号
    rt_uint8_t sw_ver;           // 软件版本号
    rt_uint8_t alarm_l_value;    // 报警低阈值
    rt_uint8_t alarm_h_value;    // 报警高阈值
    rt_uint8_t temp_alarm_threshold;//温度报警阈值
    rt_uint16_t iot_upload_cycle; //IOT上传周期
    rt_uint8_t iot_retry;         // 重试次数
    rt_uint8_t emagnetic_switch;
    rt_uint8_t relay_switch;
    rt_uint8_t iot_imei[15];      // IMEI
    rt_uint8_t iot_imsi[15];      // IMSI
    rt_uint8_t iot_iccid[20];     // ICCID
} sys_config_info;

struct flash_sever_info
{
    char server_url[64];
    char server_port[8];
};
extern struct  flash_sever_info  sever_info;
void Flash_Write_Record(TeRecord record);
int Get_IotImei(char *buf, rt_size_t len);
int Get_IotImsi(char *buf, rt_size_t len);
int Get_IotIccid(char *buf, rt_size_t len);

rt_uint8_t Flash_GetNum_Records(TeRecord record);

void Flash_ErasePage_ConfigInfo(void);
void Flash_ErasePage_ReadConfigInfo(rt_uint8_t *page_buf);
int Flash_Write_ConfigInfo(rt_uint8_t *page_buf);

ErrorStatus Flash_GetProductTimeLimit(TuFlashProductTimeLimitFrame *pLimitTime,
                                      TeFlashProductTimeLimitId id);
void Flash_SetProductTimeLimit(rt_uint16_t year,
                               rt_uint8_t mon,
                               rt_uint8_t day,
                               rt_uint8_t hour,
                               rt_uint8_t min,
                               rt_uint8_t second,
                               TeFlashProductTimeLimitId id);

void Set_FactoryRtcTime(void);
void Set_ExpirationTime(rt_uint16_t days);

ErrorStatus Flash_GetTotalRecord(TsTotalRecords *pTotalRecords);
ErrorStatus Flash_GetRecord(TeFrameC2 record_type, rt_uint8_t index, TsRecordsTime *pRecordsTime);

void Flash_Erase_Records(TeRecord record);

void BSP_Flash_EraseRecodrs(void);
int BSP_Flash_Init(void);

rt_uint8_t Flash_Sys_Cfg(TeFlashCfgInfoId id, rt_uint8_t *buf, rt_size_t len);

size_t Flash_Get_SysCfg(TeFlashCfgInfoId id);
int BSP_Flash_Write_Info(rt_uint8_t *buf, rt_size_t len);
int Flash_Get_Sever_Data(struct flash_sever_info *sever_info);
int Flash_Set_Sever_Data(rt_uint8_t *data);
rt_uint16_t Flash_Get_WorkDuration(void);
int Flash_Set_WorkDuration(rt_uint16_t value);





#endif //!@__BSP_FLASH_H__
