
#include "inFlash.h"
#include "parameter.h"
#include "pDebug.h"
#include "cfg_protocol.h"

static void save_config_info(config_info *save_config_info);

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

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

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

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

void saveConfigInfo(config_info *config_info)
{
    save_config_info(config_info);
    // save_backups_config_info(config_info);
}

/**
 * @brief   检测flash中是否有配置文件或者文件是否有损坏,若两处flash中都损坏则使用默认文件
 * @param   config_info 读取的配置信息
 * @retval  None
 *
 */
static void readFlashContent(config_info *config_info)
{
    read_config_info(config_info);
    /* 配置文件正确就返回 */
    if (config_info->crc == checkModebusCrc((uint8_t *)config_info, CONFIG_INFO_SIZE - 2)) {
        return;
    }

    // /* 更深处的配置文件正确就返回 */
    // read_backups_config_info(config_info);
    // if (config_info->crc == configCheckFunc((uint8_t *)config_info, CONFIG_INFO_SIZE - 2)) {
    //     save_config_info(config_info);
    //     return;
    // }

    /* 配置文件错误使用默认配置 */
    config_info->address[0] = 0x11;
    config_info->address[1] = 0x11;
    config_info->address[2] = 0x11;
    config_info->address[3] = 0x11;
    config_info->address[4] = 0x11;
    config_info->address[5] = 0x11;
    config_info->address[6] = 0x11;
    // config_info->Access_Node_Type = 0x01;
    // config_info->Communication_Methods = 0x02;
    config_info->gw485_Baud = 9600;
    config_info->bat485_Baud = 115200;
    
    config_info->hardwareID[0] = 0x48;
    config_info->hardwareID[1] = 0x59;
    config_info->hardwareID[2] = 0x30;
    config_info->hardwareID[3] = 0x30;
    config_info->hardwareID[4] = 0x30;
    config_info->hardwareID[5] = 0x31;
    config_info->communicationID[0] = 0x00;
    config_info->communicationID[1] = 0x00;
    config_info->communicationID[2] = 0x00;
    config_info->communicationID[3] = 0x01;
    config_info->protocolType = 0x01;

    config_info->CommunicationProtocolType = 0x01;
    config_info->onlyPower = 0x01;

    config_info->constantVoltageV = 14;
    config_info->floatI = 0.02;
    config_info->startSolarOpenCircuitV = 17;
    config_info->stopSolarOpenCircuitV = 15;
    config_info->constantVoltageChargeV = 14.4;
    config_info->FloatChargeV = 14;
    config_info->HighSideMosTemperature_stop = 100;
    config_info->HighSideMosTemperature_end = 90;
    config_info->HighSideMosTemperature_start = 50;

    // config_info->checkSolarOpenCircuitVTime = 10;
    // config_info->sensorEnableBroadcastTime = 20;
    config_info->outputAgainFlagTime = 10;
    config_info->excessiveLoadFlagTime = 60;
    config_info->eLAgainTime = 1800;
}

/**
 * @brief   通过配置文件初始化系统参数
 * @param   None
 * @retval  None
 *
 */
void config_info_start(void)
{
    Flash_Init();

    config_info temp_configInfo;
    readFlashContent(&temp_configInfo);

    g_cfgParameter.constantVoltageV             = temp_configInfo.constantVoltageV;
    g_cfgParameter.floatI                       = temp_configInfo.floatI;
    g_cfgParameter.startSolarOpenCircuitV       = temp_configInfo.startSolarOpenCircuitV;
    g_cfgParameter.stopSolarOpenCircuitV        = temp_configInfo.stopSolarOpenCircuitV;
    g_cfgParameter.constantVoltageChargeV       = temp_configInfo.constantVoltageChargeV;
    g_cfgParameter.FloatV                       = temp_configInfo.FloatChargeV;
    g_cfgParameter.HighSideMosTemperature_stop  = temp_configInfo.HighSideMosTemperature_stop;
    g_cfgParameter.HighSideMosTemperature_end   = temp_configInfo.HighSideMosTemperature_end;
    g_cfgParameter.HighSideMosTemperature_start = temp_configInfo.HighSideMosTemperature_start;
    // g_cfgParameter.sensorEnableBroadcastTime    = temp_configInfo.sensorEnableBroadcastTime;
//    g_cfgParameter.checkSolarOpenCircuitVTime   = temp_configInfo.checkSolarOpenCircuitVTime;
    g_cfgParameter.outputAgainFlagTime          = temp_configInfo.outputAgainFlagTime;
    g_cfgParameter.excessiveLoadFlagTime        = temp_configInfo.excessiveLoadFlagTime;
    g_cfgParameter.eLAgainTime                  = temp_configInfo.eLAgainTime;
    g_cfgParameter.collectOpenCircuitVoltageTime= 3600;
    g_cfgParameter.address[0]                   = temp_configInfo.address[0];
    g_cfgParameter.address[1]                   = temp_configInfo.address[1];
    g_cfgParameter.address[2]                   = temp_configInfo.address[2];
    g_cfgParameter.address[3]                   = temp_configInfo.address[3];
    g_cfgParameter.address[4]                   = temp_configInfo.address[4];
    g_cfgParameter.address[5]                   = temp_configInfo.address[5];
    g_cfgParameter.address[6]                   = temp_configInfo.address[6];
    // g_cfgParameter.Access_Node_Type             = temp_configInfo.Access_Node_Type;
    // g_cfgParameter.Communication_Methods        = temp_configInfo.Communication_Methods;
    g_cfgParameter.hardwareID[0]                = temp_configInfo.hardwareID[0];
    g_cfgParameter.hardwareID[1]                = temp_configInfo.hardwareID[1];
    g_cfgParameter.hardwareID[2]                = temp_configInfo.hardwareID[2];
    g_cfgParameter.hardwareID[3]                = temp_configInfo.hardwareID[3];
    g_cfgParameter.hardwareID[4]                = temp_configInfo.hardwareID[4];
    g_cfgParameter.hardwareID[5]                = temp_configInfo.hardwareID[5];
    g_cfgParameter.communicationID[0]           = temp_configInfo.communicationID[0];
    g_cfgParameter.communicationID[1]           = temp_configInfo.communicationID[1];
    g_cfgParameter.communicationID[2]           = temp_configInfo.communicationID[2];
    g_cfgParameter.communicationID[3]           = temp_configInfo.communicationID[3];
    g_cfgParameter.protocolType                 = temp_configInfo.protocolType;
    // g_cfgParameter.CommunicationProtocolType    = temp_configInfo.CommunicationProtocolType;
    g_cfgParameter.onlyPower                    = temp_configInfo.onlyPower;

    g_cfgParameter.startFlagSL[0]               = 'S';
    g_cfgParameter.startFlagSL[1]               = 'L';
    g_cfgParameter.endFlagSL                    = 0x16;
    g_cfgParameter.startFlagHY                  = 0x68;
    g_cfgParameter.endFlagHY                    = 0x16;

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

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


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

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

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

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

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

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

