/*
 * task.c
 *
 *  Created on: 2024年6月24日
 *      Author: psx
 */
#include  <string.h>

#include "task.h"


#include "tim.h"
#include "pwm.h"
#include "adc.h"
#include "rs485.h"
#include "gpio.h"
#include "flash.h"


#include "sl_protocol.h"
#include "mppt_control.h"
#include "inflash.h"
#include <stdlib.h>
#include "collect_Conversion.h"


//uint8_t g_interruptNum = 0;       /* 每次关闭或重新开启定时器3时，先清零该引脚 */
void stop_mpptWork(void)
{
//    GPIO_WriteBit(EnPowerSupply_GPIO, EnPowerSupply_PIN, SET);
    g_duty_ratio = 0.7;
    TIM_Cmd(TIM3, DISABLE);
//    g_interruptNum = 0;
    TIM_SetCompare4(TIM4, 0);
//    TimeSliceOffset_Register(&m_startMpptControl, Task_startMpptControl
//            , startMpptControl_reloadVal, startMpptControl_offset);
//    GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);

}

void start_mpptWork(void)
{
//    GPIO_WriteBit(EnPowerSupply_GPIO, EnPowerSupply_PIN, RESET);
//    g_interruptNum = 0;
    TIM_Cmd(TIM3, ENABLE);
//    TIM3->CNT = 0;
    g_Mppt_Para.MPPT_Mode = CONSTANTCURRENT;
//    TimeSliceOffset_Unregister(&m_startMpptControl);
//    Delay_Ms(500);
//    GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
}

/**
  * @brief  运行指示灯
  * @param
  * @retval
  */
STR_TimeSliceOffset m_runled;
void Task_RunLED(void)
{
//    uart_sendstr(g_gw485_uart4_handle, "\n\n\n\n\n");
//    uart_sendstr(g_gw485_uart4_handle, "is gw485\n");
//    uart_sendstr(g_bat485_uart3_handle, "is bat485\n");get_PV1_VOLT_IN();

//    printf(" \n");
//    printf(" duty_ratio : %d/1000 \n", (int)(g_duty_ratio * 1000));
//
//    printf(" vout : %d/100 \n", (int)(g_Mppt_Para.Battery_Voltage * 100));
//    printf(" Iout : %d/100 \n", (int)(g_Mppt_Para.Charg_Current * 100));
//    printf(" Idisout : %d/100 \n", (int)(g_Mppt_Para.Discharg_Current * 100));
//    printf(" mosT : %d/10 \n", (int)(g_Mppt_Para.HighSideMos_Temperature * 10));
//    printf(" mosState : %d \n", (int)(g_Mppt_Para.DischargMos_State));
////    printf(" mosState : %d \n", GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN));
////    printf(" mosState : %d \n", GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN));
//
//    printf(" 0.没有工作; 1.涓流模式; 2.恒流模式; 3.恒压模式; 4.浮充模式; 5.没有电池 : %d \n", g_Mppt_Para.MPPT_Mode);
//
//    printf(" \n");
//    uart_sendstr(g_bat485_uart3_handle, " \n");

//    uart_dev_write(g_bat485_uart3_handle, " \n", sizeof(" \n"));
//
//    char buffer[80];
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " duty_ratio : %d/1000 \n", (int)(g_duty_ratio * 1000));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " Input_Voltage : %d/100 \n", (int)(g_Mppt_Para.Input_Voltage * 100));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " vout : %d/100 \n", (int)(g_Mppt_Para.Output_Voltage * 100));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " vBattery : %d/100 \n", (int)(g_Mppt_Para.Battery_Voltage * 100));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " Iout : %d/100 \n", (int)(g_Mppt_Para.Charg_Current * 100));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " Idisout : %d/100 \n", (int)(g_Mppt_Para.Discharg_Current * 100));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " mosT : %d/10 \n",  (int)(g_Mppt_Para.HighSideMos_Temperature * 10));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " impedance : %d/1000 \n",  (int)(g_impedance * 1000));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " g_impedanceStart : %d \n",  g_impedanceStart);
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " mosState : %d \n",  (int)(g_Mppt_Para.DischargMos_State));
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " batteryState : %d \n",  g_batteryState);
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " outputAgainFlag : %d \n",  outputAgainFlag);
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " excessiveLoadFlag : %d \n",  excessiveLoadFlag);
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    memset(buffer, 0, sizeof(buffer));
//    sprintf(buffer, " 0.没有工作; 1.涓流模式; 2.恒流模式; 3.恒压模式; 4.浮充模式; 5.没有电池 : %d \n",  g_Mppt_Para.MPPT_Mode);
//    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//
//    uart_dev_write(g_bat485_uart3_handle, " \n", sizeof(" \n"));



