#ifndef BL_IN_FLASH_H_
#define BL_IN_FLASH_H_

#include "flash.h"
#include "stm32g431xx.h"
#include "chargControlTypes.h"
#include "bl_usart.h"

#pragma pack(push, 1)

// /* 高字节在前,低字节在后 */
// typedef struct _recv_config_info{
//     uint8_t start_Flag[2];                  /* 开始标志 */
//     /* SL */
//     uint8_t address[7];                     /* 地址 */
//     // uint8_t Access_Node_Type[2];            /* 接入节点类型  */
//     // uint8_t Communication_Methods[2];       /* 通信方式  */
//     uint8_t gw485_Baud[4];                  /* 串口波特率 */
//     uint8_t bat485_Baud[4];                 /* 串口波特率,为0代表bms不支持通信 */

//     /* HY */
//     uint8_t hardwareID[6];                  /* 硬件ID */
//     uint8_t communicationID[4];             /* 通信ID */
//     uint8_t protocolType;                   /* 协议类型;  0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/


//     uint8_t CommunicationProtocolType;      /* 0x00:SL
//                                                0x01:HY*/
//     uint8_t onlyPower;                      /* 是否只充当电源板:0x00:不是
//                                                           0x01:是*/

//     uint8_t ConstantVoltageV[2];            /* 高于该(电压 / 100)且电流大于FloatI * 100进行恒压充电 */
//     uint8_t FloatI[2];                      /* 高于该(电压 / 100)且电流低于FloatI * 100进行浮充充电 */
//     uint8_t startSolarOpenCircuitV[2];      /* 高于该(电压 / 100)开始充电 */
//     uint8_t stopSolarOpenCircuitV[2];       /* 太阳能板开路电压高于该电压停止充电  (V) */
//     uint8_t constantVoltageChargeV[2];      /* 恒压充电时的输出电压  (V) */
//     uint8_t FloatChargeV[2];                /* 浮充充电时的输出电压  (V) */
//     uint8_t HighSideMosTemperature_stop[2]; /* 当上桥温度达到该值时,停止输出  (°C) */
//     uint8_t HighSideMosTemperature_end[2];  /* 当上桥温度上升到该值时,降低功率运行  (°C) */
//     uint8_t HighSideMosTemperature_start[2];/* 当上桥温度降低到该值时,按照正常情况输出  (°C) */

//     // uint8_t checkSolarOpenCircuitVTime[2];  /* 启动任务中太阳能板开路电压检测间隔时间  (S) */
//     // uint8_t sensorEnableBroadcastTime[2];   /* 传感器运行再次注册的间隔 (S) */
//     uint8_t outputAgainFlagTime[2];         /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出  (S) */
//     uint8_t excessiveLoadFlagTime[2];       /* 出现过载后,在该间隔时间中多次(2次)出现过载,则关闭输出  (S) */
//     uint8_t eLAgainTime[2];                 /* 出现过载过载保护后,在该间隔段时间后,再次尝试输出  (S) */
//     uint8_t crc[2];                         /* 校验 */
//     uint8_t end_Flag;                       /* 结束标志 */
// }recv_config_info;
// #define RECV_CONFIG_INFO sizeof(recv_config_info)

