/*
 * inflash.c
 *
 *  Created on: 2024年6月24日
 *      Author: psx
 */

#include "inflash.h"
#include "flash.h"
#include "sl_protocol.h"
#include "parameter.h"
#include <string.h>

/**
  * @brief  校验算法
  * @param
  * @retval
  */
uint16_t configCheckFunc(uint8_t *arr_buff, uint8_t len)
{
    uint16_t crc = 0xFFFF;
    uint16_t i, j;
    for (j = 0; j < len; ++j) {
        crc = crc ^ (*arr_buff++);
        for (i = 0; i < 8; ++i) {
            if ((crc&0x0001) > 0) {
                crc = crc >> 1;
                crc = crc ^ 0xa001;
            }
            else {
                crc = crc >> 1;
            }
        }
    }
    return crc;
}

/**
 * @brief   保存配置信息
 * @param   save_config_info 需要保存的配置信息
 * @retval
 */
void save_config_info(config_info *save_config_info)
{
    SPI_Flash_Write((uint8_t *)save_config_info, CONFIG_SAVE_ADDR_BEGIN, CONFIG_INFO_SIZE);
}

/**
 * @brief   保存配置信息到备份区
 * @param   save_config_info 需要保存的配置信息
 * @retval
 */
static void save_backups_config_info(config_info *save_config_info)
{
    SPI_Flash_Write((uint8_t *)save_config_info, CONFIG_SAVE_addr, CONFIG_INFO_SIZE);
}

/**
 * @brief   读取配置信息
 * @param   read_config_info 读取配置信息并保存在output_config_info中
 */
void read_config_info(config_info *output_config_info)
{
    SPI_Flash_Read((uint8_t *)output_config_info, CONFIG_SAVE_ADDR_BEGIN, CONFIG_INFO_SIZE);
}

/**
 * @brief   读取备份的配置信息
 * @param   read_config_info 读取配置信息并保存在output_config_info中
 */
static void read_backups_config_info(config_info *output_config_info)
{
    SPI_Flash_Read((uint8_t *)output_config_info, CONFIG_SAVE_addr, CONFIG_INFO_SIZE);
}

/**
 * @brief   检测flash中是否有配置文件或者文件是否有损坏，损坏了就将备份的配置文件读出，没有则将默认配置保存在其中
 * @param   read_config_info1 读取的配置信息并保存在in_config_info中
 * @retval
 *
 */
void checkFlashContent(void)
{
    config_info temp_configInfo;
    read_config_info(&temp_configInfo);


    /* 配置文件正确就返回 */
//    printf("crc : %x %x\n", temp_configInfo.crc, configCheckFunc((uint8_t *)&temp_configInfo, CONFIG_INFO_SIZE - 2));
    if (temp_configInfo.crc == configCheckFunc((uint8_t *)&temp_configInfo, CONFIG_INFO_SIZE - 2)) {
//        printf("config\n");
        return;
    }

    /* 更深处的配置文件正确就返回 */
    read_backups_config_info(&temp_configInfo);
    if (temp_configInfo.crc == configCheckFunc((uint8_t *)&temp_configInfo, CONFIG_INFO_SIZE - 2)) {
//        printf("backups config\n");
        save_config_info(&temp_configInfo);
        return;
    }


    /* 配置文件错误使用默认配置 */
    config_info configInfo = {
            .address = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
            .Access_Node_Type = 0x01,
            .Communication_Methods = 0x02,
            .gw485_Baud = 9600,
            .bat485_Baud = 115200,

            .hardwareID = {0x48, 0x59, 0x30, 0x30, 0x30, 0x31},
            .communicationID = {0x00, 0x00, 0x00, 0x01},
            .protocolType = 0x01,

            .CommunicationProtocolType = 0x00,
            .onlyPower = 0x01,

            .constantVoltageV = 14,
            .floatI = 0.02,
            .startSolarOpenCircuitV = 17,
            .stopSolarOpenCircuitV = 15,
            .constantVoltageChargeV = 14.4,
            .FloatChargeV = 14,
            .HighSideMosTemperature_stop = 100,
            .HighSideMosTemperature_end = 90,
            .HighSideMosTemperature_start = 50,
//            .loopImpedance = 0.0,
//            .totalElectricityConsumption = 0.0,
//            .totalChargCapacity = 0.0,

            .checkSolarOpenCircuitVTime = 10,
//            .registerRefreshTime = 1,
            .sensorEnableBroadcastTime = 20,
            .outputAgainFlagTime = 10,
            .excessiveLoadFlagTime = 60,
            .eLAgainTime = 1800,
    };

    configInfo.crc = configCheckFunc((uint8_t *)&configInfo, CONFIG_INFO_SIZE - 2);

    save_config_info(&configInfo);
}