//    printf("vout : %d/100 \n", (int)(get_capturedata(get_PV_VOLT_OUT) * 100));

//    get_CHG_CURR();

//    printf("\n\n\n");
//    printf("num = %d \n", g_adcData.num);
//    printf("Charg_Current = %d/1000 \n", (int)(g_Mppt_Para.Charg_Current * 1000));
//    printf("Output_Voltage = %d/1000 \n", (int)(g_Mppt_Para.Output_Voltage * 1000));
//    printf("Discharg_Current = %d/1000 \n", (int)(g_Mppt_Para.Discharg_Current * 1000));
//    printf("Input_Voltage = %d/1000 \n", (int)(g_Mppt_Para.Input_Voltage * 1000));
//    printf("get_PV_VOLT_IN1 = %d/1000 \n", (int)(get_PV_VOLT_IN1() * 1000));
//    printf("HighSideMos_Temperature = %d/1000 \n", (int)(g_Mppt_Para.HighSideMos_Temperature * 1000));
//    printf("\n\n\n");

//    printf("%d\n", g_adcData.num);
//    printf("%d\n", (int)(g_Mppt_Para.Charg_Current * 1000));
//    printf("%d\n", (int)(g_Mppt_Para.Output_Voltage * 1000));
//    printf("%d\n", (int)(g_Mppt_Para.Discharg_Current * 1000));
//    printf("%d\n", (int)(g_Mppt_Para.Input_Voltage * 1000));
//    printf("%d\n", (int)(g_Mppt_Para.Solar_Open_Circuit_Voltage * 1000));
//    printf("%d\r\n", (int)(g_Mppt_Para.HighSideMos_Temperature * 1000));

    static uint8_t flag = RESET;
    flag = !flag;
    GPIO_WriteBit(RUN_LED_GPIO, RUN_LED_PIN, flag);


    static uint8_t num = 0;
    if (10 == ++num) {
        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
    }

    return;
}


/**
  * @brief  启动mppt控制
  * @param
  * @retval
  */
STR_TimeSliceOffset m_startMpptControl;
void Task_startMpptControl(void)
{
    static uint16_t checkSolarOpenCircuitVTimeFlag;
    static uint8_t only_once = 1;
    if (only_once) {
        only_once = 0;
        checkSolarOpenCircuitVTimeFlag = g_slConfigInfo.checkSolarOpenCircuitVTime - 3;
    }

    if (g_slConfigInfo.checkSolarOpenCircuitVTime == ++checkSolarOpenCircuitVTimeFlag) {
        checkSolarOpenCircuitVTimeFlag = 0;
        g_Mppt_Para.Solar_Open_Circuit_Voltage = get_PV_VOLT_IN();
//        printf("volt in : %d/100 \n", (int)(g_Mppt_Para.Solar_Open_Circuit_Voltage * 100));
//        char buff[50];
//        memset(buff, 0, sizeof(buff));
//        sprintf(buff, "volt in : %d/100 \n",  (int)(g_Mppt_Para.Solar_Open_Circuit_Voltage * 100));
//        uart_dev_write(g_bat485_uart3_handle, buff, sizeof(buff));

        if (g_Mppt_Para.Solar_Open_Circuit_Voltage
             > ((float_t)g_slConfigInfo.startSolarOpenCircuitV / 100)) {
            TimeSliceOffset_Unregister(&m_startMpptControl);
            m_startMpptControl.runFlag = 0;
//            printf("1\n");
//            start_mpptWork();
            if (g_Mppt_Para.Output_Voltage > 11) {
                g_batteryState = 1;
            } else {
                g_batteryState = 0;
            }
            TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
        }
    }
    return;
}

