refactor: start fixup for error handling

This commit is contained in:
Kilian Bracher 2025-02-20 15:35:36 +01:00
parent f3fae2686f
commit 53a9597fe8
4 changed files with 146 additions and 134 deletions

View File

@ -1,27 +1,36 @@
#ifndef ADBMS_DRIVER_H #ifndef ADBMS_DRIVER_H
#define ADBMS_DRIVER_H #define ADBMS_DRIVER_H
#include <stdint.h>
#include "stm32h7xx_hal.h" #include "stm32h7xx_hal.h"
#include <stdint.h>
#define ERROR_TIME_THRESH 150 // ms #define ERROR_TIME_THRESH 150 // ms
typedef enum { typedef enum : uint16_t {
SEK_OVERTEMP, ADBMS_OK = 0x00, // same as STM32 HAL status
SEK_UNDERTEMP, ADBMS_ERROR = 0x01, //
SEK_OVERVOLT, ADBMS_BUSY = 0x02, //
SEK_UNDERVOLT, ADBMS_TIMEOUT = 0x03 //
SEK_TOO_FEW_TEMPS, } ADBMS_StatusTypeDef;
SEK_OPENWIRE,
SEK_EEPROM_ERR, typedef enum : uint16_t {
SEK_INTERNAL_BMS_TIMEOUT, ADBMS_NONE = 0,
SEK_INTERNAL_BMS_CHECKSUM_FAIL, ADBMS_OVERTEMP,
SEK_INTERNAL_BMS_OVERTEMP, ADBMS_UNDERTEMP,
SEK_INTERNAL_BMS_FAULT, ADBMS_OVERVOLT,
SEK_1WIRE_ERR, ADBMS_UNDERVOLT,
SEK_DS18B20_TIMEOUT, ADBMS_OPENWIRE,
ADBMS_INTERNAL_BMS_TIMEOUT,
ADBMS_INTERNAL_BMS_CHECKSUM_FAIL,
ADBMS_INTERNAL_BMS_OVERTEMP,
ADBMS_INTERNAL_BMS_FAULT,
NUM_ERROR_KINDS NUM_ERROR_KINDS
} SlaveErrorKind; } ADBMS_ErrorKind;
typedef struct {
ADBMS_StatusTypeDef status : 16;
ADBMS_ErrorKind error : 16; // zero if status is ADBMS_OK
} ADBMS_DetailedStatus;
typedef struct { typedef struct {
uint8_t data[4]; uint8_t data[4];
@ -75,10 +84,9 @@ typedef struct {
extern uint32_t error_sources; // Bitfield of error sources extern uint32_t error_sources; // Bitfield of error sources
extern SlaveErrorData error_data[NUM_ERROR_KINDS]; extern SlaveErrorData error_data[NUM_ERROR_KINDS];
[[gnu::nonnull]] [[gnu::nonnull]] ADBMS_DetailedStatus AMS_Init(SPI_HandleTypeDef* hspi);
void AMS_Init(SPI_HandleTypeDef* hspi);
uint8_t AMS_Idle_Loop(); ADBMS_DetailedStatus AMS_Idle_Loop();
#undef MAXIMUM_CELL_VOLTAGES #undef MAXIMUM_CELL_VOLTAGES
#undef MAXIMUM_AUX_VOLTAGES #undef MAXIMUM_AUX_VOLTAGES

View File

@ -11,8 +11,8 @@
static_assert(sizeof(error_sources) * CHAR_BIT >= NUM_ERROR_KINDS, static_assert(sizeof(error_sources) * CHAR_BIT >= NUM_ERROR_KINDS,
"error_sources is too small to hold all error sources"); "error_sources is too small to hold all error sources");
void set_error_source(SlaveErrorKind source); void set_error_source(ADBMS_ErrorKind source);
void clear_error_source(SlaveErrorKind source); void clear_error_source(ADBMS_ErrorKind source);
#endif //AMS_MASTER_CODE_ADBMS_ERROR_H #endif //AMS_MASTER_CODE_ADBMS_ERROR_H

View File

@ -4,14 +4,14 @@
SlaveErrorData error_data[NUM_ERROR_KINDS] = {}; SlaveErrorData error_data[NUM_ERROR_KINDS] = {};
uint32_t error_sources = 0; uint32_t error_sources = 0;
void set_error_source(SlaveErrorKind source) { void set_error_source(ADBMS_ErrorKind source) {
if (!(error_sources & (1 << source))) { if (!(error_sources & (1 << source))) {
error_data[source].errors_since = HAL_GetTick(); error_data[source].errors_since = HAL_GetTick();
} }
error_sources |= (1 << source); error_sources |= (1 << source);
} }
void clear_error_source(SlaveErrorKind source) { void clear_error_source(ADBMS_ErrorKind source) {
error_data[source].errors_since = 0; error_data[source].errors_since = 0;
error_sources &= ~(1 << source); error_sources &= ~(1 << source);
} }

View File

@ -7,10 +7,10 @@
#include "ADBMS_HighLevel.h" #include "ADBMS_HighLevel.h"
#include "ADBMS_Abstraction.h" #include "ADBMS_Abstraction.h"
#include "ADBMS_Driver.h"
#include "ADBMS_Error.h"
#include "ADBMS_LL_Driver.h" #include "ADBMS_LL_Driver.h"
#include "config_ADBMS6830.h" #include "config_ADBMS6830.h"
#include "ADBMS_Error.h"
#include "ADBMS_Driver.h"
#include "stm32h7xx_hal.h" #include "stm32h7xx_hal.h"
#include "swo_log.h" #include "swo_log.h"
#include <stdint.h> #include <stdint.h>
@ -35,26 +35,32 @@ struct pollingTimes {
struct pollingTimes pollingTimes = {0, 0}; struct pollingTimes pollingTimes = {0, 0};
void AMS_Init(SPI_HandleTypeDef* hspi) { static constexpr ADBMS_DetailedStatus NO_ERROR = {ADBMS_OK, ADBMS_NONE};
debug_log(LOG_LEVEL_INFO, "ADBMS6830B HAL - configured for %d controllers and %d cells per controller...", N_BMS, numberofCells);
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) { if (initAMS(hspi) != HAL_OK) {
debug_log(LOG_LEVEL_ERROR, "ADBMS6830B HAL - initialization failed"); debug_log(LOG_LEVEL_ERROR, "ADBMS6830B HAL - initialization failed");
return (ADBMS_DetailedStatus){ADBMS_ERROR, ADBMS_INTERNAL_BMS_FAULT};
} }
pollingTimes = (struct pollingTimes){HAL_GetTick(), HAL_GetTick()}; pollingTimes = (struct pollingTimes){HAL_GetTick(), HAL_GetTick()};
return NO_ERROR;
} }
#define any(x) ({ \ #define any(x) \
bool any = false; \ ({ \
uint32_t any = false; \
static_assert(sizeof(any) * CHAR_BIT >= N_BMS, "any datatype needs to be larger!"); \
for (size_t __any_intern_i = 0; __any_intern_i < N_BMS; __any_intern_i++) { \ for (size_t __any_intern_i = 0; __any_intern_i < N_BMS; __any_intern_i++) { \
Cell_Module module = modules[__any_intern_i]; \ Cell_Module module = modules[__any_intern_i]; \
any |= (x); \ any |= ((x) ? 1 : 0) << __any_intern_i; \
} \ } \
any; \ any; \
}) })
ADBMS_DetailedStatus AMS_Idle_Loop() {
uint8_t AMS_Idle_Loop() {
if (!amsWakeUp()) { if (!amsWakeUp()) {
// error_data.data_kind = SEK_INTERNAL_BMS_TIMEOUT; //we don't receive data for the wakeup command // error_data.data_kind = SEK_INTERNAL_BMS_TIMEOUT; //we don't receive data for the wakeup command
// set_error_source(ERROR_SOURCE_INTERNAL); //so we can't tell if we timed out // set_error_source(ERROR_SOURCE_INTERNAL); //so we can't tell if we timed out
@ -65,7 +71,7 @@ uint8_t AMS_Idle_Loop() {
if (any(module.status.SLEEP)) { if (any(module.status.SLEEP)) {
deviceSleeps++; deviceSleeps++;
if (deviceSleeps > MAX_DEVICE_SLEEP) { if (deviceSleeps > MAX_DEVICE_SLEEP) {
set_error_source(SEK_INTERNAL_BMS_TIMEOUT); return (ADBMS_DetailedStatus){ADBMS_ERROR, ADBMS_INTERNAL_BMS_TIMEOUT};
} else { } else {
amsReset(); amsReset();
} }
@ -74,26 +80,24 @@ uint8_t AMS_Idle_Loop() {
if (any(module.status.CS_FLT || module.status.SPIFLT || module.status.CMED || module.status.SMED || if (any(module.status.CS_FLT || module.status.SPIFLT || module.status.CMED || module.status.SMED ||
module.status.VDE || module.status.VDEL || module.status.OSCCHK || module.status.TMODCHK)) { module.status.VDE || module.status.VDEL || module.status.OSCCHK || module.status.TMODCHK)) {
// TODO: handle errors const uint8_t* ptr = ((uint8_t*)&modules[0].status) + 4; // skip conversion counter
error_data[ADBMS_INTERNAL_BMS_FAULT].data[2] = ptr[1];
// ftcan_marshal_unsigned(&error_data[SEK_INTERNAL_BMS_FAULT].data[0], module.status.CS_FLT, 2); error_data[ADBMS_INTERNAL_BMS_FAULT].data[3] = ptr[0];
/* const uint8_t* ptr = ((uint8_t*)&modules.status) + 4; //skip conversion counter
error_data[SEK_INTERNAL_BMS_FAULT].data[2] = ptr[1];
error_data[SEK_INTERNAL_BMS_FAULT].data[3] = ptr[0];
set_error_source(SEK_INTERNAL_BMS_FAULT); */
// Fault bits are latched -- clear them so we can check again next // Fault bits are latched -- clear them so we can check again next
// iteration. // iteration.
amsClearFlag(); amsClearFlag();
return (ADBMS_DetailedStatus){ADBMS_ERROR, ADBMS_INTERNAL_BMS_FAULT};
} else { } else {
clear_error_source(SEK_INTERNAL_BMS_FAULT); // clear_error_source(SEK_INTERNAL_BMS_FAULT);
} }
packetChecksumFails += amsCellMeasurement(&modules); packetChecksumFails += amsCellMeasurement(&modules);
packetChecksumFails += amsCheckUnderOverVoltage(&modules); packetChecksumFails += amsCheckUnderOverVoltage(&modules);
if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) { if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) {
set_error_source(SEK_INTERNAL_BMS_CHECKSUM_FAIL); set_error_source(ADBMS_INTERNAL_BMS_CHECKSUM_FAIL);
} }
// TODO: temperature measurement // TODO: temperature measurement
@ -103,13 +107,13 @@ uint8_t AMS_Idle_Loop() {
for (size_t i = 0; i < numberofCells; i++) { for (size_t i = 0; i < numberofCells; i++) {
if (any(module.cellVoltages[i] < 2500)) { if (any(module.cellVoltages[i] < 2500)) {
undervolt = true; undervolt = true;
error_data[SEK_UNDERVOLT].data[0] = i; error_data[ADBMS_UNDERVOLT].data[0] = i;
uint8_t* ptr = &error_data[SEK_UNDERVOLT].data[1]; uint8_t* ptr = &error_data[ADBMS_UNDERVOLT].data[1];
// ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2); // ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2);
} else if (any(module.cellVoltages[i] > 4200)) { } else if (any(module.cellVoltages[i] > 4200)) {
overvolt = true; overvolt = true;
error_data[SEK_OVERVOLT].data[0] = i; error_data[ADBMS_OVERVOLT].data[0] = i;
uint8_t* ptr = &error_data[SEK_OVERVOLT].data[1]; uint8_t* ptr = &error_data[ADBMS_OVERVOLT].data[1];
// ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2); // ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2);
} }
} }
@ -117,24 +121,24 @@ uint8_t AMS_Idle_Loop() {
if (any(module.internalDieTemp > 28000 || module.status.THSD)) { // TODO: change to correct value 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); // ftcan_marshal_unsigned(&error_data[SEK_INTERNAL_BMS_OVERTEMP].data[0], module.internalDieTemp, 2);
set_error_source(SEK_INTERNAL_BMS_OVERTEMP); set_error_source(ADBMS_INTERNAL_BMS_OVERTEMP);
} else { } else {
clear_error_source(SEK_INTERNAL_BMS_OVERTEMP); clear_error_source(ADBMS_INTERNAL_BMS_OVERTEMP);
} }
if (overvolt) { if (overvolt) {
set_error_source(SEK_OVERVOLT); set_error_source(ADBMS_OVERVOLT);
} else { } else {
clear_error_source(SEK_OVERVOLT); clear_error_source(ADBMS_OVERVOLT);
} }
if (undervolt) { if (undervolt) {
set_error_source(SEK_UNDERVOLT); set_error_source(ADBMS_UNDERVOLT);
} else { } else {
clear_error_source(SEK_UNDERVOLT); clear_error_source(ADBMS_UNDERVOLT);
} }
mcuDelay(10); mcuDelay(10);
return 0; return NO_ERROR;
} }