///**
// * @brief   保存回路阻抗的值
// * @param   loopImpedance 需要保存的回路阻抗的值
// * @retval
// *
// */
//void saveLoopImpedance(float_t *loopImpedance)
//{
//    config_info temp_configInfo;
//    read_config_info(&temp_configInfo);
//
//    temp_configInfo.loopImpedance = *loopImpedance;
//
//    temp_configInfo.crc = configCheckFunc((uint8_t *)&temp_configInfo, CONFIG_INFO_SIZE - 2);
//    save_config_info(&temp_configInfo);
//}
//
///**
// * @brief   保存总充电电量和总消耗电量的值
// * @param   totalElectricityConsumption 需要保存的总消耗电量
// *          totalChargCapacity          需要保存的总充电电量
// * @retval
// *
// */
//void saveTotalPower(float_t *totalElectricityConsumption, float_t *totalChargCapacity)
//{
//    config_info temp_configInfo;
//    read_config_info(&temp_configInfo);
//
//    temp_configInfo.totalElectricityConsumption = *totalElectricityConsumption;
//    temp_configInfo.totalChargCapacity = *totalChargCapacity;
//
//    temp_configInfo.crc = configCheckFunc((uint8_t *)&temp_configInfo, CONFIG_INFO_SIZE - 2);
//    save_config_info(&temp_configInfo);
//}

/**
 * @brief   读取配置文件初始化各参数
 * @param
 * @retval
 *
 */