/**
  * @brief  软起动
  * @param
  * @retval
  */
STR_TimeSliceOffset m_softStart;
void Task_softStart(void)
{
    static uint16_t num = 0;
    static float_t dutyRatio = 0;

    num++;

//    if (num == 1) {
//        GPIO_WriteBit(EnPowerSupply_GPIO, EnPowerSupply_PIN, RESET);
//    }

    if (num < 5) {
        TIM_SetCompare4(TIM4, 100);
    }

    else if (num > 70 || dutyRatio > g_duty_ratio) {
        TimeSliceOffset_Unregister(&m_softStart);
        m_softStart.runFlag = 0;

        dutyRatio = 0;
        num = 0;
        Set_duty_ratio(&g_duty_ratio);

        if (g_batteryState == 1) {
            start_mpptWork();
//            GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
//            TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation
//                    , impedanceCalculation_reloadVal, impedanceCalculation_reloadVal);
            return;
        } else {
            dutyRatio = 0;
            num = 0;
            Set_duty_ratio(&g_duty_ratio);
//            TimeSliceOffset_Unregister(&m_softStart);
//            m_softStart.runFlag = 0;

            //软起动后bms保护板开启电池充电
            if (get_CHG_CURR() - get_DSG_CURR() > 0.1
                    || get_DSG_CURR() - get_CHG_CURR() > 0.1) {
//                printf("111\n");
//                TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation
//                        , impedanceCalculation_reloadVal, impedanceCalculation_reloadVal);
                start_mpptWork();
//                GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
                return;
            }

            g_Mppt_Para.MPPT_Mode = FLOAT;
            TIM_Cmd(TIM3, ENABLE);
//            GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);

            return;
        }
    }

    else {
        dutyRatio += 0.01;
        Set_duty_ratio(&dutyRatio);
    }
}

/**
  * @brief 串口数据解析和处理
  * @param
  * @retval
  */
STR_TimeSliceOffset m_usart;
uint8_t RegistrationRequestFlag = 0;
void Task_usart(void)
{
    read_and_process_uart_data(g_gw485_uart4_handle);
//    read_and_process_uart_data(g_bat485_uart3_handle);
//    uart_dev_write(g_bat485_uart3_handle, "hello world \n", sizeof("hello world \n"));
    return;
}

/**
  * @brief 看门狗
  * @param
  * @retval
  */
STR_TimeSliceOffset m_wdi;
void Task_wdi(void)
{
    static uint32_t temp = 0;
    if (wdi_RESET == temp++) {
        temp = 0;
        NVIC_SystemReset();
    }
    GPIO_WriteBit(WDI_INPUT_GPIO, WDI_INPUT_PIN, SET);
    GPIO_WriteBit(WDI_INPUT_GPIO, WDI_INPUT_PIN, RESET);
    return;
}

/**
  * @brief  刷新寄存器中的数据,同时确定mos管温度
  * @param
  * @retval
  */
STR_TimeSliceOffset m_refreshRegister;
uint8_t overTemperature = 0;
void Task_refreshRegister(void)
{
    static uint16_t checkRegisterRefreshTimeFlag;

    if (g_slConfigInfo.registerRefreshTime == ++checkRegisterRefreshTimeFlag) {
        checkRegisterRefreshTimeFlag = 0;
//        g_Mppt_Para.Battery_Voltage = get_capturedata(get_PV_VOLT_OUT);
//        g_Mppt_Para.Charg_Current = get_capturedata(get_CHG_CURR);
//        g_Mppt_Para.Discharg_Current = get_capturedata(get_DSG_CURR);
//        g_Mppt_Para.HighSideMos_Temperature = get_capturedata(get_MOSFET_Temper);
//        g_Mppt_Para.Battery_Voltage = get_PV_VOLT_OUT();
//        g_Mppt_Para.Output_Voltage = get_PV_VOLT_OUT();
//        g_Mppt_Para.Charg_Current = get_CHG_CURR();
//        g_Mppt_Para.Discharg_Current = get_DSG_CURR();
//        g_Mppt_Para.HighSideMos_Temperature = get_MOSFET_Temper();
        g_Mppt_Para.DischargMos_State = GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN)
                                                && GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN);

        if (g_Mppt_Para.Charg_Current - g_Mppt_Para.Discharg_Current < -0.1) {
                g_Mppt_Para.Battery_Voltage = g_Mppt_Para.Output_Voltage
                        - (g_Mppt_Para.Charg_Current - g_Mppt_Para.Discharg_Current) * g_impedance;
        }

        float_t inBatteryCurr = g_Mppt_Para.Charg_Current - g_Mppt_Para.Discharg_Current;
        float_t outBatteryCurr = g_Mppt_Para.Discharg_Current - g_Mppt_Para.Charg_Current;
        if (g_batteryState == 0 && (inBatteryCurr > 0.1 || outBatteryCurr > 0.1) && g_Mppt_Para.Output_Voltage < 14.2) {
             g_batteryState = 1;
         }

        /* 有电池，太阳能输出功率大，同时回路阻抗未测试或需要重新测试 */
        if (g_batteryState == 1 && (g_Mppt_Para.Charg_Current > 3.0) && (g_impedanceStart == 1 || g_impedance == 0.0)) {
            TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation
                    , impedanceCalculation_reloadVal, impedanceCalculation_reloadVal);
        }

