618 lines
22 KiB
C
618 lines
22 KiB
C
#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(2))
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
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);
|
|
}
|
|
|