#include "bmu_manager.h"
#include "adc_manager.h"
#include "iso_check.h"
#include "soc_calculate.h"
#include "sop_calculate.h"
#include "fault_manager.h"
#include "dido_manager.h"
#include "signal_manager.h"
#include "eeprom_manager.h"
#include "hv_adc_manager.h"
#include "statistic_manager.h"
#include "run_status.h"

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


typedef struct
{
    bool        is_bsu_fault;
    uint8_t     fault_cur_rate[2];
    uint16_t    fault_bit[8];
    FaultLevel  max_level[2];
    FaultLevel  min_level[2];
    uint8_t  	fault_res[2][kFaultCode_End]; //高4位为故障bit,低4位为故障最高等级
    ExStatus 	fault_ex[kExType_End];
    uint16_t 	fault_data[kFaultData_End];
    uint64_t    relay_off_bit[2][kFaultLevel_End - 1];
}FaultItem;
FaultItem fault_item  __attribute__((section (".CCM_RAM")));

uint8_t is_afe_happen = 0;
void bms_update_fault_data(uint32_t base_time)
{
//    uint16_t tmp;
    int16_t acc_tv = 0, sample_tv = 0;
    
    if(true)
    {
        fault_item.fault_data[kFaultData_SOC] = bms_get_soc() / 100;
        fault_item.fault_data[kFaultData_Current] = KIT_ABS(bms_get_current());
        fault_item.fault_data[kFaultData_MaxVolt] = bms_get_statistic_data(kStatisticData_MaxVolt);
        fault_item.fault_data[kFaultData_MinVolt] = bms_get_statistic_data(kStatisticData_MinVolt);
        fault_item.fault_data[kFaultData_VoltDiff] = bms_get_statistic_data(kStatisticData_VoltDiff);
        fault_item.fault_data[kFaultData_MaxTemp] = bms_get_statistic_data(kStatisticData_MaxTemp) * 10 + 500;
        fault_item.fault_data[kFaultData_MinTemp] = bms_get_statistic_data(kStatisticData_MinTemp) * 10 + 500;
        fault_item.fault_data[kFaultData_TempDiff] = bms_get_statistic_data(kStatisticData_TempDiff);
        fault_item.fault_data[kFaultData_EnviTemp] = bms_get_statistic_data(kStatisticData_EnviTemp);		//环境温度
        fault_item.fault_data[kFaultData_TempRise] = fault_item.fault_ex[kExType_TempRise];	                //温升
        fault_item.fault_data[kFaultData_TotalVolt] = bms_get_statistic_data(kStatisticData_TotalVolt);
        
        fault_item.fault_data[kFaultData_Insulation] = bms_get_iso_data(kIsoData_Value);
        fault_item.fault_data[kFaultData_MScomm] = (bms_get_bmu_fault_bit(kBmuFaultBit_Offline) != 0);
        fault_item.fault_data[kFaultData_VoltCable] = (bms_get_bmu_fault_bit(kBmuFaultBit_VoltCable) != 0);
        fault_item.fault_data[kFaultData_TempCable] = (bms_get_bmu_fault_bit(kBmuFaultBit_TempCable) != 0);
        
        //fault_item.fault_data[kFaultData_SupplyVolt] = bms_get_adc_data(kAdcData_PwrVolt);
        //tmp = (get_eeprom_data(kEep_EnTempChannel_NtcType, kEepromDataType_High) & 0x01) << 1;
        fault_item.fault_data[kFaultData_T1Temp] = bms_get_en_temp((EnTemp)(kEnTemp_T1)) / 10 * 10;
        fault_item.fault_data[kFaultData_T2Temp] = bms_get_en_temp((EnTemp)(kEnTemp_T2)) / 10 * 10;
        
        acc_tv = bms_get_statistic_data(kStatisticData_TotalVolt);
        sample_tv = bms_get_high_volt(kHvType_Bat);
        fault_item.fault_data[kFaultData_HighVoltDiffer] = KIT_ABS_DIFF(acc_tv, sample_tv);//高压异常

        fault_item.fault_data[kFaultData_CmdHeart] = (bms_get_cmd_heartbeat() >= 5000);
        
        fault_item.fault_data[kFaultData_MaxPoleTemp] = bms_get_statistic_data(kStatisticData_MaxPoleTemp) * 10;
        fault_item.fault_data[kFaultData_MaxPackVolt] = bms_get_statistic_data(kStatisticData_MaxPackVolt);
        fault_item.fault_data[kFaultData_MinPackVolt] = bms_get_statistic_data(kStatisticData_MaxPackVolt);
        
        if(bms_get_bmu_fault_bit(kBmuFaultBit_Afe) != 0)
        {
			is_afe_happen = 4;
            //bms_set_fault_level(kFaultCode_AFE, kFaultLevel_Third, kFaultHandle_CutRlyIdx);
        }
        
        if(bms_get_bmu_fault_bit(kBmuFaultBit_Msd) != 0)
        {
            bms_set_fault_level(kFaultCode_MSD, kFaultLevel_Third, kFaultHandle_CutRlyIdx);
        }       
    }
}