//        g_Mppt_Para.DischargMos_State = GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN);
//        g_Mppt_Para.Solar_Open_Circuit_Voltage = get_capturedata(get_PV1_VOLT_IN);
        g_Mppt_Para.Input_Voltage = get_PV_VOLT_IN();

        if (g_Mppt_Para.HighSideMos_Temperature < g_slConfigInfo.HighSideMosTemperature_start + 3) {
            if (overTemperature == 2) {
//                start_mpptWork();
                TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
            }
            overTemperature = 0;
            return;
        }

        if (g_Mppt_Para.HighSideMos_Temperature > g_slConfigInfo.HighSideMosTemperature_end + 3
                && g_Mppt_Para.HighSideMos_Temperature < g_slConfigInfo.HighSideMosTemperature_stop) {
//            g_Mppt_Para.MPPT_Mode = NoBattery;
//            g_duty_ratio -= 0.1;
            g_duty_ratio = 0.6;
            Set_duty_ratio(&g_duty_ratio);
            overTemperature = 1;
        }

        if (g_Mppt_Para.HighSideMos_Temperature > g_slConfigInfo.HighSideMosTemperature_stop  + 3) {
            overTemperature = 2;
            stop_mpptWork();
        }
    }
}

/**
  * @brief 接收到广播指令后,发送数据给网关，未接收到指令再次发送，最多三次，间隔时间3s
  * @param
  * @retval
  */
