#include "drv_gpio.h"

#include "bsp_task.h"
#include "bsp_event.h"

#include "gpio_manager.h"
#include "fault_manager.h"
#include "signal_manager.h"
#include "eeprom_manager.h"
#include "hv_adc_manager.h"
#include "statistic_manager.h"

#include "kit_data.h"
#include "kit_debug.h"

EVENT_STATIC_INIT_CCM(signal_event, kSignalIdx_End);


void bms_on_signal_analyse(EventItem *item, uint8_t idx)
{
    item->enable_cond = false;
}

void bms_cc2_signal_analyse(EventItem *item, uint8_t idx)
{
    item->enable_cond = false;
}


void bms_sw_signal_analyse(EventItem *item, uint8_t idx)
{
    GpioStatus st = drv_gpio_get_pin_status(kGpioType_DI1 + idx);
    item->enable_cond = (st == kGpioStatus_High);
    item->disable_cond = !item->enable_cond;
}

void bms_sw_signal_low_valid_analyse(EventItem *item, uint8_t idx)
{
    GpioStatus st = drv_gpio_get_pin_status(kGpioType_DI1 + idx);
    item->enable_cond = (st == kGpioStatus_Low);
    item->disable_cond = !item->enable_cond;
}

void bms_heat_analyse(EventItem *item, uint8_t idx)
{
    uint16_t min_temp = bms_get_statistic_data(kStatisticData_MinTemp);
    
	//min_temp = min_temp/10;
	uint16_t starttemp = get_eeprom_data(kEep_HeatOn_OffTemp, kEepromDataType_High) * 10;
	uint16_t endtemp = get_eeprom_data(kEep_HeatOn_OffTemp, kEepromDataType_Low) * 10;
    item->enable_cond = min_temp <= starttemp;
    item->disable_cond = min_temp >= endtemp;
}

void bms_cool_analyse(EventItem *item, uint8_t idx)
{
    uint16_t max_temp = bms_get_statistic_data(kStatisticData_MaxTemp);
	
    item->enable_cond = max_temp >= get_eeprom_data(kEep_CoolOn_OffTemp, kEepromDataType_High) * 10;
    item->disable_cond = max_temp <= get_eeprom_data(kEep_CoolOn_OffTemp, kEepromDataType_Low) * 10;
}

void bms_cool2_analyse(EventItem *item, uint8_t idx)
{
    uint16_t max_temp = bms_get_statistic_data(kStatisticData_MaxTemp);
    uint16_t min_temp = bms_get_statistic_data(kStatisticData_MinTemp);

    item->enable_cond = ((max_temp >= get_eeprom_data(kEep_CoolOn_OffTemp, kEepromDataType_High) * 10) 
                        && (min_temp > (20 + 50) * 10));
    item->disable_cond = ((max_temp <= get_eeprom_data(kEep_CoolOn_OffTemp, kEepromDataType_Low) * 10)
                        || (min_temp <= (18 + 50) * 10));
}

void bms_auto_analyse(EventItem *item, uint8_t idx)
{
    uint16_t temp_diff = 0;
    
    if(bms_get_statistic_data(kStatisticData_MaxTemp) > bms_get_statistic_data(kStatisticData_MinTemp))
    {
        temp_diff = bms_get_statistic_data(kStatisticData_MaxTemp) - bms_get_statistic_data(kStatisticData_MinTemp);
    }
    else
    {
        temp_diff = 0;
    }
   
    item->enable_cond = temp_diff >= 6 * 10;
    item->disable_cond = temp_diff <= 4 * 10;
}


void bms_chg_cur_analyse(EventItem *item, uint8_t idx)
{
    int32_t cur = bms_get_current();
    item->enable_cond = (cur >= (int16_t)get_eeprom_data(kEep_ChgCurThreshold_KeepTime, kEepromDataType_High));
    item->disable_cond = !item->enable_cond;
}

void bms_dis_cur_analyse(EventItem *item, uint8_t idx)
{
    int32_t cur = bms_get_current();
    item->enable_cond = (cur + (int16_t)get_eeprom_data(kEep_ChgCurThreshold_KeepTime, kEepromDataType_High) <= 0);
    item->disable_cond = !item->enable_cond;
}

void bms_volt_temp_point1_analyse(EventItem *item, uint8_t idx)
{
    item->enable_cond = (bms_get_statistic_data(kStatisticData_MinTemp) >= get_eeprom_data(kEep_VoltFaultTemp2_Temp1, kEepromDataType_Low) * 10);
    item->disable_cond = !item->enable_cond;
}

void bms_low_volt_sleep_analyse(EventItem *item, uint8_t idx)
{
    item->enable_cond = ((bms_get_fault_level(kFaultCode_LowCellVolt) >= kFaultLevel_Third) 
                      && (get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Low) > 0));
    item->disable_cond = !item->enable_cond;
}

void bms_standby_sleep_analyse(EventItem *item, uint8_t idx)
{
    item->enable_cond = ((bms_get_run_status() == kRunStatus_Standby) 
                      && (get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Full) > 0));
    item->disable_cond = !item->enable_cond;
}

void bms_forbid_dis_analyse(EventItem *item, uint8_t idx)
{

    item->enable_cond = item->disable_cond = false;
}