void bms_set_bsu_fault(bool is_fault)
{
    fault_item.is_bsu_fault = is_fault;
}

bool bms_is_bsu_fault(void)
{
    return fault_item.is_bsu_fault;
}

const uint16_t cell_limit_value[kCellType_End][2] = 
{
    {1500, 3800},   //铁锂极限值
    {2000, 4300},   //三元极限值
    {1000, 3000},   //钛酸锂极限值
    {1000, 3000},   //铅酸极限值
    {0,    3000},   //超级电容极限值
};

//极限故障
void bms_analyse_exterme_fault(RunStatus status, uint32_t base_time)
{
    static uint16_t volt_dly = 0, temp_dly = 0;
    //uint16_t cell_type = get_eeprom_data(kEep_TempType_BatteryType, kEepromDataType_Low);
    uint16_t cell_type = 1;
	
    if(cell_type >= kCellType_End)
    {
        cell_type = kCellType_kLiFePO4;
    }
    
    if((fault_item.fault_data[kFaultData_MaxVolt] >= cell_limit_value[cell_type][1]) 
    || (fault_item.fault_data[kFaultData_MinVolt] <= cell_limit_value[cell_type][0]))
    {
        volt_dly += base_time;
        if(volt_dly >= KIT_SECOND_CONVERT(10))
        {
            bms_set_fault_level_by_status(status, kFaultCode_Exterme, (FaultLevel)(kFaultLevel_End - 1), kFaultHandle_CutNoRelIdx);
            bms_cut_all_relay();
        }
    }
    else
    {
        volt_dly = 0;
    }
    
//    if((fault_item.fault_data[kFaultData_MaxTemp] >= KIT_TEMP_CONVERT(65)) 
//    || (fault_item.fault_data[kFaultData_MinTemp] <= KIT_TEMP_CONVERT(-30)))
//    {
//        temp_dly += base_time;
//        if(temp_dly >= KIT_SECOND_CONVERT(2))
//        {
//            bms_set_fault_level_by_status(status, kFaultCode_Exterme, kFaultLevel_Third, kFaultHandle_CutNoRelIdx);
//            bms_cut_all_relay();
//        }
//    }
//    else
//    {
//        temp_dly = 0;
//    }
}

FaultLevel bms_get_max_fault_level(void)
{
    FaultLevel level1, level2;
    level1 = fault_item.max_level[kRunStatus_Dis];
    level2 = fault_item.max_level[kRunStatus_Chg];
    if(level1 < level2)
    {
        level1 = level2;
    }
    return level1;
}

FaultLevel bms_get_max_fault_level_by_status(RunStatus status)
{
    FaultLevel level = kFaultLevel_Normal;
    
	if(status < 2)
    {
		level = fault_item.max_level[status];
	}
    return level;
}


