diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index 5cf69df2..082e53db 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -48,6 +48,7 @@ #define OVER_VOLT_TIME 15000 #define LOW_CELL_TIME 15000 #define HIGH_TEMP_TIME 60000 +#define INT_CELL_COMM_TIME 1000 #define CURR_ERR_MARG 50 // in A * 10 #define DCDC_CURRENT_DRAW 2 // in A, this is generous diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index b16a2694..b852a643 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -5,6 +5,9 @@ #include "bmsConfig.h" #include "datastructs.h" +// global that passes cell comm faults upstream to sm +bool cell_comm_fault_status; + /** * @brief Initializes the segments */ diff --git a/Core/Inc/stateMachine.h b/Core/Inc/stateMachine.h index f007520c..c9f40fe9 100644 --- a/Core/Inc/stateMachine.h +++ b/Core/Inc/stateMachine.h @@ -7,7 +7,7 @@ #include "analyzer.h" #include "timer.h" -#define NUM_FAULTS 8 +#define NUM_FAULTS 9 /** * @brief Returns if we want to balance cells during a particular frame diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 6fe8cd6d..a7f86637 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -25,8 +25,8 @@ nertimer_t therm_timer; nertimer_t voltage_reading_timer; nertimer_t variance_timer; -int voltage_error = 0; //not faulted -int therm_error = 0; //not faulted +int voltage_error = FAULTS_CLEAR; +int therm_error = FAULTS_CLEAR; uint16_t therm_settle_time_ = 0; @@ -69,6 +69,8 @@ void segment_init() local_config[c][5] = 0x00; } push_chip_configuration(); + + cell_comm_fault_status = false; } void select_therm(uint8_t therm) @@ -199,7 +201,7 @@ int pull_voltages() memcpy(segment_data[i].voltage_reading, previous_data[i].voltage_reading, sizeof(segment_data[i].voltage_reading)); } - return 1; + return 1; //error } /* If the read was successful, copy the voltage data */ @@ -223,7 +225,7 @@ int pull_voltages() /* Start the timer between readings if successful */ start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); - return 0; + return 0; /* Read Succesfully */ } int pull_thermistors() @@ -301,6 +303,8 @@ void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]) * data */ memcpy(previous_data, segment_data, sizeof(chipdata_t) * NUM_CHIPS); + cell_comm_fault_status = (voltage_error || therm_error); + segment_data = NULL; } diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index d116cd7d..50d06100 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -206,6 +206,7 @@ uint32_t sm_fault_return(acc_data_t* accData) static nertimer_t ovr_volt_timer = {0}; static nertimer_t low_cell_timer = {0}; static nertimer_t high_temp_timer = {0}; + static nertimer_t int_cell_comm_tmr = {0}; static fault_eval_t* fault_table = NULL; static acc_data_t* fault_data = NULL; @@ -219,12 +220,13 @@ uint32_t sm_fault_return(acc_data_t* accData) // ___________FAULT ID____________ __________TIMER___________ _____________DATA________________ __OPERATOR__ __________________________THRESHOLD____________________________ _______TIMER LENGTH_________ _____________FAULT CODE_________________ ___OPERATOR 2__ _______________DATA 2______________ __THRESHOLD 2__ fault_table[0] = (fault_eval_t) {.id = "Discharge Current Limit", .timer = ovr_curr_timer, .data_1 = fault_data->pack_current, .optype_1 = GT, .lim_1 = (fault_data->discharge_limit + DCDC_CURRENT_DRAW)*10*1.04, .timeout = OVER_CURR_TIME, .code = DISCHARGE_LIMIT_ENFORCEMENT_FAULT, .optype_2 = NOP/* ---------------------------UNUSED------------------- */ }; fault_table[1] = (fault_eval_t) {.id = "Charge Current Limit", .timer = ovr_chgcurr_timer, .data_1 = fault_data->pack_current, .optype_1 = GT, .lim_1 = (fault_data->charge_limit)*10, .timeout = OVER_CHG_CURR_TIME, .code = CHARGE_LIMIT_ENFORCEMENT_FAULT, .optype_2 = LT, .data_2 = fault_data->pack_current, .lim_2 = 0 }; - fault_table[2] = (fault_eval_t) {.id = "Low Cell Voltage", .timer = undr_volt_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = MIN_VOLT * 10000, .timeout = UNDER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_LOW, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; - fault_table[3] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_chgvolt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_CHARGE_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; - fault_table[4] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_volt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = EQ, .data_2 = fault_data->is_charger_connected, .lim_2 = false }; - fault_table[5] = (fault_eval_t) {.id = "High Temp", .timer = high_temp_timer, .data_1 = fault_data->max_temp.val, .optype_1 = GT, .lim_1 = MAX_CELL_TEMP, .timeout = LOW_CELL_TIME, .code = PACK_TOO_HOT, .optype_2 = NOP/* ----------------------------------------------------*/ }; - fault_table[6] = (fault_eval_t) {.id = "Extremely Low Voltage", .timer = low_cell_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = 900, .timeout = HIGH_TEMP_TIME, .code = LOW_CELL_VOLTAGE, .optype_2 = NOP/* --------------------------UNUSED--------------------*/ }; - fault_table[7] = (fault_eval_t) {.id = NULL}; + fault_table[2] = (fault_eval_t) {.id = "Low Cell Voltage", .timer = undr_volt_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = MIN_VOLT * 10000, .timeout = UNDER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_LOW, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; + fault_table[3] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_chgvolt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_CHARGE_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; + fault_table[4] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_volt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = EQ, .data_2 = fault_data->is_charger_connected, .lim_2 = false }; + fault_table[5] = (fault_eval_t) {.id = "High Temp", .timer = high_temp_timer, .data_1 = fault_data->max_temp.val, .optype_1 = GT, .lim_1 = MAX_CELL_TEMP, .timeout = LOW_CELL_TIME, .code = PACK_TOO_HOT, .optype_2 = NOP/* ----------------------------------------------------*/ }; + fault_table[6] = (fault_eval_t) {.id = "Internal Cell Comm Fault",.timer = int_cell_comm_tmr, .data_1 = cell_comm_fault_status, .optype_1 = NEQ,.lim_1 = FAULTS_CLEAR, .timeout = INT_CELL_COMM_TIME, .code = INTERNAL_CELL_COMM_FAULT, .optype_2 = NOP/* --------------------------UNUSED--------------------*/ }; + fault_table[7] = (fault_eval_t) {.id = "Extremely Low Voltage", .timer = low_cell_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = 900, .timeout = HIGH_TEMP_TIME, .code = LOW_CELL_VOLTAGE, .optype_2 = NOP/* --------------------------UNUSED--------------------*/ }; + fault_table[8] = (fault_eval_t) {.id = NULL}; // clang-format on } uint32_t fault_status = 0;