#include "iso_check.h"
#include "dido_manager.h"
#include "fault_manager.h"
#include "eeprom_manager.h"
#include "hv_adc_manager.h"
#include "flash_manager.h"
#include "signal_manager.h"
#include "statistic_manager.h"


void bms_dis_low_volt_ht_call(uint8_t level, uint16_t data, bool *cond, uint16_t *threshold)
{
    bool temp_cond = (bms_get_signal(kSignalIdx_HTPoint1) == kSignalStatus_High);
    cond[kCondType_Alarm] = temp_cond && (data <= threshold[kCondType_Alarm]);
    cond[kCondType_Release] = temp_cond && (data >= threshold[kCondType_Release]);
}

void bms_dis_low_volt_lt_call(uint8_t level, uint16_t data, bool *cond, uint16_t *threshold)
{
    bool temp_cond = (bms_get_signal(kSignalIdx_HTPoint1) == kSignalStatus_Low);
    cond[kCondType_Alarm] = temp_cond && (data <= threshold[kCondType_Alarm]);
    cond[kCondType_Release] = temp_cond && (data >= threshold[kCondType_Release]);
}



void bms_dis_high_cur_call(uint8_t level, uint16_t data, bool *cond, uint16_t *threshold)
{
    int16_t cur = bms_get_current();
    cond[kCondType_Alarm] = (cur < 0) && (data >= threshold[kCondType_Alarm]);
    cond[kCondType_Release] = (cur >= 0) || (data <= threshold[kCondType_Release]);
}