uint8_t recvbroadcast_flag = 0;
device_handle g_recvBroadcastDevice;
uint8_t g_recvBroadcastRegisterNumber;
STR_TimeSliceOffset m_recvbroadcast;
void Task_recvbroadcast(void)
{
    static uint8_t run_number = 0;
    /* 超过三次，不再发送 */
    if (run_number++ == 3 || run_number > 3) {
        RegistrationRequestFlag = 0;
        run_number = 0;
        TimeSliceOffset_Unregister(&m_recvbroadcast);
        m_recvbroadcast.runFlag = 0;
        return;
    }
//    if (g_Mppt_Para.Registration_Status == REGISTER_SUCCESS) {
//        TimeSliceOffset_Unregister(&m_recvbroadcast);
//        return;
//    }
    SL_Mppt_RegistrationRequest_pack recvpack = {0};

    /* 起始标志 */
    recvpack.start_Flag[0] = g_slConfigInfo.start_Flag[0];
    recvpack.start_Flag[1] = g_slConfigInfo.start_Flag[1];

    /* ID */
    recvpack.address[0] = 0xFF;
    recvpack.address[1] = 0xFF;
    recvpack.address[2] = 0xFF;
    recvpack.address[3] = 0xFF;
    recvpack.address[4] = 0xFF;
    recvpack.address[5] = 0xFF;
    recvpack.address[6] = 0xFF;

    /* 功能码 */
    recvpack.function_Code = SL_Function_Code_Registration_request;

    /* 寄存器长度 */
    recvpack.register_Length_H =  g_recvBroadcastRegisterNumber >> 8;
    recvpack.register_Length_L =  g_recvBroadcastRegisterNumber;

    /* 注册状态 */
    recvpack.registration_Status_H = g_Mppt_Para.Registration_Status >> 8;
    recvpack.registration_Status_L = g_Mppt_Para.Registration_Status;

    /* 接入节点ID */
    recvpack.access_Node_ID[0] = g_slConfigInfo.address[0];
    recvpack.access_Node_ID[1] = g_slConfigInfo.address[1];
    recvpack.access_Node_ID[2] = g_slConfigInfo.address[2];
    recvpack.access_Node_ID[3] = g_slConfigInfo.address[3];
    recvpack.access_Node_ID[4] = g_slConfigInfo.address[4];
    recvpack.access_Node_ID[5] = g_slConfigInfo.address[5];
    recvpack.access_Node_ID[6] = g_slConfigInfo.address[6];

    /* 接入节点类型 */
    recvpack.access_Node_Type_H = g_Mppt_Para.Access_Node_Type >> 8;
    recvpack.access_Node_Type_L = g_Mppt_Para.Access_Node_Type;

    /* 校验位 */
//    uint8_t *rpack_buf = (uint8_t *)&recvpack;
    uint16_t crc = CheckFunc((uint8_t *)&recvpack, SL_MPPT_REGISTRATIONREQUEST_PACK_SIZE - 3);

    recvpack.check_Bit_H = crc >> 8;
    recvpack.check_Bit_L = crc;
    /* 结束标志 */
    recvpack.end_Flag = g_slConfigInfo.end_Flag;
    /* 校验位 */
    for (uint8_t var = 0; var < 10; ++var) {
        Delay_Ms(randomDelay());
        if (!Check_485_bus_busy(g_recvBroadcastDevice)) {
            if (recvbroadcast_flag == 1) {
                recvbroadcast_flag = 0;
                run_number = 0;
                return;
            }
            uart_dev_write(g_recvBroadcastDevice, (uint8_t *)&recvpack, SL_MPPT_REGISTRATIONREQUEST_PACK_SIZE + 1);

            if (g_recvBroadcastDevice == g_bat485_uart3_handle) {
                USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
            } else {
                USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
            }

            break;
        }
    }
}

/**
  * @brief 阻抗计算
  * @param
  * @retval
  */