FaultLevel bms_get_min_fault_level(void)
{
    FaultLevel level1, level2;
    level1 = fault_item.min_level[kRunStatus_Dis];
    level2 = fault_item.min_level[kRunStatus_Chg];
    if(level1 > level2)
    {
        level1 = level2;
    }
    return level1;
}

uint32_t bms_get_total_alarm(uint16_t input)
{
    FaultLevel level;
    level = bms_get_max_fault_level() == kFaultLevel_First || bms_get_max_fault_level() == kFaultLevel_Second;
    return level;
}

uint32_t bms_get_total_fault(uint16_t input)
{
    FaultLevel level;
    level = bms_get_max_fault_level() == kFaultLevel_Third;
    return level;
}

uint8_t bms_get_fault_cur_rate(RunStatus status)
{
    uint8_t rate = 100;
    
	if(status < 2)
    {
		rate = fault_item.fault_cur_rate[status];
	}
    return rate;
}

FaultLevel bms_get_fault_level(FaultCode idx)
{
    FaultLevel level1 = kFaultLevel_Normal, level2;
    if(idx < kFaultCode_End)
    {
        level1 = (FaultLevel)(fault_item.fault_res[kRunStatus_Dis][idx] & 0x0F);
        level2 = (FaultLevel)(fault_item.fault_res[kRunStatus_Chg][idx] & 0x0F);
        if(level1 < level2)
        {
            level1 = level2;
        }
    }
    
    return level1;
}

FaultLevel bms_get_fault_level_by_status(RunStatus status, FaultCode idx)
{
    FaultLevel level = kFaultLevel_Normal;
    if(idx < kFaultCode_End)
    {
        if(status < 2)
        {
            level = (FaultLevel)(fault_item.fault_res[status][idx] & 0x0F);
        }
        else
        {
            level = bms_get_fault_level(idx);
        }
    }
    
    return level;
}

void bms_set_fault_level(FaultCode idx, FaultLevel level, FaultHandle handle)
{
    bms_set_fault_level_by_status(kRunStatus_Dis, idx, level, handle);
    bms_set_fault_level_by_status(kRunStatus_Chg, idx, level, handle);
}

void bms_set_fault_level_by_status(RunStatus status, FaultCode idx, FaultLevel level, FaultHandle handle)
{
    uint16_t tmp;
    if((idx < kFaultCode_End) && (status < 2) && (level < kFaultLevel_End))
    {
        if(level > kFaultLevel_Normal)
        {
            tmp = level;
            KIT_SET_BIT_MASK_32(tmp, (level + 3));
            fault_item.fault_res[status][idx] = tmp;
            
            if(handle >= kFaultHandle_CutRlyIdx)
            {
                tmp = get_eeprom_data(kEep_FaultCntStart + idx, kEepromDataType_Full);
                bsp_eeprom_save_data(kEep_FaultCntStart + idx, tmp++, kEepromDataType_Full);
                KIT_SET_BIT_MASK_64(fault_item.relay_off_bit[status][level - 1], idx);
            }
        }
        else if(handle < kFaultHandle_CutNoRelIdx)
        {
            fault_item.fault_res[status][idx] = 0;
            KIT_CLR_BIT_64(fault_item.relay_off_bit[status][0], idx);
            KIT_CLR_BIT_64(fault_item.relay_off_bit[status][1], idx);
            KIT_CLR_BIT_64(fault_item.relay_off_bit[status][2], idx);
        }
    }
}

uint16_t bms_get_fault_bit(uint8_t idx)
{
    uint16_t res = 0;
    if(idx < 8)
    {
        res = fault_item.fault_bit[idx]; 
    }
    return res;
}

uint16_t bms_get_fault_single_bit(uint8_t index, FaultLevel level)
{
    uint8_t i, offset, value,pos;
    uint16_t fault = 0;
    
    for(i = (index << 4); i < ((index << 4) + 16); i++)
    {
        if(i < kFaultCode_End)
        {           
            pos = i >> 3;
            offset = (i % 8) << 1;
            value = (bms_get_fault_bit(pos) >> offset) &0x0003;
            if(value == level)
                KIT_SET_BIT_MASK_32(fault, i - (index << 4));
            else
                KIT_CLR_BIT_32(fault, i - (index << 4));    
        }
        else
        {
            KIT_CLR_BIT_32(fault, i - (index << 4));
        }
    }
    return fault;
}