void bms_force_chg1_analyse(EventItem *item, uint8_t idx)
{
    uint16_t min_volt = bms_get_statistic_data(kStatisticData_MinVolt);
    uint16_t volt = get_eeprom_data(kEep_ForceChg1Volt, kEepromDataType_Full);
    
    item->enable_cond = ((volt > 0) && (min_volt <= volt));
    item->disable_cond = (min_volt >= get_eeprom_data(kEep_ForbidDisRelVolt, kEepromDataType_Full));
}

void bms_force_chg2_analyse(EventItem *item, uint8_t idx)
{
    uint16_t min_volt = bms_get_statistic_data(kStatisticData_MinVolt);
    uint16_t volt = get_eeprom_data(kEep_ForceChg2Volt, kEepromDataType_Full);
    
    item->enable_cond = ((volt > 0) && (min_volt <= volt));
    item->disable_cond = (min_volt >= get_eeprom_data(kEep_ForbidDisRelVolt, kEepromDataType_Full));
}

void bms_forbid_chg_analyse(EventItem *item, uint8_t idx)
{
    item->enable_cond = item->disable_cond = false;
}

void bms_chg_1st_cur_down_analyse(EventItem *item, uint8_t idx)
{
    uint16_t max_volt = bms_get_statistic_data(kStatisticData_MaxVolt);
    uint16_t volt = get_eeprom_data(kEep_ChgFstCurDownVolt, kEepromDataType_Full);
    
    item->enable_cond = ((volt > 0) && (max_volt >= volt) && (bms_get_run_status() == kRunStatus_Chg));
    item->disable_cond = (bms_get_run_status() != kRunStatus_Chg);
}

void bms_chg_2nd_cur_down_analyse(EventItem *item, uint8_t idx)
{
    uint16_t max_volt = bms_get_statistic_data(kStatisticData_MaxVolt);
    uint16_t volt = get_eeprom_data(kEep_ChgSndCurDownVolt, kEepromDataType_Full);
    
    item->enable_cond = ((volt > 0) && (max_volt >= volt) && (bms_get_run_status() == kRunStatus_Chg));
    item->disable_cond = (bms_get_run_status() != kRunStatus_Chg);
}


void bms_init_signal(void)
{    
    uint32_t i;
    uint32_t tmp = get_eeprom_data(kEep_ChgCurThreshold_KeepTime, kEepromDataType_Low) * 1000;
	
    for(i = kSignalIdx_DiStart; i < kSignalIdx_DiEnd; i++)
    {
		bsp_event_register(&signal_event, 200,  500,  bms_sw_signal_low_valid_analyse);     
    }
	
	//gary @update 20240718 删除无用信号注册，整理信号注册
	bsp_event_register(&signal_event, 200,  500,  bms_on_signal_analyse);
	bsp_event_register(&signal_event, 200,  500,  bms_on_signal_analyse);
	bsp_event_register(&signal_event, 200,  500,  bms_on_signal_analyse);
	bsp_event_register(&signal_event, 200,  500,  bms_on_signal_analyse);

	bsp_event_register(&signal_event, tmp,  1000,  bms_chg_cur_analyse);
    bsp_event_register(&signal_event, tmp,  1000,  bms_dis_cur_analyse);
    bsp_event_register(&signal_event, 1000, 1000,  bms_volt_temp_point1_analyse);
	
	bsp_event_register(&signal_event, 2000,  1000,   bms_heat_analyse);
    bsp_event_register(&signal_event, 2000,  1000,   bms_cool_analyse);
	
	//tmp = get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Low) * 60 * 1000;
    //bsp_event_register(&signal_event, tmp,  500,   bms_low_volt_sleep_analyse);
    //tmp = get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Low) * 24 * 6 * 60 * 1000;
	//tmp = get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Full) * 60 * 60 * 100;
	tmp = get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Full) * 60 * 1000;
    bsp_event_register(&signal_event, tmp,  500,   bms_standby_sleep_analyse);

    bsp_event_register(&signal_event, 1000,  1000,   bms_forbid_dis_analyse);

    
    bsp_event_register(&signal_event, 1000,  1000,   bms_forbid_chg_analyse);
    bsp_event_register(&signal_event, 1000,  5000,   bms_chg_1st_cur_down_analyse);
    bsp_event_register(&signal_event, 1000,  5000,   bms_chg_2nd_cur_down_analyse);
    
    //上电连续检测30次用于上电自检使用
    for(i = 0; i < 30; i++)
    {
        bms_poll_signal(100);
        bsp_task_delay_ms(10);
    }
}

void bms_poll_signal(uint32_t base_time)
{
    bsp_event_poll(&signal_event, base_time);
}

SignalStatus bms_get_signal(SignalIdx idx)
{
    SignalStatus st = kSignalStatus_Err;
	
    KIT_ASSERT_PARAM(idx < kSignalIdx_End);
	
	if(idx < kSignalIdx_End)
	{
		st = (SignalStatus)(KIT_GET_BIT_32(signal_event.flag, idx) != 0);
	}
	
    return st;
}

void bms_set_signal(SignalIdx idx, SignalStatus st)
{
    if(idx < kSignalIdx_End)
    {
        if(st == kSignalStatus_High)
        {
            KIT_SET_BIT_MASK_32(signal_event.flag, idx);
        }
        else if(st == kSignalStatus_Low)
        {
            KIT_CLR_BIT_32(signal_event.flag, idx);
        }
    }
}

uint32_t bms_get_signal_flag(void)
{
    return signal_event.flag;
}