STR_TimeSliceOffset m_impedanceCalculation;
float_t g_impedance = 0;            /* 回路阻抗的值 */
uint8_t g_batteryState = 0;         /* 有无电池 */
uint8_t g_impedanceStart = 0;       /* 是否开始测量回路阻抗 */
//config_info tempConfigInfo;
void Task_impedanceCalculation(void)
{
    static uint8_t num = 0;
    static float_t currOne = 0;
    static float_t voltOne = 0;
    static float_t currTwo = 0;
    static float_t voltTwo = 0;
//    static uint8_t only_one = 1;
//    if (only_one) {
//        g_impedance = g_slConfigInfo.loopImpedance;
//    }

//    if (g_Mppt_Para.MPPT_Mode == CONSTANTCURRENT
//            || g_Mppt_Para.MPPT_Mode == CONSTANTVOLTAGE) {
//        ++num;
//    } else {
//        num = 0;
//    }
//
//    if (num == 10) {
//        num = 0;
//        TIM_Cmd(TIM3, DISABLE);
//
//        TIM_SetCompare4(TIM4, 300);
//        Delay_Ms(500);
//
//        TIM_SetCompare4(TIM4, 420);
//        Delay_Ms(5);
////        currOne = get_capturedata(get_CHG_CURR) - get_capturedata(get_DSG_CURR);
////        voltOne = get_capturedata(get_PV_VOLT_OUT);
//        currOne = get_CHG_CURR() - get_DSG_CURR();
//        voltOne = get_PV_VOLT_OUT();
//
////        currTwo = get_capturedata(get_CHG_CURR) - get_capturedata(get_DSG_CURR);
////        voltTwo = get_capturedata(get_PV_VOLT_OUT);
//        currTwo = get_CHG_CURR() - get_DSG_CURR();
//        voltTwo = get_PV_VOLT_OUT();
//
//        g_impedance = (voltOne - voltTwo) / (currOne - currTwo);
//
//        printf("currOne = %d/1000, voltOne = %d/100 \n", (int)(currOne * 1000), (int)(voltOne * 100));
//        printf("currTwo = %d/1000, voltTwo = %d/100 \n", (int)(currTwo * 1000), (int)(voltTwo * 100));
//        printf("Res = %d/1000, E = %d/100 \n", (int)(g_impedance * 1000), (int)((voltTwo - currTwo * g_impedance) * 100));
//
////        TIM_Cmd(TIM3, ENABLE);
//    }

    num++;

//    printf("g_batteryState : %d\n", g_batteryState);

    if (num == 1) {
        TIM_Cmd(TIM3, DISABLE);
//        g_interruptNum = 0;
        TIM_SetCompare4(TIM4, 300);
        return;
    }

    if (num == 11) {
        currOne = get_CHG_CURR() - get_DSG_CURR();
        voltOne = get_PV_VOLT_OUT();
        TIM_SetCompare4(TIM4, 420);
        return;
    }

    if (num == 21) {
        TimeSliceOffset_Unregister(&m_impedanceCalculation);
        m_impedanceCalculation.runFlag = 0;

        currTwo = get_CHG_CURR() - get_DSG_CURR();
        voltTwo = get_PV_VOLT_OUT();
        g_impedance = (voltOne - voltTwo) / (currOne - currTwo);

//        printf("g_batteryState : %d\n", g_batteryState);

//        printf("currOne = %d/1000, voltOne = %d/100 \n", (int)(currOne * 1000), (int)(voltOne * 100));
//        printf("currTwo = %d/1000, voltTwo = %d/100 \n", (int)(currTwo * 1000), (int)(voltTwo * 100));
//        printf("Res = %d/1000, E = %d/100 \n", (int)(g_impedance * 1000), (int)((voltTwo - currTwo * g_impedance) * 100));

        /* 判断回路阻抗是否合理 */
        if (g_impedance > 1.0 || g_impedance < 0.05) {
            g_impedance = 0;
            num = 0;
            start_mpptWork();
            return;
        }

        /* 将回路阻抗的值放入flash中 */
        config_info tempConfigInfo;
        if (read_config_info1(&tempConfigInfo)) {
            tempConfigInfo.loopImpedance = (uint16_t)(g_impedance * 1000);
            save_config_info(&tempConfigInfo);
        } else {
            tempConfigInfo = g_slConfigInfo;
            tempConfigInfo.loopImpedance = (uint16_t)(g_impedance * 1000);
            save_config_info(&tempConfigInfo);
        }

//        uart_dev_write(g_bat485_uart3_handle, "\n\n\n\n\n", sizeof("\n\n\n\n\n"));
//        char buffer[80];
//        memset(buffer, 0, sizeof(buffer));
//        sprintf(buffer, " tempConfigInfo.loopImpedance : %d/1000 \n", tempConfigInfo.loopImpedance);
//        uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//        memset(buffer, 0, sizeof(buffer));
//        config_info tempConfigInfo2 = {0};
//        read_config_info1(&tempConfigInfo2);
//        sprintf(buffer, " tempConfigInfo2.loopImpedance : %d/1000 \n", tempConfigInfo2.loopImpedance);
//        uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));
//        uart_dev_write(g_bat485_uart3_handle, "\n\n\n\n\n", sizeof("\n\n\n\n\n"));

        g_impedanceStart = 0;
        num = 0;
        start_mpptWork();
//        TIM_Cmd(TIM3, ENABLE);
        return;
    }

    return;
}

/**
  * @brief 延时一段时间后检测是否仍然短路
  * @param
  * @retval
  */
