
#include "inFlash.h"
#include "parameter.h"
#include "pDebug.h"
//#include "cfg_protocol.h"
#include "configParameter.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 *configInfo)
{
    save_config_info(configInfo);
    // save_backups_config_info(config_info);
}

void cfgTest(void)
{
    // uint32_t tempTime = HAL_GetTick();
    // config_info temp_configInfo;
    // read_config_info(&temp_configInfo);
    // log_info("1 read time : %d \n", HAL_GetTick() - tempTime);
    // tempTime = HAL_GetTick();
    // saveConfigInfo(&temp_configInfo);
    // log_info("1 write time : %d \n", HAL_GetTick() - tempTime);
    // tempTime = HAL_GetTick();
    // for (int i = 0; i < 10; i++) {        
    //     read_config_info(&temp_configInfo);
    //     saveConfigInfo(&temp_configInfo);
    // }    
    // log_info("10 time : %d \n", HAL_GetTick() - tempTime);

    // uint32_t tempTime = HAL_GetTick();
    // float tempF;
    // readtotalElectricityConsumption(&tempF);
    // log_info("1 read time : %d \n", HAL_GetTick() - tempTime);
    // tempTime = HAL_GetTick();
    // savetotalElectricityConsumption(&tempF);
    // log_info("1 write time : %d \n", HAL_GetTick() - tempTime);
    // tempTime = HAL_GetTick();
    // for (int i = 0; i < 10; i++) {
    //     readtotalElectricityConsumption(&tempF);
    //     savetotalElectricityConsumption(&tempF);
    // }    
    // log_info("10 time : %d \n", HAL_GetTick() - tempTime);

    // uint32_t tempTime = HAL_GetTick();
    // timeInfo tempT;
    // readTime(&tempT);
    // log_info("1 read time : %d \n", HAL_GetTick() - tempTime);
    // tempTime = HAL_GetTick();
    // saveTime(&tempT);
    // log_info("1 write time : %d \n", HAL_GetTick() - tempTime);
    // tempTime = HAL_GetTick();
    // for (int i = 0; i < 10; i++) {
    //     readTime(&tempT);
    //     saveTime(&tempT);
    // }    
    // log_info("10 time : %d \n", HAL_GetTick() - tempTime);
    
    uint32_t tempTime = HAL_GetTick();
    uint8_t tempBuf[30];
    write_Flash((uint8_t *)"hello 12345\n", 2048, sizeof("hello 12345\n"));
    log_info("1 write time : %d \n", HAL_GetTick() - tempTime);
    tempTime = HAL_GetTick();
    read_Flash(tempBuf, 2048, sizeof("hello 12345\n"));
    log_info("1 read time : %d \n", HAL_GetTick() - tempTime);
    log_info("%s\n", tempBuf);
    tempTime = HAL_GetTick();
    for (int i = 0; i < 10; i++) {
        read_Flash(tempBuf, 2048, sizeof("hello world\n"));
        write_Flash((uint8_t *)"hello world\n", 2048, sizeof("hello world\n"));
    }    
    log_info("10 time : %d \n", HAL_GetTick() - tempTime);
}



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

    /* 配置文件错误使用默认配置 */
    configInfo->uniqueDeviceID[0] = 0x11;
    configInfo->uniqueDeviceID[1] = 0x11;
    configInfo->uniqueDeviceID[2] = 0x11;
    configInfo->uniqueDeviceID[3] = 0x11;
    configInfo->uniqueDeviceID[4] = 0x11;
    configInfo->uniqueDeviceID[5] = 0x11;
    configInfo->uniqueDeviceID[6] = 0x11;

    configInfo->gw485_Baud = 9600;
    configInfo->bat485_Baud = 9600;

    configInfo->powerBoxType = 0xFF;

    configInfo->constantVoltageV = 14;
    configInfo->floatI = 0.2f;
    configInfo->startSolarOpenCircuitV = 19;
    configInfo->stopSolarOutputCircuitV = 15;

    configInfo->checkCanStartTime = 5;
    configInfo->shortCircuitJudgmentDelay = 10;
    configInfo->inputPowerLowJudgmentDelay = 60;
    configInfo->inputPowerLowAgainOutputDelay = 1800;

    configInfo->firstStageProtectionDelay = 200;
    configInfo->firstStageProtectionCurr = 50;
    configInfo->secondStageProtectionDelay = 20000;
    configInfo->secondStageProtectionCurr = 35;
    configInfo->thirdStageProtectionDelay = 600000;
    configInfo->thirdStageProtectionCurr = 30;

    configInfo->inputPowerLowDetectionDelay = 10;
    configInfo->inputPowerLowDetectionVolt = 14.0f;

    configInfo->maxOpenSolarOutputCircuitV = 25;
    configInfo->maxChargCurr = 30;

    configInfo->minCheckLoopImpedanceChargCurr = 5;

    configInfo->stopPowerOutputTemperature = 90;
    configInfo->reducePowerOutputTemperature = 70;
    configInfo->fullPowerOutputTemperature = 60;

    configInfo->constantVoltageChargeV = 14.4f;
    configInfo->FloatChargeV = 14.2f;
    configInfo->collectOpenCircuitVoltageTime = 1800;
    
    configInfo->reverseChargProtectionCurr = 1;

    configInfo->softStartVolt = 18.5f;
    configInfo->MPPTConstantVoltage = 17.2f;
    configInfo->MPPTReduceConstantVoltage = 20.0f;
    configInfo->underVoltageProtection = 11.0f;

    // configInfo->firstStageProtectionCurr = firstStageProtectionCurrMacro;
    // configInfo->firstStageProtectionDelay = firstStageProtectionDelayMacro;
    // configInfo->firstStageProtectionValue = firstStageProtectionValueMacro;
    // configInfo->secondStageProtectionCurr = secondStageProtectionCurrMacro;
    // configInfo->secondStageProtectionDelay = secondStageProtectionDelayMacro;
    // configInfo->thirdStageProtectionCurr = thirdStageProtectionCurrMacro;
    // configInfo->thirdStageProtectionDelay = thirdStageProtectionDelayMacro;
    // configInfo->checkLoopImpedanceChargCurr = checkLoopImpedanceChargCurrMacro;
    // configInfo->lowInputLoadDetectionVolt = lowInputLoadDetectionVoltMacro;
    // configInfo->lowInputLoadDetectionDelay = lowInputLoadDetectionDelayMacro;
    // configInfo->maxChargCurr = maxChargCurrMacro;
    // configInfo->maxOpenSolarOpenCircuitV = maxOpenSolarOpenCircuitVMacro;

}

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

    config_info temp_configInfo;
    readFlashContent(&temp_configInfo);

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

    g_cfgParameter.Access_Node_Type             = POWERBOX;
    g_cfgParameter.Communication_Methods        = RS485;

    g_cfgParameter.gw485_Baud                   = temp_configInfo.gw485_Baud;
    // g_cfgParameter.gw485_Baud                   = 9600;
    g_cfgParameter.bat485_Baud                  = temp_configInfo.bat485_Baud;
    g_cfgParameter.supportProtocolTypes         = 0x01;
    // g_cfgParameter.bat485_Baud                  = 115200;
    // static volatile uint32_t tempBatBaud;
    // tempBatBaud = temp_configInfo.bat485_Baud;

    g_cfgParameter.uniqueDeviceID[0]            = temp_configInfo.uniqueDeviceID[0];
    g_cfgParameter.uniqueDeviceID[1]            = temp_configInfo.uniqueDeviceID[1];
    g_cfgParameter.uniqueDeviceID[2]            = temp_configInfo.uniqueDeviceID[2];
    g_cfgParameter.uniqueDeviceID[3]            = temp_configInfo.uniqueDeviceID[3];
    g_cfgParameter.uniqueDeviceID[4]            = temp_configInfo.uniqueDeviceID[4];
    g_cfgParameter.uniqueDeviceID[5]            = temp_configInfo.uniqueDeviceID[5];
    g_cfgParameter.uniqueDeviceID[6]            = temp_configInfo.uniqueDeviceID[6];

    g_cfgParameter.powerBoxType                 = temp_configInfo.powerBoxType;

    g_cfgParameter.constantVoltageV             = temp_configInfo.constantVoltageV;
    g_cfgParameter.floatI                       = temp_configInfo.floatI;

    g_cfgParameter.startSolarOpenCircuitV       = temp_configInfo.startSolarOpenCircuitV;
    g_cfgParameter.stopSolarOutputCircuitV      = temp_configInfo.stopSolarOutputCircuitV;

    g_cfgParameter.checkCanStartTime            = temp_configInfo.checkCanStartTime;
    g_cfgParameter.shortCircuitJudgmentDelay    = temp_configInfo.shortCircuitJudgmentDelay;
    g_cfgParameter.inputPowerLowJudgmentDelay   = temp_configInfo.inputPowerLowJudgmentDelay;
    g_cfgParameter.inputPowerLowAgainOutputDelay= temp_configInfo.inputPowerLowAgainOutputDelay;

    g_cfgParameter.firstStageProtectionCurr     = temp_configInfo.firstStageProtectionCurr;
    g_cfgParameter.firstStageProtectionDelay    = temp_configInfo.firstStageProtectionDelay;
    g_cfgParameter.secondStageProtectionCurr    = temp_configInfo.secondStageProtectionCurr;
    g_cfgParameter.secondStageProtectionDelay   = temp_configInfo.secondStageProtectionDelay;
    g_cfgParameter.thirdStageProtectionCurr     = temp_configInfo.thirdStageProtectionCurr;
    g_cfgParameter.thirdStageProtectionDelay    = temp_configInfo.thirdStageProtectionDelay;

    g_cfgParameter.inputPowerLowDetectionDelay  = temp_configInfo.inputPowerLowDetectionDelay;
    g_cfgParameter.inputPowerLowDetectionVolt   = temp_configInfo.inputPowerLowDetectionVolt;

    g_cfgParameter.maxOpenSolarOutputCircuitV   = temp_configInfo.maxOpenSolarOutputCircuitV;
    g_cfgParameter.maxChargCurr                 = temp_configInfo.maxChargCurr;
    g_cfgParameter.minCheckLoopImpedanceChargCurr = temp_configInfo.minCheckLoopImpedanceChargCurr;
    g_cfgParameter.stopPowerOutputTemperature   = temp_configInfo.stopPowerOutputTemperature;
    g_cfgParameter.reducePowerOutputTemperature = temp_configInfo.reducePowerOutputTemperature;
    g_cfgParameter.fullPowerOutputTemperature   = temp_configInfo.fullPowerOutputTemperature;

    g_cfgParameter.constantVoltageChargeV       = temp_configInfo.constantVoltageChargeV;
    g_cfgParameter.FloatChargeV                 = temp_configInfo.FloatChargeV;
    g_cfgParameter.collectOpenCircuitVoltageTime= temp_configInfo.collectOpenCircuitVoltageTime;
    g_cfgParameter.reverseChargProtectionCurr   = temp_configInfo.reverseChargProtectionCurr;

    // g_cfgParameter.softStartVolt                = 18.5f;
    // g_cfgParameter.MPPTConstantVoltage          = 17.5f;
    // g_cfgParameter.MPPTReduceConstantVoltage    = 20.0f;
    // g_cfgParameter.underVoltageProtection       = 11.0f;
    g_cfgParameter.softStartVolt                = temp_configInfo.softStartVolt;
    g_cfgParameter.MPPTConstantVoltage          = temp_configInfo.MPPTConstantVoltage;
    g_cfgParameter.MPPTReduceConstantVoltage    = temp_configInfo.MPPTReduceConstantVoltage;
    g_cfgParameter.underVoltageProtection       = temp_configInfo.underVoltageProtection;
    
    /* 读取的回路阻抗无效则回路阻抗设置为0 */
   float fTemp;
   // fTemp = 0.01f;
   // saveLoopImpedance(&fTemp);
   readLoopImpedance(&fTemp);
   // setLoopImpedance(fTemp);
   // if (getLoopImpedance() < 0 || getLoopImpedance() > 0.3f)  {
   if (!setLoopImpedance(fTemp))  {        
       setLoopImpedance(0);
       fTemp = getLoopImpedance();
       saveLoopImpedance(&fTemp);
   }
   
//    readtotalElectricityConsumption(&fTemp);
//    totalElectricityConsumptionInt(fTemp);
//    readtotalChargCapacity(&fTemp);
//    totalChargCapacityInt(fTemp);
//    timeInfo time;
//    readTime(&time);
//    setLastTime(time);
}

/**
 * @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));
}

/**
 * @brief  读取flash中的时间，这个时间是上次读取充放电量的时间
 * @param
 */
void saveTime(timeInfo *time)
{
    write_Flash((uint8_t *)time, time_SAVE_addr, sizeof(timeInfo));
}

/**
 * @brief  读取flash中的时间
 * @param
 */
void readTime(timeInfo *time)
{
    read_Flash((uint8_t *)time, time_SAVE_addr, sizeof(timeInfo));
}

// void saveOtherInfo(other_info *otherInfo)
// {
//     write_Flash((uint8_t *)otherInfo, LoopImpedance_SAVE_addr, sizeof(OTHER_INFO_SIZE));
// }

// void readOtherInfo(other_info *otherInfo)
// {
//     read_Flash((uint8_t *)otherInfo, LoopImpedance_SAVE_addr, sizeof(OTHER_INFO_SIZE));
// }