void config_info_start(void)
{
    checkFlashContent();

    /* 读取配置文件并将需要的参数保存在全局变量中 */
    config_info temp_configInfo;
    read_config_info(&temp_configInfo);

    g_controlParameter.constantVoltageV             = temp_configInfo.constantVoltageV;
    g_controlParameter.floatI                       = temp_configInfo.floatI;
    g_controlParameter.startSolarOpenCircuitV       = temp_configInfo.startSolarOpenCircuitV;
    g_controlParameter.stopSolarOpenCircuitV        = temp_configInfo.stopSolarOpenCircuitV;
    g_controlParameter.constantVoltageChargeV       = temp_configInfo.constantVoltageChargeV;
    g_controlParameter.FloatV                       = temp_configInfo.FloatChargeV;
//    g_controlParameter.loopImpedance                = temp_configInfo.loopImpedance;
    g_controlParameter.HighSideMosTemperature_stop  = temp_configInfo.HighSideMosTemperature_stop;
    g_controlParameter.HighSideMosTemperature_end   = temp_configInfo.HighSideMosTemperature_end;
    g_controlParameter.HighSideMosTemperature_start = temp_configInfo.HighSideMosTemperature_start;
    g_controlParameter.sensorEnableBroadcastTime    = temp_configInfo.sensorEnableBroadcastTime;
    g_controlParameter.checkSolarOpenCircuitVTime   = temp_configInfo.checkSolarOpenCircuitVTime;
    g_controlParameter.outputAgainFlagTime          = temp_configInfo.outputAgainFlagTime;
    g_controlParameter.excessiveLoadFlagTime        = temp_configInfo.excessiveLoadFlagTime;
    g_controlParameter.eLAgainTime                  = temp_configInfo.eLAgainTime;
    g_controlParameter.collectOpenCircuitVoltageTime= 3600;

//    strlcpy(g_otherParameter.address, temp_configInfo.address, 7);
    g_otherParameter.address[0] = temp_configInfo.address[0];
    g_otherParameter.address[1] = temp_configInfo.address[1];
    g_otherParameter.address[2] = temp_configInfo.address[2];
    g_otherParameter.address[3] = temp_configInfo.address[3];
    g_otherParameter.address[4] = temp_configInfo.address[4];
    g_otherParameter.address[5] = temp_configInfo.address[5];
    g_otherParameter.address[6] = temp_configInfo.address[6];
//    printf("address : 0x %x %x %x %x %x %x %x\n", temp_configInfo.address[0]
//            , temp_configInfo.address[1], temp_configInfo.address[2], temp_configInfo.address[3]
//            , temp_configInfo.address[4], temp_configInfo.address[5], temp_configInfo.address[6]);
    g_otherParameter.Access_Node_Type               = temp_configInfo.Access_Node_Type;
    g_otherParameter.Communication_Methods          = temp_configInfo.Communication_Methods;
//    strlcpy(g_otherParameter.hardwareID, temp_configInfo.hardwareID, 6);
    g_otherParameter.hardwareID[0] = temp_configInfo.hardwareID[0];
    g_otherParameter.hardwareID[1] = temp_configInfo.hardwareID[1];
    g_otherParameter.hardwareID[2] = temp_configInfo.hardwareID[2];
    g_otherParameter.hardwareID[3] = temp_configInfo.hardwareID[3];
    g_otherParameter.hardwareID[4] = temp_configInfo.hardwareID[4];
    g_otherParameter.hardwareID[5] = temp_configInfo.hardwareID[5];
//    strlcpy(g_otherParameter.communicationID, temp_configInfo.communicationID, 4);
    g_otherParameter.communicationID[0] = temp_configInfo.communicationID[0];
    g_otherParameter.communicationID[1] = temp_configInfo.communicationID[1];
    g_otherParameter.communicationID[2] = temp_configInfo.communicationID[2];
    g_otherParameter.communicationID[3] = temp_configInfo.communicationID[3];
    g_otherParameter.protocolType       = temp_configInfo.protocolType;
    g_otherParameter.CommunicationProtocolType      = temp_configInfo.CommunicationProtocolType;
//    g_otherParameter.CommunicationProtocolType      = 0x01;
    g_otherParameter.onlyPower                      = temp_configInfo.onlyPower;
    g_otherParameter.Battery_Voltage                = 0;
    g_otherParameter.Output_Voltage                 = 0;
    g_otherParameter.Charg_Current                  = 0;
    g_otherParameter.Discharg_Current               = 0;
    g_otherParameter.Input_Voltage                  = 0;
    g_otherParameter.Solar_Open_Circuit_Voltage     = 0;
    g_otherParameter.HighSideMos_Temperature        = 0;
    g_otherParameter.Solar_In_Circuit_Voltage       = 0;
    g_otherParameter.Charg_BatteryCurrent           = 0;
//    g_otherParameter.totalElectricityConsumption    = temp_configInfo.totalElectricityConsumption;
//    g_otherParameter.totalChargCapacity             = temp_configInfo.totalChargCapacity;
    g_otherParameter.SOC                            = 0;
    g_otherParameter.chargMos_State                 = 0;
    g_otherParameter.DischargMos_State              = 0;
    g_otherParameter.MPPT_Mode                      = 0;
    strlcpy(g_otherParameter.versionInformation, softVer, 13);

//    strlcpy(g_otherParameter.startFlagSL, "SL", 2);
//    printf("%s", g_otherParameter.startFlagSL);
    g_otherParameter.startFlagSL[0] = 'S';
    g_otherParameter.startFlagSL[1] = 'L';


    g_otherParameter.endFlagSL                      = 0x16;
    g_otherParameter.startFlagHY                    = 0x68;
    g_otherParameter.endFlagHY                      = 0x16;

    g_otherParameter.batteryState                   = 0;
    g_otherParameter.impedanceStart                 = 1;
    g_otherParameter.overTemperature                = 0;
    g_otherParameter.RegistrationRequestFlag        = 0;
    g_otherParameter.runBroadcast                   = 1;
    g_otherParameter.RegisterNumberMax              = 10;
    g_otherParameter.RegisterStartAddressMax        = 0x150;

    g_otherParameter.HYconfigModeState              = 0;
    g_otherParameter.HYconfigModeT                  = 0;

    if (g_otherParameter.CommunicationProtocolType == 0x00) {
        g_otherParameter.gw485_Baud                 = temp_configInfo.gw485_Baud;
        g_otherParameter.bat485_Baud                = temp_configInfo.bat485_Baud;
    } else if (g_otherParameter.CommunicationProtocolType == 0x01) {
        g_otherParameter.bat485_Baud                = temp_configInfo.bat485_Baud;
        if (g_otherParameter.protocolType == 0x01) {
            g_otherParameter.gw485_Baud             = 9600;
        } else if (g_otherParameter.protocolType == 0x02) {
            g_otherParameter.gw485_Baud             = 115200;
        }
    }

//    readLoopImpedance(&g_controlParameter.loopImpedance);
    float_t fTemp;
    readLoopImpedance(&fTemp);
    /* 读取的回路阻抗偏差过大则不使用 */
    if (fTemp > 0.005 && fTemp < 1) {
        g_controlParameter.loopImpedance = fTemp;
    }
    else {
        g_controlParameter.loopImpedance = 0;
        saveLoopImpedance(&g_controlParameter.loopImpedance);
    }
    readtotalElectricityConsumption(&g_otherParameter.totalElectricityConsumption);
    readtotalChargCapacity(&g_otherParameter.totalChargCapacity);

//    printf("");

    printf("%s\n", g_otherParameter.versionInformation);
    printf("address : 0x %x %x %x %x %x %x %x\n", g_otherParameter.address[0]
            , g_otherParameter.address[1], g_otherParameter.address[2], g_otherParameter.address[3]
            , g_otherParameter.address[4], g_otherParameter.address[5], g_otherParameter.address[6]);
    printf("Access_Node_Type : 0x%x\n", g_otherParameter.Access_Node_Type);
    printf("Communication_Methods : 0x%x\n", g_otherParameter.Communication_Methods);
    printf("gw485_Baud : %d\n", g_otherParameter.gw485_Baud);
    printf("bat485_Baud : %d\n", g_otherParameter.bat485_Baud);
    printf("hardwareID : 0x %x %x %x %x %x %x\n", g_otherParameter.hardwareID[0]
            , g_otherParameter.hardwareID[1], g_otherParameter.hardwareID[2], g_otherParameter.hardwareID[3]
            , g_otherParameter.hardwareID[4], g_otherParameter.hardwareID[5]);
    printf("communicationID : 0x %x %x %x %x\n", g_otherParameter.communicationID[0], g_otherParameter.communicationID[1]
                                               , g_otherParameter.communicationID[2], g_otherParameter.communicationID[3]);
    printf("Communication_Methods : 0x%x\n", g_otherParameter.CommunicationProtocolType);
    printf("onlyPower : 0x%x\n", g_otherParameter.onlyPower);

    printf("constantVoltageV : %d/100\n", (int)(g_controlParameter.constantVoltageV * 100));
    printf("floatI : %d/100\n", (int)(g_controlParameter.floatI * 100));
    printf("startSolarOpenCircuitV : %d/100\n", (int)(g_controlParameter.startSolarOpenCircuitV * 100));
    printf("stopSolarOpenCircuitV : %d/100\n", (int)(g_controlParameter.stopSolarOpenCircuitV * 100));
    printf("constantVoltageChargeV : %d/100\n", (int)(g_controlParameter.constantVoltageChargeV * 100));
    printf("FloatV : %d/100\n", (int)(g_controlParameter.FloatV * 100));
    printf("loopImpedance : %d/100\n", (int)(g_controlParameter.loopImpedance * 100));
    printf("HighSideMosTemperature_stop : %d/100\n", (int)(g_controlParameter.HighSideMosTemperature_stop * 100));
    printf("HighSideMosTemperature_end : %d/100\n", (int)(g_controlParameter.HighSideMosTemperature_end * 100));
    printf("HighSideMosTemperature_start : %d/100\n", (int)(g_controlParameter.HighSideMosTemperature_start * 100));
    printf("totalChargCapacity : %d/10000\n", (int)(g_otherParameter.totalChargCapacity * 10000));
    printf("totalElectricityConsumption : %d/10000\n", (int)(g_otherParameter.totalElectricityConsumption * 10000));

    printf("checkSolarOpenCircuitVTime : %d\n", g_controlParameter.checkSolarOpenCircuitVTime);
    printf("sensorEnableBroadcastTime : %d\n", g_controlParameter.sensorEnableBroadcastTime);
    printf("outputAgainFlagTime : %d\n", g_controlParameter.outputAgainFlagTime);
    printf("excessiveLoadFlagTime : %d\n", g_controlParameter.excessiveLoadFlagTime);
    printf("eLAgainTime : %d\n", g_controlParameter.eLAgainTime);
}