STR_TimeSliceOffset m_outputAgain;
uint8_t outputAgainFlag = 0;
void Task_outputAgain(void)
{
    static uint8_t num = 0;
    num++;

//    if (outputAgainFlag == 1) {
////        outputAgainFlag = 0;
//        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
//        TimeSliceOffset_Unregister(&m_outputAgain);
//        m_outputAgain.runFlag = 0;
//        num = 0;
//    }

//    printf(" in POW_OUT_CON\n");
    if (num == g_slConfigInfo.outputAgainFlagTime) {
        num = 0;
        outputAgainFlag = 0;
        TimeSliceOffset_Unregister(&m_outputAgain);
        m_outputAgain.runFlag = 0;
//        printf(" in POW_OUT_CON control %d \n", GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN));
        if (!(GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN))) {
//            uart_dev_write(g_bat485_uart3_handle, " \n\n\n\n\n", sizeof(" \n\n\n\n\n"));
//            uart_dev_write(g_bat485_uart3_handle, " in task pow_out_con reset", sizeof(" in task pow_out_con reset"));
//            uart_dev_write(g_bat485_uart3_handle, " \n\n\n\n\n", sizeof(" \n\n\n\n\n"));
//            printf(" in POW_OUT_CON RESET \n");
            GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
        }
    }

    return;
}

/**
  * @brief 过载后开始延时，这段时间内再次过载则关闭输出
  * @param
  * @retval
  */
STR_TimeSliceOffset m_excessiveLoad;
uint8_t excessiveLoadFlag = 0;
void Task_excessiveLoad(void)
{
    static uint8_t num = 0;
    static uint16_t numLong = 0;

//    if (outputAgainFlag == 1) {
////        outputAgainFlag = 0;
//        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
//        TimeSliceOffset_Unregister(&m_outputAgain);
//        m_outputAgain.runFlag = 0;
//        num = 0;
//    }

//    printf(" in POW_OUT_CON\n");
    if (outputAgainFlag == 1) {
        num = 0;
        numLong = 0;
        excessiveLoadFlag = 0;
        TimeSliceOffset_Unregister(&m_excessiveLoad);
        m_excessiveLoad.runFlag = 0;
    }

    if (excessiveLoadFlag == 1) {
        num++;
    }

    if (num == g_slConfigInfo.excessiveLoadFlagTime) {
        num = 0;
        excessiveLoadFlag = 0;
        TimeSliceOffset_Unregister(&m_excessiveLoad);
        m_excessiveLoad.runFlag = 0;
        return;
    }



    if (excessiveLoadFlag >= 2) {
        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
        num = 0;
    }

    if (!(GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN))) {
        numLong++;
    }

    if (numLong == g_slConfigInfo.eLAgainTime) {
        numLong = 0;
        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
        excessiveLoadFlag = 0;
        TimeSliceOffset_Unregister(&m_excessiveLoad);
        m_excessiveLoad.runFlag = 0;
    }

    return;
}

/**
  * @brief 设定传感器能再次注册的间隔时间
  * @param
  * @retval
  */
STR_TimeSliceOffset m_sensorEnableBroadcast;
/* 是否接收广播帧标志位 */
uint8_t run_Broadcast = 1;
void Task_sensorEnableBroadcast(void)
{
    static uint32_t enabBroadcastTimeFlag = 0;
    enabBroadcastTimeFlag++;
    run_Broadcast = 0;

    if (enabBroadcastTimeFlag == g_slConfigInfo.sensorEnableBroadcastTime) {
        enabBroadcastTimeFlag = 0;
        run_Broadcast = 1;
        TimeSliceOffset_Unregister(&m_sensorEnableBroadcast);
        m_sensorEnableBroadcast.runFlag = 0;
    }
    return;
}

/**
  * @brief  初始化各个寄存器
  * @param
  * @retval
  */