typedef struct _config_info{
    // /* SL */
    // uint8_t address[7];                     /* 地址 */
    // // uint16_t Access_Node_Type;              /* 接入节点类型  */
    // // uint16_t Communication_Methods;         /* 通信方式  */
    // uint32_t gw485_Baud;                    /* 串口波特率,为0代表bms不支持通信 */
    // uint32_t bat485_Baud;                   /* 串口波特率 */

    // /* HY */
    // uint8_t hardwareID[6];                  /* 硬件ID */
    // uint8_t communicationID[4];             /* 通信ID */
    // uint8_t protocolType;                   /* 协议类型;  0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/

    // uint8_t CommunicationProtocolType;      /* 0x00:SL
    //                                            0x01:HY*/
    // uint8_t onlyPower;                      /* 是否只充当电源板:0x00:不是
    //                                                       0x01:是*/

    // float constantVoltageV;                 /* 电压高于ConstantVoltageV且电流大于FloatI + 0.1)进行恒压充电 */
    // float floatI;                           /* 电压高于ConstantVoltageV且电流低于FloatI进行浮充充电 */
    // float startSolarOpenCircuitV;           /* 太阳能板开路电压高于该电压开始充电 */
    // float stopSolarOpenCircuitV;            /* 太阳能板开路电压高于该电压 停止充电 */
    // float constantVoltageChargeV;           /* 恒压充电时的输出电压 */
    // float FloatChargeV;                     /* 浮充电压 */
    // float HighSideMosTemperature_stop;      /* 当上桥温度达到该值时,停止输出 */
    // float HighSideMosTemperature_end;       /* 当上桥温度上升到该值时,降低功率运行 */
    // float HighSideMosTemperature_start;     /* 当上桥温度降低到该值时,按照正常情况输出 */

    // // uint16_t checkSolarOpenCircuitVTime;    /* 启动任务中太阳能板开路电压检测时间 */
    // // uint16_t sensorEnableBroadcastTime;     /* 传感器运行再次注册的间隔 */
    // uint16_t outputAgainFlagTime;           /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出 */
    // uint16_t excessiveLoadFlagTime;         /* 出现过载后,在该段时间中再次出现过载,则关闭输出 */
    // uint16_t eLAgainTime;                   /* 出现过载过载保护后,该段时间后,再次尝试输出 */

    uint8_t uniqueDeviceID[7];                      /* 设备唯一ID */
    uint32_t gw485_Baud;                            /* 串口波特率 */
    uint32_t bat485_Baud;                           /* 串口波特率,为0代表bms不支持通信 */    
    uint8_t powerBoxType;                           /* 是否只充当电源板:0x00:不是;0x01:是*/
    float constantVoltageV;                         /* 恒压充电阈值电压(V) */
    float floatI;                                   /* 浮充充电阈值电流(A) */
    float startSolarOpenCircuitV;                   /* 启动充电太阳能板开路电压(V) */
    float stopSolarOutputCircuitV;                  /* 停止充电太阳能板输出电压(V) */
    uint16_t checkCanStartTime;                     /* 检测能否启动间隔时间(S) */
    uint16_t shortCircuitJudgmentDelay;             /* 短路判断延时(S) */
    uint16_t inputPowerLowJudgmentDelay;            /* 前端输入功率不足判断延时(S) */
    uint16_t inputPowerLowAgainOutputDelay;         /* 前端输入功率不足再次输出延时(S) */
    uint16_t firstStageProtectionDelay;             /* 第一段保护延时(10uS) */
    float firstStageProtectionCurr;                 /* 第一段保护电流(A) */
    uint16_t secondStageProtectionDelay;            /* 第二段保护延时(100uS) */
    float secondStageProtectionCurr;                /* 第二段保护电流(A) */
    uint32_t thirdStageProtectionDelay;             /* 第三段保护延时(100uS) */
    float thirdStageProtectionCurr;                 /* 第三段保护电流(A) */
    uint16_t inputPowerLowDetectionDelay;           /* 前端输入功率不足检测延时(100uS) */
    float inputPowerLowDetectionVolt;               /* 前端输入功率不足检测电压(V) */
    float maxOpenSolarOutputCircuitV;               /* 最大太阳能板输出电压(V) */
    float maxChargCurr;                             /* 最大充电电流(A) */
    float minCheckLoopImpedanceChargCurr;           /* 检测回路阻抗时的最小充电电流(A) */
    float fullPowerOutputTemperature;               /* 满功率输出温度(℃) */
    float reducePowerOutputTemperature;             /* 降功率输出温度(℃) */
    float stopPowerOutputTemperature;               /* 停止输出温度(℃) */
    float constantVoltageChargeV;                   /* 恒压充电时的输出电压(V) */
    float FloatChargeV;                             /* 浮充充电时的输出电压(V) */
    uint16_t collectOpenCircuitVoltageTime;         /* 充电时采集开路电压的间隔时间 */
    
    uint16_t crc;                                   /* 校验 */
}config_info;
#define CONFIG_INFO_SIZE    (sizeof(config_info))
// typedef struct _other_info {
//     float loopImpedance;
//     float totalElectricityConsumption;
//     float totalChargCapacity;
//     float lastTime;
// }other_info;
// #define OTHER_INFO_SIZE    (sizeof(other_info))

#pragma pack(pop)

#define CONFIG_SAVE_addr                        (0)
#define CONFIG_SAVE_ADDR_BEGIN                  (CONFIG_INFO_SIZE)
#define CONFIG_SAVE_ADDR_END                    (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE)
#define LoopImpedance_SAVE_addr                 (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 10)
#define totalElectricityConsumption_SAVE_addr   (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 20)
#define totalChargCapacity_SAVE_addr            (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 30)
#define time_SAVE_addr                          (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 40)

// #define LoopImpedance_SAVE_addr                 (4096)
// #define totalElectricityConsumption_SAVE_addr   (LoopImpedance_SAVE_addr + 4)
// #define totalChargCapacity_SAVE_addr            (LoopImpedance_SAVE_addr + 8)
// #define time_SAVE_addr                          (LoopImpedance_SAVE_addr + 12)


// void save_config_info(config_info *save_config_info);
void read_config_info(config_info *output_config_info);
void saveConfigInfo(config_info *config_info);
void config_info_start(void);
void readFlashContent(config_info *configInfo);
void cfgTest(void);

void saveLoopImpedance();
BOOL readLoopImpedance();
void savetotalElectricityConsumption(float *totalElectricityConsumption);
void readtotalElectricityConsumption(float *totalElectricityConsumption);
void savetotalChargCapacity(float *totalChargCapacity);
void readtotalChargCapacity(float *totalChargCapacity);
void saveTime(timeInfo *time);
void readTime(timeInfo *time);
// void saveOtherInfo(other_info *otherInfo);
// void readOtherInfo(other_info *otherInfo);



#endif