/**
 * @brief   判断接收到的配置文件数据是否正确，正确的话存入flash中
 * @param
 * @retval
 *
 */
#define enlargeScale 100
void read_and_process_config_data(void)
{
    recv_config_info *pack = (recv_config_info *)config_buff;
    config_info save_configInfo;
//    uint32_t len = strlen(config_buff);
//    char buffer[80];
//    printf("%d %d\n", cfig_len, RECV_CONFIG_INFO);
    while (cfig_len >= RECV_CONFIG_INFO) {
//        printf("1\n");
        /* 判断起始标志是否正确 */
        if (pack->start_Flag[0] != g_otherParameter.startFlagSL[0]
                || pack->start_Flag[1] != g_otherParameter.startFlagSL[1]) {
//            printf(" start_Flag : 0x%x, 0x%x \n", pack->start_Flag[0], pack->start_Flag[1]);
            goto err;
        }
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " start_Flag : 0x%x, 0x%x \n", pack->start_Flag[0], pack->start_Flag[1]);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));

//        if (pack->address[0] != g_otherParameter.address[0]
//                || pack->address[1] != g_otherParameter.address[1]
//                || pack->address[2] != g_otherParameter.address[2]
//                || pack->address[3] != g_otherParameter.address[3]
//                || pack->address[4] != g_otherParameter.address[4]
//                || pack->address[5] != g_otherParameter.address[5]
//                || pack->address[6] != g_otherParameter.address[6]) {
//            memcpy(config_buff, config_buff + 1, RECV_CONFIG_INFO - 1);
//            continue;
//        }

        /* 判断接入节点类型是否正确 */
        save_configInfo.Access_Node_Type = (uint16_t)pack->Access_Node_Type[0] << 8
                                            | (uint16_t)pack->Access_Node_Type[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " Access_Node_Type : 0x%x \n", save_configInfo.Access_Node_Type);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.Access_Node_Type != POWERBOX) {
            goto err;
        }

        /* 判断通信方式是否正确 */
        save_configInfo.Communication_Methods = (uint16_t)pack->Communication_Methods[0] << 8
                                                | (uint16_t)pack->Communication_Methods[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " Communication_Methods : 0x%x \n", save_configInfo.Communication_Methods);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