void bms_clear_fault_relay_off_bit(FaultCode idx)
{
    KIT_CLR_BIT_64(fault_item.relay_off_bit[kRunStatus_Dis][0], idx);
    KIT_CLR_BIT_64(fault_item.relay_off_bit[kRunStatus_Dis][1], idx);
    KIT_CLR_BIT_64(fault_item.relay_off_bit[kRunStatus_Dis][2], idx);
    KIT_CLR_BIT_64(fault_item.relay_off_bit[kRunStatus_Chg][0], idx);
    KIT_CLR_BIT_64(fault_item.relay_off_bit[kRunStatus_Chg][1], idx);
    KIT_CLR_BIT_64(fault_item.relay_off_bit[kRunStatus_Chg][2], idx);
}

uint64_t bms_get_fault_relay_off_bit(void)
{
    uint64_t tmp = 0;
    tmp |= fault_item.relay_off_bit[kRunStatus_Dis][0] | fault_item.relay_off_bit[kRunStatus_Dis][1] | fault_item.relay_off_bit[kRunStatus_Dis][2];
    tmp |= fault_item.relay_off_bit[kRunStatus_Chg][0] | fault_item.relay_off_bit[kRunStatus_Chg][1] | fault_item.relay_off_bit[kRunStatus_Chg][2];
    return tmp;
}

void bms_clear_fault_relay_off_bit_by_status(RunStatus status, FaultCode idx)
{
    if(status < 2)
    {
        KIT_CLR_BIT_64(fault_item.relay_off_bit[status][0], idx);
        KIT_CLR_BIT_64(fault_item.relay_off_bit[status][1], idx);
        KIT_CLR_BIT_64(fault_item.relay_off_bit[status][2], idx);
    }
}

uint64_t bms_get_fault_relay_off_bit_by_status(RunStatus status)
{
    uint64_t res = 0;
    if(status < 2)
    {
        res = fault_item.relay_off_bit[status][0] | fault_item.relay_off_bit[status][1] | fault_item.relay_off_bit[status][2];
    }
    return res;
}

void bms_clear_fault_code(RunStatus status)
{
    uint32_t i;
    
    if(status < 2)
    {
        for(i = 0; i < kFaultCode_End; i++)
        {
            fault_item.fault_res[status][i] = 0;
        }
        fault_item.relay_off_bit[status][0] = fault_item.relay_off_bit[status][1] = fault_item.relay_off_bit[status][2] = 0;
        fault_item.fault_cur_rate[status] = 100;
        fault_item.max_level[status] = fault_item.min_level[status] = kFaultLevel_Normal;
    }
}

ExStatus bms_get_ex_data(ExType idx)
{
    ExStatus tmp = kExStatus_None;
    if(idx < kExType_End)
    {
        tmp = fault_item.fault_ex[idx];
    }
    
    return tmp;
}

void bms_set_ex_data(ExType idx, ExStatus st)
{
    KIT_ASSERT_PARAM((idx < kExType_End) && (st < kExStatus_End));
    
    if(idx < kExType_End)
    {
        fault_item.fault_ex[idx] = st;
    }
}


#define FAULT_ARARM_THRESHOLD_ADDR(x)           (x)
#define FAULT_ARARM_DLY_THRESHOLD_ADDR(x)       (x + 1)
#define FAULT_RELEASE_THRESHOLD_ADDR(x)         (x + 2)
#define FAULT_RELEASE_DLY_THRESHOLD_ADDR(x)     (x + 3)
#define FAULT_ALARM_HANDLER_ADDR(x)             (x + 4)

