refactor: more work on error handling
This commit is contained in:
parent
53a9597fe8
commit
522ef539be
@ -7,14 +7,7 @@
|
||||
#define ERROR_TIME_THRESH 150 // ms
|
||||
|
||||
typedef enum : uint16_t {
|
||||
ADBMS_OK = 0x00, // same as STM32 HAL status
|
||||
ADBMS_ERROR = 0x01, //
|
||||
ADBMS_BUSY = 0x02, //
|
||||
ADBMS_TIMEOUT = 0x03 //
|
||||
} ADBMS_StatusTypeDef;
|
||||
|
||||
typedef enum : uint16_t {
|
||||
ADBMS_NONE = 0,
|
||||
ADBMS_NO_ERROR = 0,
|
||||
ADBMS_OVERTEMP,
|
||||
ADBMS_UNDERTEMP,
|
||||
ADBMS_OVERVOLT,
|
||||
@ -25,11 +18,11 @@ typedef enum : uint16_t {
|
||||
ADBMS_INTERNAL_BMS_OVERTEMP,
|
||||
ADBMS_INTERNAL_BMS_FAULT,
|
||||
NUM_ERROR_KINDS
|
||||
} ADBMS_ErrorKind;
|
||||
} ADBMS_Status;
|
||||
|
||||
typedef struct {
|
||||
ADBMS_StatusTypeDef status : 16;
|
||||
ADBMS_ErrorKind error : 16; // zero if status is ADBMS_OK
|
||||
ADBMS_Status status : 16;
|
||||
int16_t bms_id : 16; // the BMS that caused the error, zero if no error, -1 if unknown BMS
|
||||
} ADBMS_DetailedStatus;
|
||||
|
||||
typedef struct {
|
||||
|
@ -11,8 +11,8 @@
|
||||
static_assert(sizeof(error_sources) * CHAR_BIT >= NUM_ERROR_KINDS,
|
||||
"error_sources is too small to hold all error sources");
|
||||
|
||||
void set_error_source(ADBMS_ErrorKind source);
|
||||
void clear_error_source(ADBMS_ErrorKind source);
|
||||
void set_error_source(ADBMS_Status source);
|
||||
void clear_error_source(ADBMS_Status source);
|
||||
|
||||
|
||||
#endif //AMS_MASTER_CODE_ADBMS_ERROR_H
|
||||
|
@ -4,14 +4,14 @@
|
||||
SlaveErrorData error_data[NUM_ERROR_KINDS] = {};
|
||||
uint32_t error_sources = 0;
|
||||
|
||||
void set_error_source(ADBMS_ErrorKind source) {
|
||||
void set_error_source(ADBMS_Status source) {
|
||||
if (!(error_sources & (1 << source))) {
|
||||
error_data[source].errors_since = HAL_GetTick();
|
||||
}
|
||||
error_sources |= (1 << source);
|
||||
}
|
||||
|
||||
void clear_error_source(ADBMS_ErrorKind source) {
|
||||
void clear_error_source(ADBMS_Status source) {
|
||||
error_data[source].errors_since = 0;
|
||||
error_sources &= ~(1 << source);
|
||||
}
|
||||
|
@ -35,14 +35,14 @@ struct pollingTimes {
|
||||
|
||||
struct pollingTimes pollingTimes = {0, 0};
|
||||
|
||||
static constexpr ADBMS_DetailedStatus NO_ERROR = {ADBMS_OK, ADBMS_NONE};
|
||||
static constexpr ADBMS_DetailedStatus NO_ERROR = {ADBMS_NO_ERROR};
|
||||
|
||||
ADBMS_DetailedStatus AMS_Init(SPI_HandleTypeDef* hspi) {
|
||||
debug_log(LOG_LEVEL_INFO, "ADBMS6830B HAL - configured for %d controllers and %d cells per controller...", N_BMS,
|
||||
numberofCells);
|
||||
if (initAMS(hspi) != HAL_OK) {
|
||||
debug_log(LOG_LEVEL_ERROR, "ADBMS6830B HAL - initialization failed");
|
||||
return (ADBMS_DetailedStatus){ADBMS_ERROR, ADBMS_INTERNAL_BMS_FAULT};
|
||||
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT};
|
||||
}
|
||||
|
||||
pollingTimes = (struct pollingTimes){HAL_GetTick(), HAL_GetTick()};
|
||||
@ -51,13 +51,15 @@ ADBMS_DetailedStatus AMS_Init(SPI_HandleTypeDef* hspi) {
|
||||
|
||||
#define any(x) \
|
||||
({ \
|
||||
uint32_t any = false; \
|
||||
static_assert(sizeof(any) * CHAR_BIT >= N_BMS, "any datatype needs to be larger!"); \
|
||||
int first_match = -1; \
|
||||
for (size_t __any_intern_i = 0; __any_intern_i < N_BMS; __any_intern_i++) { \
|
||||
Cell_Module module = modules[__any_intern_i]; \
|
||||
any |= ((x) ? 1 : 0) << __any_intern_i; \
|
||||
if (x) { \
|
||||
first_match = __any_intern_i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
any; \
|
||||
first_match; \
|
||||
})
|
||||
|
||||
ADBMS_DetailedStatus AMS_Idle_Loop() {
|
||||
@ -68,10 +70,11 @@ ADBMS_DetailedStatus AMS_Idle_Loop() {
|
||||
|
||||
packetChecksumFails += amsAuxAndStatusMeasurement(&modules);
|
||||
|
||||
if (any(module.status.SLEEP)) {
|
||||
static int match = 0;
|
||||
if ((match = any(module.status.SLEEP))) {
|
||||
deviceSleeps++;
|
||||
if (deviceSleeps > MAX_DEVICE_SLEEP) {
|
||||
return (ADBMS_DetailedStatus){ADBMS_ERROR, ADBMS_INTERNAL_BMS_TIMEOUT};
|
||||
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_TIMEOUT, match};
|
||||
} else {
|
||||
amsReset();
|
||||
}
|
||||
@ -88,54 +91,29 @@ ADBMS_DetailedStatus AMS_Idle_Loop() {
|
||||
// iteration.
|
||||
amsClearFlag();
|
||||
|
||||
return (ADBMS_DetailedStatus){ADBMS_ERROR, ADBMS_INTERNAL_BMS_FAULT};
|
||||
} else {
|
||||
// clear_error_source(SEK_INTERNAL_BMS_FAULT);
|
||||
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT, match};
|
||||
}
|
||||
|
||||
packetChecksumFails += amsCellMeasurement(&modules);
|
||||
packetChecksumFails += amsCheckUnderOverVoltage(&modules);
|
||||
|
||||
if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) {
|
||||
set_error_source(ADBMS_INTERNAL_BMS_CHECKSUM_FAIL);
|
||||
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_CHECKSUM_FAIL, -1};
|
||||
}
|
||||
|
||||
// TODO: temperature measurement
|
||||
|
||||
bool overvolt = false;
|
||||
bool undervolt = false;
|
||||
for (size_t i = 0; i < numberofCells; i++) {
|
||||
if (any(module.cellVoltages[i] < 2500)) {
|
||||
undervolt = true;
|
||||
if ((match = any(module.cellVoltages[i] < 2500))) {
|
||||
error_data[ADBMS_UNDERVOLT].data[0] = i;
|
||||
uint8_t* ptr = &error_data[ADBMS_UNDERVOLT].data[1];
|
||||
// ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2);
|
||||
} else if (any(module.cellVoltages[i] > 4200)) {
|
||||
overvolt = true;
|
||||
return (ADBMS_DetailedStatus){ADBMS_UNDERVOLT, match};
|
||||
} else if ((match = any(module.cellVoltages[i] > 4200))) {
|
||||
error_data[ADBMS_OVERVOLT].data[0] = i;
|
||||
uint8_t* ptr = &error_data[ADBMS_OVERVOLT].data[1];
|
||||
// ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2);
|
||||
return (ADBMS_DetailedStatus){ADBMS_OVERVOLT, match};
|
||||
}
|
||||
}
|
||||
|
||||
if (any(module.internalDieTemp > 28000 || module.status.THSD)) { // TODO: change to correct value
|
||||
// ftcan_marshal_unsigned(&error_data[SEK_INTERNAL_BMS_OVERTEMP].data[0], module.internalDieTemp, 2);
|
||||
|
||||
set_error_source(ADBMS_INTERNAL_BMS_OVERTEMP);
|
||||
} else {
|
||||
clear_error_source(ADBMS_INTERNAL_BMS_OVERTEMP);
|
||||
}
|
||||
|
||||
if (overvolt) {
|
||||
set_error_source(ADBMS_OVERVOLT);
|
||||
} else {
|
||||
clear_error_source(ADBMS_OVERVOLT);
|
||||
}
|
||||
|
||||
if (undervolt) {
|
||||
set_error_source(ADBMS_UNDERVOLT);
|
||||
} else {
|
||||
clear_error_source(ADBMS_UNDERVOLT);
|
||||
// TODO: replace with the correct threshold for the internal die temperature
|
||||
if ((match = any(module.internalDieTemp > 28000 || module.status.THSD))) {
|
||||
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_OVERTEMP, match};
|
||||
}
|
||||
|
||||
mcuDelay(10);
|
||||
|
Loading…
x
Reference in New Issue
Block a user