diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Driver.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Driver.h index b4194d9..3db67c5 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Driver.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Driver.h @@ -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 { diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Error.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Error.h index 2e37f99..5973e59 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Error.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Error.h @@ -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 diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Error.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Error.c index 04554bc..a48e237 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Error.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Error.c @@ -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); } diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_HighLevel.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_HighLevel.c index 49cbadf..c15c922 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_HighLevel.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_HighLevel.c @@ -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);