cleanup part 4
This commit is contained in:
parent
d4dc7e4533
commit
1edc8d3e1c
2
AMS_Master_Code/.clang-format
Normal file
2
AMS_Master_Code/.clang-format
Normal file
@ -0,0 +1,2 @@
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 120
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
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};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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));
|
||||
|
@ -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());
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user