From 1edc8d3e1c38bac8f3007e398cf3f743422b2f3c Mon Sep 17 00:00:00 2001 From: Kilian Bracher Date: Fri, 9 May 2025 14:49:16 +0200 Subject: [PATCH] cleanup part 4 --- AMS_Master_Code/.clang-format | 2 + AMS_Master_Code/Core/Inc/soc_estimation.h | 7 -- .../ADBMS6830B_Driver/Inc/ADBMS_Abstraction.h | 8 +- .../Lib/ADBMS6830B_Driver/Inc/ADBMS_Driver.h | 4 +- .../Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h | 2 +- .../ADBMS6830B_Driver/Src/ADBMS_Abstraction.c | 10 +-- .../ADBMS6830B_Driver/Src/ADBMS_HighLevel.c | 12 +-- AMS_Master_Code/Core/Lib/logger/log.h | 2 + AMS_Master_Code/Core/Src/battery.c | 30 +++---- AMS_Master_Code/Core/Src/can.c | 4 +- .../Core/Src/print_module_status.c | 82 +++++++++---------- AMS_Master_Code/Core/Src/soc_estimation.c | 60 ++++++++------ 12 files changed, 113 insertions(+), 110 deletions(-) create mode 100644 AMS_Master_Code/.clang-format diff --git a/AMS_Master_Code/.clang-format b/AMS_Master_Code/.clang-format new file mode 100644 index 0000000..1f4b5bb --- /dev/null +++ b/AMS_Master_Code/.clang-format @@ -0,0 +1,2 @@ +IndentWidth: 4 +ColumnLimit: 120 \ No newline at end of file diff --git a/AMS_Master_Code/Core/Inc/soc_estimation.h b/AMS_Master_Code/Core/Inc/soc_estimation.h index 07033d7..057c27d 100644 --- a/AMS_Master_Code/Core/Inc/soc_estimation.h +++ b/AMS_Master_Code/Core/Inc/soc_estimation.h @@ -8,11 +8,4 @@ extern float current_soc; void soc_init(); void soc_update(); -typedef struct { - uint16_t ocv; - float soc; -} ocv_soc_pair_t; -extern ocv_soc_pair_t OCV_SOC_PAIRS[]; -float soc_for_ocv(uint16_t ocv); - #endif // INC_SOC_ESTIMATION_H diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Abstraction.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Abstraction.h index d1797ba..82d57f8 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Abstraction.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Abstraction.h @@ -17,9 +17,9 @@ ADBMS_Internal_Status amsReset(); ADBMS_Internal_Status initAMS(USER_PTR_TYPE ptr); ADBMS_Internal_Status amsWakeUp(); -ADBMS_Internal_Status amsCellMeasurement(Cell_Module (*module)[N_BMS]); +ADBMS_Internal_Status amsCellMeasurement(BMS_Chip (*module)[N_BMS]); -ADBMS_Internal_Status amsAuxAndStatusMeasurement(Cell_Module (*module)[N_BMS]); +ADBMS_Internal_Status amsAuxAndStatusMeasurement(BMS_Chip (*module)[N_BMS]); ADBMS_Internal_Status amsConfigBalancing(const uint32_t channels[static N_BMS], uint8_t dutyCycle); ADBMS_Internal_Status amsStartBalancing(); @@ -29,12 +29,12 @@ ADBMS_Internal_Status amsSelfTest(); ADBMS_Internal_Status amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t underVoltage); //arguments in mV -ADBMS_Internal_Status amsCheckUnderOverVoltage(Cell_Module (*module)[N_BMS]); +ADBMS_Internal_Status amsCheckUnderOverVoltage(BMS_Chip (*module)[N_BMS]); ADBMS_Internal_Status amsClearFlag(); ADBMS_Internal_Status amsClearAux(); ADBMS_Internal_Status amsClearOVUV(); -ADBMS_Internal_Status amsReadCellVoltages(Cell_Module (*module)[N_BMS]); +ADBMS_Internal_Status amsReadCellVoltages(BMS_Chip (*module)[N_BMS]); #endif /* INC_ADBMS_ABSTRACTION_H_ */ diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Driver.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Driver.h index 6bf5c84..7645c43 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Driver.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Driver.h @@ -86,9 +86,9 @@ typedef struct { int16_t cellVoltages[MAXIMUM_CELL_VOLTAGES]; int16_t auxVoltages[MAXIMUM_AUX_VOLTAGES]; -} Cell_Module; +} BMS_Chip; -extern Cell_Module modules[N_BMS]; +extern BMS_Chip bms_data[N_BMS]; [[gnu::nonnull]] ADBMS_DetailedStatus AMS_Init(USER_PTR_TYPE ptr); diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h index 5941660..82e9a3c 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h @@ -53,7 +53,7 @@ static inline void mcuDelay(uint32_t delay) { // Optional logging, leave as is if not needed -#if !ADBMS_NO_LOGGING_DEFS +#ifndef ADBMS_NO_LOGGING_DEFS #define LOG_PREFIX "[ADBMS] " #include "log.h" diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_Abstraction.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_Abstraction.c index 1fcd0e0..67fc875 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_Abstraction.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_Abstraction.c @@ -53,7 +53,7 @@ ADBMS_Internal_Status amsReset() { for (size_t j = 0; j < SID_GROUP_SIZE; j++) { id |= sidbuffer[BUFFER_BMS_OFFSET(i, SID_GROUP_SIZE) + j] << (j * 8); } - modules[i].bmsID = id; + bms_data[i].bmsID = id; debug_log_cont(ADBMS_LOG_LEVEL_INFO, "0x%08lx%08lx ", (uint32_t)(id >> 32), (uint32_t)(id & 0xFFFFFFFF)); //newlib does not support %llu } } @@ -83,13 +83,13 @@ ADBMS_Internal_Status amsWakeUp() { return __pollCMD(PLADC, 100); //wake up ADBMS6830, wait for T_wake = 200 us (100 cycles at 500 kHz) } -ADBMS_Internal_Status amsCellMeasurement(Cell_Module (*module)[N_BMS]) { +ADBMS_Internal_Status amsCellMeasurement(BMS_Chip (*module)[N_BMS]) { #warning check conversion counter to ensure that continuous conversion has not been stopped #warning check for OW conditions: ADSV | ADSV_OW_0 / ADSV_OW_1 return amsReadCellVoltages(module); } -ADBMS_Internal_Status amsAuxAndStatusMeasurement(Cell_Module (*module)[N_BMS]) { +ADBMS_Internal_Status amsAuxAndStatusMeasurement(BMS_Chip (*module)[N_BMS]) { uint8_t rxbuf[CMD_BUFFER_SIZE(STATUS_GROUP_C_SIZE)] = {}; CHECK_RETURN(readCMD(RDSTATC, rxbuf, STATUS_GROUP_C_SIZE)); for (size_t i = 0; i < N_BMS; i++) { @@ -237,7 +237,7 @@ ADBMS_Internal_Status amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t u return writeCMD(WRCFGB, buffer, CFG_GROUP_B_SIZE); } -ADBMS_Internal_Status amsCheckUnderOverVoltage(Cell_Module (*module)[N_BMS]) { +ADBMS_Internal_Status amsCheckUnderOverVoltage(BMS_Chip (*module)[N_BMS]) { uint8_t regbuffer[CMD_BUFFER_SIZE(STATUS_GROUP_D_SIZE)] = {}; CHECK_RETURN(readCMD(RDSTATD, regbuffer, STATUS_GROUP_D_SIZE)); @@ -274,7 +274,7 @@ ADBMS_Internal_Status amsClearOVUV() { return writeCMD(CLOVUV, buffer, 6); } -ADBMS_Internal_Status amsReadCellVoltages(Cell_Module (*module)[N_BMS]) { +ADBMS_Internal_Status amsReadCellVoltages(BMS_Chip (*module)[N_BMS]) { uint8_t rxbuffer[CMD_BUFFER_SIZE(CV_GROUP_A_SIZE)] = {}; CHECK_RETURN(readCMD(RDCVA, rxbuffer, CV_GROUP_A_SIZE)); diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_HighLevel.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_HighLevel.c index 1f2eace..0c9644a 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_HighLevel.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Src/ADBMS_HighLevel.c @@ -6,7 +6,7 @@ #include -Cell_Module modules[N_BMS] = {}; +BMS_Chip bms_data[N_BMS] = {}; uint8_t packetChecksumFails = 0; #define MAX_PACKET_CHECKSUM_FAILS 5 @@ -40,7 +40,7 @@ ADBMS_DetailedStatus AMS_Init(USER_PTR_TYPE ptr) { ({ \ 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]; \ + BMS_Chip module = bms_data[__any_intern_i]; \ if ((x)) { \ first_match = __any_intern_i; \ break; \ @@ -55,7 +55,7 @@ ADBMS_DetailedStatus AMS_Idle_Loop() { // set_error_source(ERROR_SOURCE_INTERNAL); //so we can't tell if we timed out } - packetChecksumFails += (amsAuxAndStatusMeasurement(&modules) == ADBMS_ERROR); + packetChecksumFails += (amsAuxAndStatusMeasurement(&bms_data) == ADBMS_ERROR); int match = 0; if ((match = any(module.status.SLEEP))) { @@ -75,7 +75,7 @@ ADBMS_DetailedStatus AMS_Idle_Loop() { amsClearFlag(); // Log specific BMS fault details debug_log(ADBMS_LOG_LEVEL_ERROR, "Fault on BMS %d: ", match - 1); - auto faultyModule = &modules[match - 1]; + auto faultyModule = &bms_data[match - 1]; if (faultyModule->status.CS_FLT) debug_log_cont(ADBMS_LOG_LEVEL_ERROR, "CS_FLT "); if (faultyModule->status.SPIFLT) debug_log_cont(ADBMS_LOG_LEVEL_ERROR, "SPIFLT "); if (faultyModule->status.CMED) debug_log_cont(ADBMS_LOG_LEVEL_ERROR, "CMED "); @@ -88,8 +88,8 @@ ADBMS_DetailedStatus AMS_Idle_Loop() { return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT, match - 1}; } - packetChecksumFails += (amsCellMeasurement(&modules) == ADBMS_ERROR); - packetChecksumFails += (amsCheckUnderOverVoltage(&modules) == ADBMS_ERROR); + packetChecksumFails += (amsCellMeasurement(&bms_data) == ADBMS_ERROR); + packetChecksumFails += (amsCheckUnderOverVoltage(&bms_data) == ADBMS_ERROR); if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) { return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_CHECKSUM_FAIL, -1}; diff --git a/AMS_Master_Code/Core/Lib/logger/log.h b/AMS_Master_Code/Core/Lib/logger/log.h index 0e2c2ef..5c2784a 100644 --- a/AMS_Master_Code/Core/Lib/logger/log.h +++ b/AMS_Master_Code/Core/Lib/logger/log.h @@ -72,6 +72,8 @@ void log_message(log_level_t level, const char *msg, ...); #ifdef LOG_PREFIX #define log_message(level, fmt, ...) \ + static_assert(__builtin_constant_p(fmt), "Format string must be a compile-time constant if using LOG_PREFIX"); \ + static_assert(__builtin_constant_p(LOG_PREFIX), "LOG_PREFIX must be a compile-time constant"); \ log_message(level, LOG_PREFIX fmt, ##__VA_ARGS__) #endif diff --git a/AMS_Master_Code/Core/Src/battery.c b/AMS_Master_Code/Core/Src/battery.c index bfd9142..018ec34 100644 --- a/AMS_Master_Code/Core/Src/battery.c +++ b/AMS_Master_Code/Core/Src/battery.c @@ -1,5 +1,5 @@ #include "battery.h" -#define ADBMS_NO_LOGGING_DEFS true // fix conficting defines +#define ADBMS_NO_LOGGING_DEFS // fix conflicting defines #include "ADBMS_Driver.h" #include "NTC.h" #include "can.h" @@ -77,15 +77,15 @@ HAL_StatusTypeDef battery_update() { if (ret.bms_id != -1 && ret.bms_id < N_BMS) { const char* error_type = (ret.status == ADBMS_OVERVOLT) ? "overvoltage" : "undervoltage"; const uint32_t voltage_flags = (ret.status == ADBMS_OVERVOLT) ? - modules[ret.bms_id].overVoltage : - modules[ret.bms_id].underVoltage; + bms_data[ret.bms_id].overVoltage : + bms_data[ret.bms_id].underVoltage; debug_log(LOG_LEVEL_ERROR, "Cell %s detected on module %d, affected cells: ", error_type, ret.bms_id); for (size_t cell = 0; cell < N_CELLS; cell++) { if (voltage_flags & (1UL << cell)) { - debug_log_cont(LOG_LEVEL_ERROR, "%u (%d mV) ", cell, modules[ret.bms_id].cellVoltages[cell]); + debug_log_cont(LOG_LEVEL_ERROR, "%u (%d mV) ", cell, bms_data[ret.bms_id].cellVoltages[cell]); } } @@ -115,13 +115,13 @@ HAL_StatusTypeDef battery_update() { // First pass: calculate mean for (size_t j = 0; j < N_CELLS; j++) { - sum += modules[i].cellVoltages[j]; + sum += bms_data[i].cellVoltages[j]; } mean = sum / N_CELLS; // Second pass: calculate variance for (size_t j = 0; j < N_CELLS; j++) { - const float diff = modules[i].cellVoltages[j] - mean; + const float diff = bms_data[i].cellVoltages[j] - mean; variance += diff * diff; } variance /= N_CELLS; @@ -131,22 +131,22 @@ HAL_StatusTypeDef battery_update() { } for (size_t j = 0; j < N_CELLS; j++) { - if (modules[i].cellVoltages[j] > min_voltage) { - min_voltage = modules[i].cellVoltages[j]; + if (bms_data[i].cellVoltages[j] > min_voltage) { + min_voltage = bms_data[i].cellVoltages[j]; } - if (modules[i].cellVoltages[j] < max_voltage) { - max_voltage = modules[i].cellVoltages[j]; + if (bms_data[i].cellVoltages[j] < max_voltage) { + max_voltage = bms_data[i].cellVoltages[j]; } - if (modules[i].cellVoltages[j] > module_voltages[i].max) { - module_voltages[i].max = modules[i].cellVoltages[j]; + if (bms_data[i].cellVoltages[j] > module_voltages[i].max) { + module_voltages[i].max = bms_data[i].cellVoltages[j]; } - if (modules[i].cellVoltages[j] < module_voltages[i].min) { - module_voltages[i].min = modules[i].cellVoltages[j]; + if (bms_data[i].cellVoltages[j] < module_voltages[i].min) { + module_voltages[i].min = bms_data[i].cellVoltages[j]; } } for (size_t j = 0; j < 10; j++) { //10 GPIOs - cellTemps[i][j] = ntc_mv_to_celsius(modules[i].auxVoltages[j]); + cellTemps[i][j] = ntc_mv_to_celsius(bms_data[i].auxVoltages[j]); if (cellTemps[i][j] > max_temp) { max_temp = cellTemps[i][j]; diff --git a/AMS_Master_Code/Core/Src/can.c b/AMS_Master_Code/Core/Src/can.c index 28066c7..0850ff0 100644 --- a/AMS_Master_Code/Core/Src/can.c +++ b/AMS_Master_Code/Core/Src/can.c @@ -70,8 +70,8 @@ HAL_StatusTypeDef can_send_status() { HAL_StatusTypeDef can_send_details() { static uint8_t module_index = 0; - static uint8_t data[103] = {}; //sizeof(Cell_Module) + 10 + 1 - auto const module = &modules[module_index]; + static uint8_t data[103] = {}; //sizeof(BMS_Chip) + 10 + 1 + auto const module = &bms_data[module_index]; auto data_ptr = &data[1]; isotp_status_t status = isotp_try_add_message(isotp_connection_id, data, sizeof(data)); diff --git a/AMS_Master_Code/Core/Src/print_module_status.c b/AMS_Master_Code/Core/Src/print_module_status.c index a3f3034..c1627aa 100644 --- a/AMS_Master_Code/Core/Src/print_module_status.c +++ b/AMS_Master_Code/Core/Src/print_module_status.c @@ -28,36 +28,36 @@ void print_battery_info() { for (size_t i = 0; i < N_BMS; i++) { swo_write("Module %d status:", i); - swo_write(" BMS ID: 0x%08lx%08lx", (uint32_t)(modules[i].bmsID >> 32), (uint32_t)(modules[i].bmsID & 0xFFFFFFFF)); - + swo_write(" BMS ID: 0x%08lx%08lx", (uint32_t)(bms_data[i].bmsID >> 32), (uint32_t)(bms_data[i].bmsID & 0xFFFFFFFF)); + // Print cell voltages in 4x4 format swo_write(" Cell voltages (mV):"); swo_write(" C0: %4d C1: %4d C2: %4d C3: %4d", - modules[i].cellVoltages[0], modules[i].cellVoltages[1], - modules[i].cellVoltages[2], modules[i].cellVoltages[3]); + bms_data[i].cellVoltages[0], bms_data[i].cellVoltages[1], + bms_data[i].cellVoltages[2], bms_data[i].cellVoltages[3]); swo_write(" C4: %4d C5: %4d C6: %4d C7: %4d", - modules[i].cellVoltages[4], modules[i].cellVoltages[5], - modules[i].cellVoltages[6], modules[i].cellVoltages[7]); + bms_data[i].cellVoltages[4], bms_data[i].cellVoltages[5], + bms_data[i].cellVoltages[6], bms_data[i].cellVoltages[7]); swo_write(" C8: %4d C9: %4d C10: %4d C11: %4d", - modules[i].cellVoltages[8], modules[i].cellVoltages[9], - modules[i].cellVoltages[10], modules[i].cellVoltages[11]); + bms_data[i].cellVoltages[8], bms_data[i].cellVoltages[9], + bms_data[i].cellVoltages[10], bms_data[i].cellVoltages[11]); swo_write(" C12: %4d C13: %4d C14: %4d C15: %4d", - modules[i].cellVoltages[12], modules[i].cellVoltages[13], - modules[i].cellVoltages[14], modules[i].cellVoltages[15]); - + bms_data[i].cellVoltages[12], bms_data[i].cellVoltages[13], + bms_data[i].cellVoltages[14], bms_data[i].cellVoltages[15]); + // Print GPIO values swo_write(" GPIO voltages (mV):"); swo_write( " G0: %4d G1: %4d G2: %4d G3: %4d G4: %4d", - modules[i].auxVoltages[0], modules[i].auxVoltages[1], - modules[i].auxVoltages[2], modules[i].auxVoltages[3], - modules[i].auxVoltages[4]); + bms_data[i].auxVoltages[0], bms_data[i].auxVoltages[1], + bms_data[i].auxVoltages[2], bms_data[i].auxVoltages[3], + bms_data[i].auxVoltages[4]); swo_write( " G5: %4d G6: %4d G7: %4d G8: %4d G9: %4d", - modules[i].auxVoltages[5], modules[i].auxVoltages[6], - modules[i].auxVoltages[7], modules[i].auxVoltages[8], - modules[i].auxVoltages[9]); - + bms_data[i].auxVoltages[5], bms_data[i].auxVoltages[6], + bms_data[i].auxVoltages[7], bms_data[i].auxVoltages[8], + bms_data[i].auxVoltages[9]); + // Print temperatures swo_write(" GPIO as temperatures (°C):"); swo_write( @@ -68,91 +68,91 @@ void print_battery_info() { " G5: %4d G6: %4d G7: %4d G8: %4d G9: %4d", cellTemps[i][5], cellTemps[i][6], cellTemps[i][7], cellTemps[i][8], cellTemps[i][9]); - + swo_write( " Internal temp: %d, VAnalog: %d, VDigital: %d, VRef: %d", - modules[i].internalDieTemp, modules[i].analogSupplyVoltage, - modules[i].digitalSupplyVoltage, modules[i].refVoltage); - + bms_data[i].internalDieTemp, bms_data[i].analogSupplyVoltage, + bms_data[i].digitalSupplyVoltage, bms_data[i].refVoltage); + // Print error flags if any are set bool hasFlags = false; char flagBuffer[128] = ""; char *bufPos = flagBuffer; - - if (modules[i].status.CS_FLT) { + + if (bms_data[i].status.CS_FLT) { bufPos = stpcpy(bufPos, "CS_FLT "); hasFlags = true; } - if (modules[i].status.SMED) { + if (bms_data[i].status.SMED) { bufPos = stpcpy(bufPos, "SMED "); hasFlags = true; } - if (modules[i].status.SED) { + if (bms_data[i].status.SED) { bufPos = stpcpy(bufPos, "SED "); hasFlags = true; } - if (modules[i].status.CMED) { + if (bms_data[i].status.CMED) { bufPos = stpcpy(bufPos, "CMED "); hasFlags = true; } - if (modules[i].status.CED) { + if (bms_data[i].status.CED) { bufPos = stpcpy(bufPos, "CED "); hasFlags = true; } - if (modules[i].status.VD_UV) { + if (bms_data[i].status.VD_UV) { bufPos = stpcpy(bufPos, "VD_UV "); hasFlags = true; } - if (modules[i].status.VD_OV) { + if (bms_data[i].status.VD_OV) { bufPos = stpcpy(bufPos, "VD_OV "); hasFlags = true; } - if (modules[i].status.VA_UV) { + if (bms_data[i].status.VA_UV) { bufPos = stpcpy(bufPos, "VA_UV "); hasFlags = true; } - if (modules[i].status.VA_OV) { + if (bms_data[i].status.VA_OV) { bufPos = stpcpy(bufPos, "VA_OV "); hasFlags = true; } - if (modules[i].status.THSD) { + if (bms_data[i].status.THSD) { bufPos = stpcpy(bufPos, "THSD "); hasFlags = true; } - if (modules[i].status.SLEEP) { + if (bms_data[i].status.SLEEP) { bufPos = stpcpy(bufPos, "SLEEP "); hasFlags = true; } - if (modules[i].status.SPIFLT) { + if (bms_data[i].status.SPIFLT) { bufPos = stpcpy(bufPos, "SPIFLT "); hasFlags = true; } - if (modules[i].status.COMPARE) { + if (bms_data[i].status.COMPARE) { bufPos = stpcpy(bufPos, "COMPARE "); hasFlags = true; } - if (modules[i].status.VDE) { + if (bms_data[i].status.VDE) { bufPos = stpcpy(bufPos, "VDE "); hasFlags = true; } - if (modules[i].status.VDEL) { + if (bms_data[i].status.VDEL) { bufPos = stpcpy(bufPos, "VDEL "); hasFlags = true; } swo_write(" Status flags: %s", hasFlags ? flagBuffer : "[none]"); - if (modules[i].status.CS_FLT) { // Print out which ADCs are faulting + if (bms_data[i].status.CS_FLT) { // Print out which ADCs are faulting swo_write("Comparison fault on ADC/Cell(s): "); for (ssize_t j = 0; j < 16; j++) { - if (modules[i].status.CS_FLT & (1u << j)) { + if (bms_data[i].status.CS_FLT & (1u << j)) { swo_write("%d ", j); } } } swo_write(" Conversion counter: %d", - modules[i].status.CCTS); + bms_data[i].status.CCTS); } swo_write("\n------ Updated at %lu ------", HAL_GetTick()); } \ No newline at end of file diff --git a/AMS_Master_Code/Core/Src/soc_estimation.c b/AMS_Master_Code/Core/Src/soc_estimation.c index 9c6805a..5854b0e 100644 --- a/AMS_Master_Code/Core/Src/soc_estimation.c +++ b/AMS_Master_Code/Core/Src/soc_estimation.c @@ -12,6 +12,12 @@ #define SOC_ESTIMATION_NO_CURRENT_THRESH 200 // mA #define SOC_ESTIMATION_NO_CURRENT_TIME 100000 // ms #define SOC_ESTIMATION_BATTERY_CAPACITY 64800000 // mAs + +typedef struct { + uint16_t ocv; + float soc; +} ocv_soc_pair_t; + ocv_soc_pair_t OCV_SOC_PAIRS[] = { {2500, 0.00f}, {2990, 3.97f}, {3230, 9.36f}, {3320, 12.60f}, {3350, 13.68f}, {3410, 20.15f}, {3530, 32.01f}, {3840, 66.53f}, @@ -31,33 +37,7 @@ void soc_init() { current_was_flowing = 1; } -void soc_update() { - const uint32_t now = HAL_GetTick(); - if (abs(shunt_data.current) >= SOC_ESTIMATION_NO_CURRENT_THRESH) { - last_current_time = now; - if (!current_was_flowing) { - soc_before_current = current_soc; - mAs_before_current = shunt_data.current_counter; - } - current_was_flowing = 1; - } else { - current_was_flowing = 0; - } - - if (now - last_current_time >= SOC_ESTIMATION_NO_CURRENT_TIME || - last_current_time == 0) { - // Assume we're measuring OCV if there's been no current for a while (or - // we've just turned on the battery). - current_soc = soc_for_ocv(min_voltage); - } else { - // Otherwise, use the current counter to update SoC - const float as_delta = shunt_data.current_counter - mAs_before_current; - const float soc_delta = as_delta / SOC_ESTIMATION_BATTERY_CAPACITY * 100; - current_soc = soc_before_current - soc_delta; - } -} - -float soc_for_ocv(uint16_t ocv) { +static float soc_for_ocv(uint16_t ocv) { size_t i = 0; const size_t array_length = sizeof(OCV_SOC_PAIRS) / sizeof(*OCV_SOC_PAIRS); // Find the index of the first element with OCV greater than the target OCV @@ -88,3 +68,29 @@ float soc_for_ocv(uint16_t ocv) { return interpolated_soc; } + +void soc_update() { + const uint32_t now = HAL_GetTick(); + if (abs(shunt_data.current) >= SOC_ESTIMATION_NO_CURRENT_THRESH) { + last_current_time = now; + if (!current_was_flowing) { + soc_before_current = current_soc; + mAs_before_current = shunt_data.current_counter; + } + current_was_flowing = 1; + } else { + current_was_flowing = 0; + } + + if (now - last_current_time >= SOC_ESTIMATION_NO_CURRENT_TIME || + last_current_time == 0) { + // Assume we're measuring OCV if there's been no current for a while (or + // we've just turned on the battery). + current_soc = soc_for_ocv(min_voltage); + } else { + // Otherwise, use the current counter to update SoC + const float as_delta = shunt_data.current_counter - mAs_before_current; + const float soc_delta = as_delta / SOC_ESTIMATION_BATTERY_CAPACITY * 100; + current_soc = soc_before_current - soc_delta; + } +}