//        if (temp_u16 != RS485 || temp_u16 != RJ45) {
        if (save_configInfo.Communication_Methods != RS485) {
            goto err;
        }

        /* 判断波特率是否正确 */
        save_configInfo.gw485_Baud = (uint32_t)pack->gw485_Baud[0] << 24
                                    | (uint32_t)pack->gw485_Baud[1] << 16
                                    | (uint32_t)pack->gw485_Baud[2] << 8
                                    | (uint32_t)pack->gw485_Baud[3];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " gw485_Baud : 0x%x, %d \n", save_configInfo.gw485_Baud, save_configInfo.gw485_Baud);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.gw485_Baud != 9600 && save_configInfo.gw485_Baud != 115200) {
//        if (save_configInfo.gw485_Baud != 0x2580 || save_configInfo.gw485_Baud != 115200) {
//            memset(buffer, 0, sizeof(buffer));
//            sprintf(buffer, " error : %d\n", save_configInfo.gw485_Baud);
//            uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
            goto err;
        }

        save_configInfo.bat485_Baud = (uint32_t)pack->bat485_Baud[0] << 24
                                    | (uint32_t)pack->bat485_Baud[1] << 16
                                    | (uint32_t)pack->bat485_Baud[2] << 8
                                    | (uint32_t)pack->bat485_Baud[3];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " bat485_Baud : 0x%x, %d \n", save_configInfo.bat485_Baud, save_configInfo.bat485_Baud);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.bat485_Baud != 9600 && save_configInfo.bat485_Baud!= 115200 && save_configInfo.bat485_Baud!= 0) {
            goto err;
        }

        /* 判断协议类型是否正确 */
        if (pack->protocolType != 0x01 && pack->protocolType != 0x02) {
            goto err;
        }
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " protocolType : 0x%x \n", pack->protocolType);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));

        /* 判断通信协议类型是否正确 */
        if (pack->CommunicationProtocolType != 0x00 && pack->CommunicationProtocolType != 0x01) {
            goto err;
        }
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " CommunicationProtocolType : 0x%x \n", pack->CommunicationProtocolType);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));

        /* 判断电源盒类型是否正确 */
        if (pack->onlyPower != 0x00 && pack->onlyPower != 0x01) {
            goto err;
        }
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " onlyPower : 0x%x \n", pack->onlyPower);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));

        /* 判断恒压充电阈值是否正确 */
        save_configInfo.constantVoltageV =
                (float_t)(pack->ConstantVoltageV[0] << 8 | pack->ConstantVoltageV[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " constantVoltageV : %d/100 \n", (int)(save_configInfo.constantVoltageV * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.constantVoltageV > 14.4 || save_configInfo.constantVoltageV < 13.5) {
            goto err;
        }

        /* 判断浮充充电阈值是否正确 */
        save_configInfo.floatI = (float_t)(pack->FloatI[0] << 8 | pack->FloatI[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " floatI : %d/100 \n", (int)(save_configInfo.floatI * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.floatI > 0.2 || save_configInfo.floatI < 0) {
            goto err;
        }

        /* 判断太阳能板开路启动电压是否正确 */
        save_configInfo.startSolarOpenCircuitV =
                (float_t)(pack->startSolarOpenCircuitV[0] << 8 | pack->startSolarOpenCircuitV[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " startSolarOpenCircuitV : %d/100 \n", (int)(save_configInfo.startSolarOpenCircuitV * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.startSolarOpenCircuitV > 24 || save_configInfo.startSolarOpenCircuitV < 14) {
            goto err;
        }

        /* 判断太阳能板关闭电压是否正确 */
        save_configInfo.stopSolarOpenCircuitV =
                (float_t)(pack->stopSolarOpenCircuitV[0] << 8 | pack->stopSolarOpenCircuitV[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " stopSolarOpenCircuitV : %d/100 \n", (int)(save_configInfo.stopSolarOpenCircuitV * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.stopSolarOpenCircuitV > 17 || save_configInfo.stopSolarOpenCircuitV < 13) {
            goto err;
        }

        /* 判断恒压充电时的输出电压是否正确 */
        save_configInfo.constantVoltageChargeV =
                (float_t)(pack->constantVoltageChargeV[0] << 8 | pack->constantVoltageChargeV[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " constantVoltageChargeV : %d/100 \n", (int)(save_configInfo.constantVoltageChargeV * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.constantVoltageChargeV > 14.6 || save_configInfo.constantVoltageChargeV < 14) {
            goto err;
        }

        /* 判断浮充充电时的输出电压是否正确 */
        save_configInfo.FloatChargeV =
                (float_t)(pack->FloatChargeV[0] << 8 | pack->FloatChargeV[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " FloatChargeV : %d/100 \n", (int)(save_configInfo.FloatChargeV * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.FloatChargeV > 14.4 || save_configInfo.FloatChargeV < 13.8) {
            goto err;
        }

        /* 判断mos管停止工作温度是否正确 */
        save_configInfo.HighSideMosTemperature_stop =
                (float_t)(pack->HighSideMosTemperature_stop[0] << 8 | pack->HighSideMosTemperature_stop[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " HighSideMosTemperature_stop : %d/100 \n", (int)(save_configInfo.HighSideMosTemperature_stop * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.HighSideMosTemperature_stop < 60) {
            goto err;
        }

        /* 判断mos管降低工作功率工作温度是否正确 */
        save_configInfo.HighSideMosTemperature_end =
                (float_t)(pack->HighSideMosTemperature_end[0] << 8 | pack->HighSideMosTemperature_end[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " HighSideMosTemperature_end : %d/100 \n", (int)(save_configInfo.HighSideMosTemperature_end * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.HighSideMosTemperature_end < 50) {
            goto err;
        }

        /* 判断mos管完全恢复工作温度是否正确 */
        save_configInfo.HighSideMosTemperature_start =
                (float_t)(pack->HighSideMosTemperature_start[0] << 8 | pack->HighSideMosTemperature_start[1]) / enlargeScale;
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " HighSideMosTemperature_start : %d/100 \n", (int)(save_configInfo.HighSideMosTemperature_start * 100));
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.HighSideMosTemperature_start < 40) {
            goto err;
        }

//        /* 判断回路阻抗大小是否正确 */
//        save_configInfo.loopImpedance =
//                (float_t)(pack->loopImpedance[0] << 8 | pack->loopImpedance[1]) / enlargeScale / 10;
////        memset(buffer, 0, sizeof(buffer));
////        sprintf(buffer, " loopImpedance : %d/100 \n", (int)(save_configInfo.loopImpedance * 100));
////        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
//        if (save_configInfo.loopImpedance > 1 || save_configInfo.loopImpedance < 0) {
//            goto err;
//        }
//
//        /* 判断总电量消耗是否正确 */
//        save_configInfo.totalElectricityConsumption =
//                (float_t)(pack->totalElectricityConsumption[0] << 8 | pack->totalElectricityConsumption[1]) / enlargeScale;
////        memset(buffer, 0, sizeof(buffer));
////        sprintf(buffer, " totalElectricityConsumption : %d/100 \n", (int)(save_configInfo.totalElectricityConsumption * 100));
////        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
//        if (save_configInfo.totalElectricityConsumption != 0) {
//            goto err;
//        }
//
//        /* 判断总充电电量是否正确 */
//        save_configInfo.totalChargCapacity =
//                (float_t)(pack->totalChargCapacity[0] << 8 | pack->totalChargCapacity[1]) / enlargeScale;
////        memset(buffer, 0, sizeof(buffer));
////        sprintf(buffer, " totalChargCapacity : %d/100 \n", (int)(save_configInfo.totalChargCapacity * 100));
////        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
//        if (save_configInfo.totalChargCapacity != 0) {
//            goto err;
//        }

        /* 判断启动任务中太阳能板开路电压检测间隔时间是否正确 */
        save_configInfo.checkSolarOpenCircuitVTime =
                pack->checkSolarOpenCircuitVTime[0] << 8 | pack->checkSolarOpenCircuitVTime[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " checkSolarOpenCircuitVTime : %d \n", save_configInfo.checkSolarOpenCircuitVTime);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.checkSolarOpenCircuitVTime > 1800 || save_configInfo.checkSolarOpenCircuitVTime < 5) {
            goto err;
        }

        /* 判断传感器运行再次注册的间隔是否正确 */
        save_configInfo.sensorEnableBroadcastTime =
                pack->sensorEnableBroadcastTime[0] << 8 | pack->sensorEnableBroadcastTime[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " sensorEnableBroadcastTime : %d \n", save_configInfo.sensorEnableBroadcastTime);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.sensorEnableBroadcastTime > 60 || save_configInfo.sensorEnableBroadcastTime < 10) {
            goto err;
        }

        /* 判断出现短路保护后延长该段时间再次检测是否短路，仍然短路则关闭输出的间隔是否正确 */
        save_configInfo.outputAgainFlagTime =
                pack->outputAgainFlagTime[0] << 8 | pack->outputAgainFlagTime[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " outputAgainFlagTime : %d \n", save_configInfo.outputAgainFlagTime);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.sensorEnableBroadcastTime > 30 || save_configInfo.sensorEnableBroadcastTime < 5) {
            goto err;
        }

        /* 判断出现过载后，在该间隔时间中多次（2次）出现过载，则关闭输出的间隔是否正确 */
        save_configInfo.excessiveLoadFlagTime =
                pack->excessiveLoadFlagTime[0] << 8 | pack->excessiveLoadFlagTime[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " excessiveLoadFlagTime : %d \n", save_configInfo.excessiveLoadFlagTime);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.excessiveLoadFlagTime > 90 || save_configInfo.excessiveLoadFlagTime < 30) {
            goto err;
        }

        /* 判断出现过载过载保护后，在该间隔段时间后，再次尝试输出的间隔是否正确 */
        save_configInfo.eLAgainTime = pack->eLAgainTime[0] << 8 | pack->eLAgainTime[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " eLAgainTime : %d \n", save_configInfo.eLAgainTime);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.eLAgainTime > 3000 || save_configInfo.eLAgainTime < 1000) {
            goto err;
        }

        /* crc校验 */
        save_configInfo.crc = pack->crc[0] << 8 | pack->crc[1];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " crc : %x%x \n", pack->crc[0], pack->crc[1]);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (save_configInfo.crc != CheckFuncSL(config_buff, RECV_CONFIG_INFO - 3)) {
//            memset(buffer, 0, sizeof(buffer));
//            sprintf(buffer, " CheckFuncSL : %x \n", CheckFuncSL(config_buff, RECV_CONFIG_INFO));
//            uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
            goto err;
        }


        /* 结束标志 */
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " end_Flag : %x \n", pack->end_Flag);
//        uart_dev_write(g_gw485_uart4_handle, buffer, sizeof(buffer));
        if (pack->end_Flag != 0x16) {
            goto err;
        }

//        printf("address : 0x %x %x %x %x %x %x %x\n", pack->address[0]
//                , pack->address[1], pack->address[2], pack->address[3]
//                , pack->address[4], pack->address[5], pack->address[6]);
        config_info temp_configInfo;
        read_config_info(&temp_configInfo);

        if (pack->address[0] != 0xFF
            || pack->address[1] != 0xFF
            || pack->address[2] != 0xFF
            || pack->address[3] != 0xFF
            || pack->address[4] != 0xFF
            || pack->address[5] != 0xFF
            || pack->address[6] != 0xFF) {
            save_configInfo.address[0]          = pack->address[0];
            save_configInfo.address[1]          = pack->address[1];
            save_configInfo.address[2]          = pack->address[2];
            save_configInfo.address[3]          = pack->address[3];
            save_configInfo.address[4]          = pack->address[4];
            save_configInfo.address[5]          = pack->address[5];
            save_configInfo.address[6]          = pack->address[6];
//            printf("address : 0x %x %x %x %x %x %x %x\n", save_configInfo.address[0]
//                    , save_configInfo.address[1], save_configInfo.address[2], save_configInfo.address[3]
//                    , save_configInfo.address[4], save_configInfo.address[5], save_configInfo.address[6]);
        } else {
            save_configInfo.address[0]          = temp_configInfo.address[0];
            save_configInfo.address[1]          = temp_configInfo.address[1];
            save_configInfo.address[2]          = temp_configInfo.address[2];
            save_configInfo.address[3]          = temp_configInfo.address[3];
            save_configInfo.address[4]          = temp_configInfo.address[4];
            save_configInfo.address[5]          = temp_configInfo.address[5];
            save_configInfo.address[6]          = temp_configInfo.address[6];
        }

        if (pack->hardwareID[0] != 0xFF
            || pack->hardwareID[1] != 0xFF
            || pack->hardwareID[2] != 0xFF
            || pack->hardwareID[3] != 0xFF
            || pack->hardwareID[4] != 0xFF
            || pack->hardwareID[5] != 0xFF) {
            save_configInfo.hardwareID[0]       = pack->hardwareID[0];
            save_configInfo.hardwareID[1]       = pack->hardwareID[1];
            save_configInfo.hardwareID[2]       = pack->hardwareID[2];
            save_configInfo.hardwareID[3]       = pack->hardwareID[3];
            save_configInfo.hardwareID[4]       = pack->hardwareID[4];
            save_configInfo.hardwareID[5]       = pack->hardwareID[5];
        } else {
            save_configInfo.hardwareID[0]       = temp_configInfo.hardwareID[0];
            save_configInfo.hardwareID[1]       = temp_configInfo.hardwareID[1];
            save_configInfo.hardwareID[2]       = temp_configInfo.hardwareID[2];
            save_configInfo.hardwareID[3]       = temp_configInfo.hardwareID[3];
            save_configInfo.hardwareID[4]       = temp_configInfo.hardwareID[4];
            save_configInfo.hardwareID[5]       = temp_configInfo.hardwareID[5];
        }

        if (pack->communicationID[0] != 0xFF
            || pack->communicationID[1] != 0xFF
            || pack->communicationID[2] != 0xFF
            || pack->communicationID[3] != 0xFF) {
            save_configInfo.communicationID[0]  = pack->communicationID[0];
            save_configInfo.communicationID[1]  = pack->communicationID[1];
            save_configInfo.communicationID[2]  = pack->communicationID[2];
            save_configInfo.communicationID[3]  = pack->communicationID[3];
        } else {
            save_configInfo.communicationID[0]  = temp_configInfo.communicationID[0];
            save_configInfo.communicationID[1]  = temp_configInfo.communicationID[1];
            save_configInfo.communicationID[2]  = temp_configInfo.communicationID[2];
            save_configInfo.communicationID[3]  = temp_configInfo.communicationID[3];
        }

        save_configInfo.protocolType        = pack->protocolType;

        save_configInfo.CommunicationProtocolType = pack->CommunicationProtocolType;

        save_configInfo.onlyPower           = pack->onlyPower;

        save_configInfo.crc = configCheckFunc((uint8_t *)&save_configInfo, CONFIG_INFO_SIZE - 2);
        save_backups_config_info(&save_configInfo);
        save_config_info(&save_configInfo);

        memset(config_buff, 0, sizeof(config_buff));

        /* 返回更改配置文件成功 */
        SL_Mppt_SOther_pack SUpdateProfile_pack = {0};

        SUpdateProfile_pack.start_Flag[0] = g_otherParameter.startFlagSL[0];
        SUpdateProfile_pack.start_Flag[1] = g_otherParameter.startFlagSL[1];

        SUpdateProfile_pack.address[0] = save_configInfo.address[0];
        SUpdateProfile_pack.address[1] = save_configInfo.address[1];
        SUpdateProfile_pack.address[2] = save_configInfo.address[2];
        SUpdateProfile_pack.address[3] = save_configInfo.address[3];
        SUpdateProfile_pack.address[4] = save_configInfo.address[4];
        SUpdateProfile_pack.address[5] = save_configInfo.address[5];
        SUpdateProfile_pack.address[6] = save_configInfo.address[6];

        SUpdateProfile_pack.function_Code = SL_Function_Code_Update_Profile;

        SUpdateProfile_pack.state = 0x01;

        uint16_t crc = CheckFuncSL((uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE - 3);
        SUpdateProfile_pack.check_Bit_H = crc >> 8;
        SUpdateProfile_pack.check_Bit_L = crc;

        SUpdateProfile_pack.end_Flag = g_otherParameter.endFlagSL;

        while (1) {
            if (!Check_485_bus_busy(g_gw485_uart4_handle)) {
                uart_dev_write(g_gw485_uart4_handle, (uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE);
                USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
                break;
            }
            Delay_Ms(randomDelay());
        }

        /* 复位 */
        NVIC_SystemReset();

        return;

        err:
            cfig_len--;
            memcpy(config_buff, config_buff + 1, sizeof(config_buff) - 1);
    }
}

/**
 * @brief  保存回路阻抗在flash中
 * @param
 */
void saveLoopImpedance(float_t *loopImpedance)
{
    SPI_Flash_Write((uint8_t *)loopImpedance, LoopImpedance_SAVE_addr, sizeof(float_t));
}

/**
 * @brief  读取flash中的回路阻抗
 * @param
 */
void readLoopImpedance(float_t *loopImpedance)
{
    SPI_Flash_Read((uint8_t *)loopImpedance, LoopImpedance_SAVE_addr, sizeof(float_t));
}

/**
 * @brief  保存放电量在flash中
 * @param
 */
void savetotalElectricityConsumption(float_t *totalElectricityConsumption)
{
    SPI_Flash_Write((uint8_t *)totalElectricityConsumption, totalElectricityConsumption_SAVE_addr, sizeof(float_t));
}

/**
 * @brief  读取flash中的放电量
 * @param
 */
void readtotalElectricityConsumption(float_t *totalElectricityConsumption)
{
    SPI_Flash_Read((uint8_t *)totalElectricityConsumption, totalElectricityConsumption_SAVE_addr, sizeof(float_t));
}

/**
 * @brief  保存充电量在flash中
 * @param
 */
void savetotalChargCapacity(float_t *totalChargCapacity)
{
    SPI_Flash_Write((uint8_t *)totalChargCapacity, totalChargCapacity_SAVE_addr, sizeof(float_t));
}

/**
 * @brief  读取flash中的充电量
 * @param
 */
void readtotalChargCapacity(float_t *totalChargCapacity)
{
    SPI_Flash_Read((uint8_t *)totalChargCapacity, totalChargCapacity_SAVE_addr, sizeof(float_t));
}