void g_Mppt_Para_Init(void)
{
    g_impedance = (float_t)g_slConfigInfo.loopImpedance / 1000;

    g_Mppt_Para.Registration_Status = UNREGISTER;
    g_Mppt_Para.address[0] = g_slConfigInfo.address[0];
    g_Mppt_Para.address[1] = g_slConfigInfo.address[1];
    g_Mppt_Para.address[2] = g_slConfigInfo.address[2];
    g_Mppt_Para.address[3] = g_slConfigInfo.address[3];
    g_Mppt_Para.address[4] = g_slConfigInfo.address[4];
    g_Mppt_Para.address[5] = g_slConfigInfo.address[5];
    g_Mppt_Para.address[6] = g_slConfigInfo.address[6];
    g_Mppt_Para.Access_Node_Type = defaultValue.access_Node_Type;
    g_Mppt_Para.Communication_Methods = defaultValue.communication_Methods;

//    g_Mppt_Para.Output_Voltage = get_capturedata(get_PV_VOLT_OUT);
//    g_Mppt_Para.Battery_Voltage = g_Mppt_Para.Output_Voltage;
//    g_Mppt_Para.Charg_Current = get_capturedata(get_CHG_CURR);
//    g_Mppt_Para.Discharg_Current = get_capturedata(get_DSG_CURR);
//    g_Mppt_Para.Solar_Open_Circuit_Voltage = get_capturedata(get_PV1_VOLT_IN);
//    g_Mppt_Para.HighSideMos_Temperature = get_capturedata(get_MOSFET_Temper);    g_Mppt_Para.Output_Voltage = get_capturedata(get_PV_VOLT_OUT);

    g_Mppt_Para.Output_Voltage = get_PV_VOLT_OUT();
//    g_Mppt_Para.Battery_Voltage = g_Mppt_Para.Output_Voltage;
    g_Mppt_Para.Charg_Current = get_CHG_CURR();
    g_Mppt_Para.Discharg_Current = get_DSG_CURR();
    g_Mppt_Para.Battery_Voltage = g_Mppt_Para.Output_Voltage
            - (g_Mppt_Para.Charg_Current - g_Mppt_Para.Discharg_Current) * g_impedance;
    g_Mppt_Para.Solar_Open_Circuit_Voltage = get_PV_VOLT_IN();
    g_Mppt_Para.HighSideMos_Temperature = get_MOSFET_Temper();

    if (g_Mppt_Para.Battery_Voltage < 15 || g_Mppt_Para.Battery_Voltage > 11) {
//        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
        g_impedanceStart = 1;
    }
    g_Mppt_Para.DischargMos_State = GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN)
                                            && GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN);
    g_Mppt_Para.MPPT_Mode = NoWork;


//    printf("start_flag : %s \n", g_slConfigInfo.start_Flag);
//    for (int var = 0; var < 7; ++var) {
//        printf("address[%d] : %x\n", var, g_slConfigInfo.address[var]);
//    }
//    printf("end_flag : %x\n", g_slConfigInfo.end_Flag);
//    printf("access_Node_Type : %x\n", defaultValue.access_Node_Type);
//    printf("communication_Methods : %x\n", defaultValue.communication_Methods);
}

/**
  * @brief  初始化各个任务和读取配置文件等
  * @param
  * @retval
  */
void task_Init(void)
{
    read_config_info();
    g_Mppt_Para_Init();

    TimeSliceOffset_Register(&m_runled, Task_RunLED, runled_reloadVal, runled_offset);

//    TimeSliceOffset_Register(&m_usart, Task_usart, usart_reloadVal, usart_offset);

    TimeSliceOffset_Register(&m_wdi, Task_wdi, wdi_reloadVal, wdi_offset);

//    TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation
//            , impedanceCalculation_reloadVal, impedanceCalculation_reloadVal);
//
//    TimeSliceOffset_Register(&m_refreshRegister, Task_refreshRegister
//            , refreshRegister_reloadVal, refreshRegister_reloadVal);
//
//    TimeSliceOffset_Register(&m_startMpptControl, Task_startMpptControl
//            , startMpptControl_reloadVal, startMpptControl_offset);

    TimeSliceOffset_Start();    /* 启动时间片轮询 */
}


/**
  * @brief  初始化所需外设
  * @param
  * @retval
  */
void hardware_Init(void)
{
    TIM2_Init(1);
    uart_dev_init();
    PWM_TIM_Configuration();
//    TIM_SetCompare4(TIM4, 0);
    ADC_all_Init();
    RUN_LED_Init();
    WDI_INPUT_Init();
    SPI_Flash_Init();
    POW_OUT_CON_Init();
    DSG_PROT_Init();
    WORK_VOLT_INT_Init();
    ADC_TIM_DMA_Init();
//    EnPowerSupply_Init();

//    Set_duty_ratio(&g_duty_ratio);

//    uart_dev_write(g_bat485_uart3_handle, " hello world \n", sizeof(" hello world \n"));

    TIM3_Init(300);
    TIM_Cmd(TIM3, ENABLE); //TIM3使能

    g_duty_ratio = 0.8;
    Set_duty_ratio(&g_duty_ratio);
}