//确认任务调度时间与故障时间是否匹配
const FaultLevel alarm_level_map[8] = 
{
    kFaultLevel_Normal, kFaultLevel_First, kFaultLevel_Second, kFaultLevel_Second,
    kFaultLevel_Third,  kFaultLevel_Third, kFaultLevel_Third,  kFaultLevel_Third,
};

void bms_analyse_fault(RunStatus status, FaultArray *fault_array)
{
    uint32_t i, j;
    bool tmp_cond, cond[kCheckType_End];
    uint8_t alarm_bit, alarm_handle, level, check_type, pos, offset;
    uint8_t cur_rate[kFaultLevel_End], max_cur_rate = 100;
    uint16_t idx, tmp, data, threshold[2], handler, fault_bit[16];
    FaultLevel alarm_level, min_level, max_level;
    const FaultProp *prop_array = fault_array->fault_prop_arr;
    FaultParam * param_array = fault_array->fault_param_arr;

    if(status < 2)
    {
        min_level = kFaultLevel_End;
        max_level = kFaultLevel_Normal;
        kit_set_buf(fault_bit, 16, 0);
        for(i = 0; i < fault_array->fault_cnt; i++)
        {
            idx = prop_array[i].fauld_code;        
            alarm_bit = (fault_item.fault_res[status][idx] >> 4);
            level = prop_array[i].level;
            cur_rate[kFaultLevel_Normal] = 100;
            for(j = 0; j < level; j++)
            {
                tmp = prop_array[i].threshold_idx + j * 5;
                handler = get_eeprom_data(FAULT_ALARM_HANDLER_ADDR(tmp), kEepromDataType_Full);
                alarm_handle = handler & 0x0003;
                cur_rate[j + kFaultLevel_End - level] = handler >> 8;
                if(alarm_handle == kFaultHandle_ForbidIdx)//禁用
                {
                    continue;
                }
                else if(alarm_handle != kFaultHandle_ForbidIdx)
                {
                    data = fault_item.fault_data[prop_array[i].data_idx];

                    if (i == 10 || i == 11) 
										{
                        uint16_t cell_threshold_idx = (i == 10) ? prop_array[12].threshold_idx : prop_array[13].threshold_idx;
                        uint16_t cell_threshold = get_eeprom_data(FAULT_ARARM_THRESHOLD_ADDR(cell_threshold_idx + j * 5), kEepromDataType_Full);
                        threshold[kCondType_Alarm] = (cell_threshold * bms_get_cell_num()) / 100;
                        
                        cell_threshold = get_eeprom_data(FAULT_RELEASE_THRESHOLD_ADDR(cell_threshold_idx + j * 5), kEepromDataType_Full);
                        threshold[kCondType_Release] = (cell_threshold * bms_get_cell_num()) / 100;
                    } 
										else 
										{
                        threshold[kCondType_Alarm] = get_eeprom_data(FAULT_ARARM_THRESHOLD_ADDR(tmp), kEepromDataType_Full);
                        threshold[kCondType_Release] = get_eeprom_data(FAULT_RELEASE_THRESHOLD_ADDR(tmp), kEepromDataType_Full);
                    }

                    if(prop_array[i].other_cond == NULL) //如果没有其他故障判断策略，默认模版策略
                    {
                        check_type = prop_array[i].check_type & 0x03;
                        cond[kCheckType_MoreThan] = (data >= threshold[kCondType_Alarm]);
                        cond[kCheckType_LessThan] = (data <= threshold[kCondType_Alarm]);
                        tmp_cond = cond[check_type];
                        cond[kCheckType_MoreThan] = (data <= threshold[kCondType_Release]);
                        cond[kCheckType_LessThan] = (data >= threshold[kCondType_Release]);

                        cond[kCondType_Release] = cond[check_type];
                        cond[kCondType_Alarm] = tmp_cond;
                    }
                    else //其他故障判断策略
                    {
                        prop_array[i].other_cond(j, data, cond, threshold);
                    }

                    if(cond[kCondType_Alarm] == true)
                    {
                        param_array[i].release_tick[j] = 0;
                        param_array[i].alarm_tick[j] ++;
                        data = get_eeprom_data(FAULT_ARARM_DLY_THRESHOLD_ADDR(tmp), kEepromDataType_Full);
                        if(param_array[i].alarm_tick[j] >= data)
                        {
                            //对于只有一个等级的故障，需要置最高等级
                            KIT_SET_BIT_MASK_32(alarm_bit, j + kFaultLevel_End - 1 - level);
                            //KIT_SET_BIT_MASK_32(alarm_bit, j);
                            param_array[i].alarm_tick[j] = data;
                            if((KIT_GET_BIT_64(fault_item.relay_off_bit[status][j], idx) == 0) && (alarm_handle >= kFaultHandle_CutRlyIdx))
                            {
                                //data = get_eeprom_data(kEep_FaultCntStart + idx, kEepromDataType_Full);
                                //bsp_eeprom_save_data(kEep_FaultCntStart + idx, ++data, kEepromDataType_Full);
                                KIT_SET_BIT_MASK_64(fault_item.relay_off_bit[status][j], idx);
                                if((prop_array[i].check_type & FAULT_RELAY_BOTH_OFF) == FAULT_RELAY_BOTH_OFF)
                                {
                                    KIT_SET_BIT_MASK_64(fault_item.relay_off_bit[1 - status][j], idx);
                                }
                            }
                        }
                    }
                    else
                    {
                        param_array[i].alarm_tick[j] = 0;
                        if((alarm_handle != kFaultHandle_CutNoRelIdx)
                       && (KIT_GET_BIT_32(alarm_bit, j + kFaultLevel_End - 1 - level) != 0 ))
                        {
                            if(cond[kCondType_Release]== true)
                            {
                                param_array[i].release_tick[j] ++;
                                data = get_eeprom_data(FAULT_RELEASE_DLY_THRESHOLD_ADDR(tmp), kEepromDataType_Full);
                                if(param_array[i].release_tick[j] >= data)
                                {
                                    KIT_CLR_BIT_32(alarm_bit, j + kFaultLevel_End - 1 - level);
                                    param_array[i].release_tick[j] = data;
                                    if(alarm_handle < kFaultHandle_CutNoRelIdx)
                                    {
                                        KIT_CLR_BIT_64(fault_item.relay_off_bit[status][j], idx);
                                        if((prop_array[i].check_type & FAULT_RELAY_BOTH_OFF) == FAULT_RELAY_BOTH_OFF)
                                        {
                                            KIT_CLR_BIT_64(fault_item.relay_off_bit[1 - status][j], idx);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                param_array[i].release_tick[j] = 0;
                            }                        
                        }
                    }
                }
            }
            
            alarm_level = alarm_level_map[alarm_bit & 0x07];
            fault_item.fault_res[status][idx] = ((alarm_bit << 4) | (alarm_level & 0x07));
            
            if(cur_rate[alarm_level] < max_cur_rate)
            {
                max_cur_rate = cur_rate[alarm_level];
            }
        }
        
        for(i = 0; i < kFaultCode_End; i++)
        {
            alarm_level = (FaultLevel)(fault_item.fault_res[status][i] & 0x0F);
            if(max_level < alarm_level)
            {
                max_level = alarm_level;
            }
            else if(min_level > alarm_level)
            {
                min_level = alarm_level;
            }
            //判断另外运行状态中对应故障是否大于次状态故障
            tmp = fault_item.fault_res[1 - status][i] & 0x0F;
            if(alarm_level < tmp)
            {
                alarm_level = (FaultLevel)tmp;
            }
            
            pos = i >> 3;
            offset = (i % 8) << 1;
            fault_bit[pos] |= alarm_level << offset;
        }

        fault_item.min_level[status] = min_level;
        fault_item.max_level[status] = max_level;
        fault_item.fault_cur_rate[status] = max_cur_rate;
        
        kit_copy_buf(fault_item.fault_bit, fault_bit, 16);
        
        if(max_cur_rate == 0)
        {
            if(status == kRunStatus_Chg)
            {
                bms_set_chg_forbid_status();
            }
            else if(status == kRunStatus_Dis)
            {
                bms_set_dis_forbid_status();
            }
        }
        
    }
    bms_analyse_exterme_fault(status, FAULT_PERIOD);
}

#define PWR_ON_FAULT_CHECK_MAP_LEN  22
const uint8_t fault_bit_res[3] = {0x11, 0x32, 0x73};
const FaultCode pwr_on_fault_check_map[PWR_ON_FAULT_CHECK_MAP_LEN] = 
{
    kFaultCode_HighTotalVolt, kFaultCode_LowTotalVolt, kFaultCode_HighCellVolt, kFaultCode_LowCellVolt, kFaultCode_HighCellTemp, kFaultCode_LowCellTemp,
    kFaultCode_HighVoltDiff, kFaultCode_HighTempDiff, kFaultCode_HvDiffErr, kFaultCode_DoAdhesion, kFaultCode_SupplyHighVolt, kFaultCode_SupplyLowVolt,
    kFaultCode_AFE, kFaultCode_Eeprom, kFaultCode_Rtc, kFaultCode_Adc, kFaultCode_SD, kFaultCode_Feedback, kFaultCode_Stop, kFaultCode_Fire,
    kFaultCode_HighPackVolt, kFaultCode_LowPackVolt,
};
void bms_analyse_pwr_on_fault(RunStatus status, FaultArray *fault_array, uint32_t enable_bit)
{
	uint32_t i, j;
    uint16_t idx, tmp, data, threshold[2];
    bool     cond[kCheckType_End];
	uint8_t pos, offset, fault_bit[16];
    bool     enable_check[kFaultCode_End];
    const FaultProp *prop_array = fault_array->fault_prop_arr;
    
	kit_set_buf(fault_bit, 16, 0);
    kit_set_buf(enable_check, kFaultCode_End, false);
    for(i = 0; i < PWR_ON_FAULT_CHECK_MAP_LEN; i++)
    {
        idx = pwr_on_fault_check_map[i];
        if(KIT_GET_BIT_32(enable_bit, i) != 0)
        {
            enable_check[idx] = true;
        }
    }
    
    for(i = 0; i < fault_array->fault_cnt; i++)
    {
        idx = prop_array[i].fauld_code;
        j = prop_array[i].level - 1;

        tmp = prop_array[i].threshold_idx + j * 5;
        if(enable_check[idx] == true)
        {
            data = fault_item.fault_data[prop_array[i].data_idx];
            threshold[kCondType_Alarm] = get_eeprom_data(FAULT_ARARM_THRESHOLD_ADDR(tmp), kEepromDataType_Full);
            if(prop_array[i].other_cond == NULL)
            {
                cond[kCheckType_MoreThan] = (data >= threshold[kCondType_Alarm]);
                cond[kCheckType_LessThan] = (data <= threshold[kCondType_Alarm]);
                cond[kCondType_Alarm] = cond[prop_array[i].check_type & 0x03];
            }
            else
            {
                prop_array[i].other_cond(j, data, cond, threshold);
            }

            if((cond[kCondType_Alarm] == true) && (KIT_GET_BIT_64(fault_item.relay_off_bit[status][j], idx) == 0))
            {
                fault_item.fault_res[status][idx] = 0x43;
                fault_item.max_level[status] = (FaultLevel)(kFaultLevel_End - 1);
                KIT_SET_BIT_MASK_64(fault_item.relay_off_bit[status][j], idx);
                
                pos = i >> 3;
                offset = (i % 8) << 1;
                fault_bit[pos] |= 3 << offset;
                //data = get_eeprom_data(kEep_FaultCntStart + idx, kEepromDataType_Full);
                //bsp_eeprom_save_data(kEep_FaultCntStart + idx, ++data, kEepromDataType_Full);
            }
        }
    }
	kit_copy_buf(fault_item.fault_bit, fault_bit, 16);
}