const FaultProp dis_fault_array[] = 
{
  {kFaultCode_LowISO,  		3,	kFaultData_Insulation,    kEep_LInsuAlarm1,           kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_HighT1Temp,		1,  kFaultData_T1Temp,        kEep_HT1TempAlarm1Alarm1, 	 kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_LowT1Temp,		1,  kFaultData_T1Temp,        kEep_LT1TempAlarm1,         kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_HighT2Temp,		1,  kFaultData_T2Temp,        kEep_HT2TempAlarm1Alarm1,   kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_LowT2Temp,		1,  kFaultData_T2Temp,        kEep_LT2TempAlarm1,         kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},	
	//{kFaultCode_SupplyHighVolt,	1,  kFaultData_SupplyVolt,    kEep_HSplVoltAlarm1,        kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},	
	//{kFaultCode_SupplyLowVolt,	1,  kFaultData_SupplyVolt,    kEep_LSplVoltAlarm1,        kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},	
	{kFaultCode_HvDiffErr,	    1,  kFaultData_HighVoltDiffer,kEep_HighVoltDiffAlarm1,    kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_VoltCable,      1,  kFaultData_VoltCable,     kEep_VCableAlarm1,          kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
    {kFaultCode_TempCable,      1,  kFaultData_TempCable,     kEep_TCableAlarm1,          kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},	
    {kFaultCode_MSComm,	        1,  kFaultData_MScomm,        kEep_MSCommAlarm1,          kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},	
	{kFaultCode_CmdTimeout,		1,	kFaultData_CmdHeart,	  kEep_CmdTimeoutAlarm,	     kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,	NULL},
	
  {kFaultCode_LowTotalVolt,   3,  kFaultData_TotalVolt,     kEep_DisLTVoltHTAlarm1,     kCheckType_LessThan,    bms_dis_low_volt_ht_call}, //10
	{kFaultCode_LowTotalVolt,   3,  kFaultData_TotalVolt,     kEep_DisLTVoltLTAlarm1,     kCheckType_LessThan,    bms_dis_low_volt_lt_call}, //11
  {kFaultCode_LowCellVolt,	3,  kFaultData_MinVolt,       kEep_DisLCVoltHTAlarm1,     kCheckType_LessThan,    bms_dis_low_volt_ht_call},   //12
	{kFaultCode_LowCellVolt,	3,  kFaultData_MinVolt,       kEep_DisLCVoltLTAlarm1,     kCheckType_LessThan,    bms_dis_low_volt_lt_call},   //13
	{kFaultCode_HighCellVolt,	3,  kFaultData_MaxVolt,       kEep_DisHCVoltAlarm1,     	 kCheckType_MoreThan,    NULL},
	{kFaultCode_HighCur,        3,  kFaultData_Current,       kEep_DisOverCurAlarm1,      kCheckType_MoreThan,    bms_dis_high_cur_call},
  {kFaultCode_HighCellTemp,	3,  kFaultData_MaxTemp,       kEep_DisHighTempAlarm1,     kCheckType_MoreThan,    NULL},
  {kFaultCode_LowCellTemp,	3,  kFaultData_MinTemp,       kEep_DisLowTempAlarm1,      kCheckType_LessThan,    NULL},
  {kFaultCode_HighVoltDiff,	3,  kFaultData_VoltDiff,      kEep_DisHVDiffAlarm1,       kCheckType_MoreThan,    NULL},
  {kFaultCode_HighTempDiff,	3,  kFaultData_TempDiff,      kEep_DisHTDiffAlarm1,       kCheckType_MoreThan,    NULL},    
  {kFaultCode_LowSOC,         3,  kFaultData_SOC,           kEep_DisLowSocAlarm1,       kCheckType_LessThan,    NULL},
  {kFaultCode_HighPoleTemp,   3,  kFaultData_MaxPoleTemp,   kEep_PoleHighTempAlarm1,    kCheckType_MoreThan,    NULL},
    
    //{kFaultCode_LowPackVolt,	3,  kFaultData_MinPackVolt,   kEep_LowPackVoltAlarm1,     kCheckType_LessThan,    NULL},  
};

FAULT_STATIC_INIT_CCM(dis_fault, dis_fault_array);



void bms_chg_high_volt_ht_call(uint8_t level, uint16_t data, bool *cond, uint16_t *threshold)
{
    bool temp_cond = (bms_get_signal(kSignalIdx_HTPoint1) == kSignalStatus_High);
    cond[kCondType_Alarm] = temp_cond && (data >= threshold[kCondType_Alarm]);
    cond[kCondType_Release] = temp_cond && (data <= threshold[kCondType_Release]);
}

void bms_chg_high_volt_lt_call(uint8_t level, uint16_t data, bool *cond, uint16_t *threshold)
{
    bool temp_cond = (bms_get_signal(kSignalIdx_HTPoint1) == kSignalStatus_Low);
    cond[kCondType_Alarm] = temp_cond && (data >= threshold[kCondType_Alarm]);
    cond[kCondType_Release] = temp_cond && (data <= threshold[kCondType_Release]);
}

void bms_chg_high_cur_call(uint8_t level, uint16_t data, bool *cond, uint16_t *threshold)
{
    int32_t cur = bms_get_current();
    cond[kCondType_Alarm] = (cur > 0) && (data >= threshold[kCondType_Alarm]);
    cond[kCondType_Release] = (cur <= 0) || (data <= threshold[kCondType_Release]);
}

const FaultProp chg_fault_array[] = 
{
    {kFaultCode_LowISO,  		3,	kFaultData_Insulation,    kEep_LInsuAlarm1,           kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_HighT1Temp,		1,  kFaultData_T1Temp,        kEep_HT1TempAlarm1Alarm1, 	 kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_LowT1Temp,		1,  kFaultData_T1Temp,        kEep_LT1TempAlarm1,         kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_HighT2Temp,		1,  kFaultData_T2Temp,        kEep_HT2TempAlarm1Alarm1,   kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_LowT2Temp,		1,  kFaultData_T2Temp,        kEep_LT2TempAlarm1,         kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},
	//{kFaultCode_SupplyHighVolt,	1,  kFaultData_SupplyVolt,    kEep_HSplVoltAlarm1,        kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},	
	//{kFaultCode_SupplyLowVolt,	1,  kFaultData_SupplyVolt,    kEep_LSplVoltAlarm1,        kCheckType_LessThan | FAULT_RELAY_BOTH_OFF,    NULL},	
	{kFaultCode_HvDiffErr,		1,  kFaultData_HighVoltDiffer,kEep_HighVoltDiffAlarm1,    kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_VoltCable,      1,  kFaultData_VoltCable,     kEep_VCableAlarm1,          kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
    {kFaultCode_TempCable,      1,  kFaultData_TempCable,     kEep_TCableAlarm1,          kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},	
    {kFaultCode_MSComm,	        1,  kFaultData_MScomm,        kEep_MSCommAlarm1,          kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,    NULL},
	{kFaultCode_CmdTimeout,		1,	kFaultData_CmdHeart,	  kEep_CmdTimeoutAlarm,	 	 kCheckType_MoreThan | FAULT_RELAY_BOTH_OFF,	NULL},
	
    {kFaultCode_HighTotalVolt,	3,  kFaultData_TotalVolt,     kEep_ChgHTVoltHTAlarm1,      kCheckType_MoreThan,    bms_chg_high_volt_ht_call}, //10
	{kFaultCode_HighTotalVolt,  3,  kFaultData_TotalVolt,     kEep_ChgHTVoltLTAlarm1,      kCheckType_MoreThan,    bms_chg_high_volt_lt_call},   //11
    {kFaultCode_HighCellVolt,	3,  kFaultData_MaxVolt,       kEep_ChgHCVoltHTAlarm1,      kCheckType_MoreThan,    bms_chg_high_volt_ht_call},   //12
	{kFaultCode_HighCellVolt,	3,  kFaultData_MaxVolt,       kEep_ChgHCVoltLTAlarm1,      kCheckType_MoreThan,    bms_chg_high_volt_lt_call},     //13
	{kFaultCode_LowCellVolt,	3,  kFaultData_MinVolt,       kEep_ChgLCVoltAlarm1,     	  kCheckType_LessThan,    NULL},
	{kFaultCode_HighCur,        3,  kFaultData_Current,       kEep_ChgOverCurAlarm1,       kCheckType_MoreThan,    bms_chg_high_cur_call},
	{kFaultCode_HighCellTemp,   3,  kFaultData_MaxTemp,       kEep_ChgHighTempAlarm1,      kCheckType_MoreThan,    NULL},
    {kFaultCode_LowCellTemp,    3,  kFaultData_MinTemp,       kEep_ChgLowTempAlarm1,       kCheckType_LessThan,    NULL},
    {kFaultCode_HighVoltDiff,   3,  kFaultData_VoltDiff,      kEep_ChgHVDiffAlarm1,        kCheckType_MoreThan,    NULL},
    {kFaultCode_HighTempDiff,   3,  kFaultData_TempDiff,      kEep_ChgHTDiffAlarm1,        kCheckType_MoreThan,    NULL},
    {kFaultCode_HighPoleTemp,   3,  kFaultData_MaxPoleTemp,   kEep_PoleHighTempAlarm1,    kCheckType_MoreThan,    NULL},
    
    //{kFaultCode_HighPackVolt,	3,  kFaultData_MaxPackVolt,   kEep_HighPackVoltAlarm1,    kCheckType_MoreThan,    NULL},
};
FAULT_STATIC_INIT_CCM(chg_fault, chg_fault_array);

void bms_check_dis_run_fault(RunStatus status, uint32_t base_time)
{       
	bms_analyse_fault(status, &dis_fault);
}



void bms_check_chg_run_fault(RunStatus status, uint32_t base_time)
{
	bms_analyse_fault(status, &chg_fault);
}


void bms_check_pwr_on_fault(uint32_t base_time)
{
    uint32_t dis_tmp_32u, chg_tmp_32u;
    
    dis_tmp_32u = get_eeprom_data(kEep_DisSelfFaultLow, kEepromDataType_Double);
    chg_tmp_32u = get_eeprom_data(kEep_ChgSelfFaultLow, kEepromDataType_Double);

    bms_analyse_pwr_on_fault(kRunStatus_Dis, &dis_fault, dis_tmp_32u);
	bms_analyse_pwr_on_fault(kRunStatus_Chg, &chg_fault, chg_tmp_32u);
}
