From 7fbd335017e3a940691ca564991d874da4425c1c Mon Sep 17 00:00:00 2001 From: Kilian Bracher Date: Fri, 31 Jan 2025 18:18:32 +0100 Subject: [PATCH] refactor: cell voltages, main loop --- .../Core/Inc/ADBMS_Abstraction.h | 20 +-- .../Core/Inc/AMS_HighLevel.h | 3 +- .../Core/Src/ADBMS_Abstraction.c | 134 +++++++++++------- .../Core/Src/ADBMS_LL_Driver.c | 3 - .../Core/Src/AMS_HighLevel.c | 57 ++++---- 5 files changed, 119 insertions(+), 98 deletions(-) diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h index 69dcbb8..698557f 100755 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h @@ -78,23 +78,13 @@ HAL_StatusTypeDef amsStopBalancing(); HAL_StatusTypeDef amsSelfTest(); -uint8_t amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t underVoltage); +HAL_StatusTypeDef amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t underVoltage); -uint8_t amsCheckUnderOverVoltage(Cell_Module* module); -uint8_t amsConfigOverVoltage(uint16_t overVoltage); +HAL_StatusTypeDef amsCheckUnderOverVoltage(Cell_Module (*module)[N_BMS]); -uint8_t amscheckOpenCellWire(Cell_Module* module); +HAL_StatusTypeDef amsClearFlag(); +HAL_StatusTypeDef amsClearAux(); -uint8_t amsClearFlag(); -uint8_t amsClearAux(); -uint8_t amsClearCells(); - -uint8_t amsSendWarning(); -uint8_t amsSendError(); - -uint8_t amsClearWarning(); -uint8_t amsClearError(); - -uint8_t amsReadCellVoltages(Cell_Module* module); +HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]); #endif /* INC_ADBMS_ABSTRACTION_H_ */ diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/AMS_HighLevel.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/AMS_HighLevel.h index c37ac7d..f7f41cf 100755 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/AMS_HighLevel.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/AMS_HighLevel.h @@ -11,6 +11,7 @@ #include "ADBMS_Abstraction.h" #include "ADBMS_CMD_MAKROS.h" #include "ADBMS_LL_Driver.h" +#include "config_ADBMS6830.h" #include @@ -25,7 +26,7 @@ typedef enum { } amsState; extern amsState currentAMSState; -extern Cell_Module module; +extern Cell_Module modules[N_BMS]; extern uint32_t balancedCells; extern bool BalancingActive; diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c index e17fc36..5ca14d2 100755 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c @@ -16,7 +16,7 @@ extern uint8_t numberofCells; #define CHECK_RETURN(x) \ { \ - uint8_t status = x; \ + HAL_StatusTypeDef status = x; \ if (status != 0) \ return status; \ } @@ -205,90 +205,114 @@ HAL_StatusTypeDef amsStopBalancing() { return writeCMD(MUTE, CMD_EMPTY_BUFFER, 0 HAL_StatusTypeDef amsSelfTest() { return 0; } -uint8_t amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t underVoltage) { - uint8_t buffer[CFG_GROUP_A_SIZE] = {}; +HAL_StatusTypeDef amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t underVoltage) { + uint8_t buffer[CMD_BUFFER_SIZE(CFG_GROUP_B_SIZE)] = {}; if (underVoltage & 0xF000 || overVoltage & 0xF000) { // only 12 bits allowed - return 1; + return HAL_ERROR; } - CHECK_RETURN(readCMD(RDCFGB, buffer, CFG_GROUP_A_SIZE)); + debug_log(LOG_LEVEL_INFO, "Configuring OV/UV thresholds to %f/%f", mV_from_ADBMS6830(overVoltage), mV_from_ADBMS6830(underVoltage)); - //UV - buffer[0] = (uint8_t) (underVoltage & 0xFF); - buffer[1] &= 0xF0; - buffer[1] |= (uint8_t) ((underVoltage >> 8) & 0x0F); + CHECK_RETURN(readCMD(RDCFGB, buffer, CFG_GROUP_B_SIZE)); - //OV - buffer[1] &= 0x0F; - buffer[1] |= (uint8_t) (overVoltage << 4); - buffer[2] = (uint8_t) (overVoltage >> 4); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CFG_GROUP_B_SIZE); - return writeCMD(WRCFGB, buffer, CFG_GROUP_A_SIZE); + //UV + buffer[offset + 0] = (uint8_t)(underVoltage & 0xFF); + buffer[offset + 1] &= 0xF0; + buffer[offset + 1] |= (uint8_t)((underVoltage >> 8) & 0x0F); + + //OV + buffer[offset + 1] &= 0x0F; + buffer[offset + 1] |= (uint8_t)(overVoltage << 4); + buffer[offset + 2] = (uint8_t)(overVoltage >> 4); + } + + return writeCMD(WRCFGB, buffer, CFG_GROUP_B_SIZE); } -uint8_t amsCheckUnderOverVoltage(Cell_Module* module) { - uint8_t regbuffer[STATUS_GROUP_D_SIZE]; - uint32_t ov_uv_data = 0; - CHECK_RETURN(readCMD(RDSTATD, regbuffer, STATUS_GROUP_D_SIZE)); - ov_uv_data = (regbuffer[0] << 0) | (regbuffer[1] << 8) | - (regbuffer[2] << 16) | (regbuffer[3] << 24); - - module->overVoltage = 0; - module->underVoltage = 0; +HAL_StatusTypeDef amsCheckUnderOverVoltage(Cell_Module (*module)[N_BMS]) { + uint8_t regbuffer[CMD_BUFFER_SIZE(STATUS_GROUP_D_SIZE)] = {}; - for (size_t i = 0; i < numberofCells; i++) { // ov/uv flags are 1-bit flags for each cell C0UV, C0OV, C1UV, C1OV, ... - module->underVoltage |= (ov_uv_data >> (i * 2)) & 0x01; - module->overVoltage |= (ov_uv_data >> (i * 2 + 1)) & 0x01; + CHECK_RETURN(readCMD(RDSTATD, regbuffer, STATUS_GROUP_D_SIZE)); + + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_D_SIZE); + uint32_t ov_uv_data = 0; + ov_uv_data = (regbuffer[offset + 0] << 0) | (regbuffer[offset + 1] << 8) | + (regbuffer[offset + 2] << 16) | (regbuffer[offset + 3] << 24); + + module[i]->overVoltage = 0; + module[i]->underVoltage = 0; + + for (size_t j = 0; j < numberofCells; j++) { // ov/uv flags are 1-bit flags for each cell C0UV, C0OV, C1UV, C1OV, ... + module[i]->underVoltage |= (ov_uv_data >> (j * 2)) & 0x01; + module[i]->overVoltage |= (ov_uv_data >> (j * 2 + 1)) & 0x01; + } } - return 0; + return HAL_OK; } -uint8_t amsClearFlag() { - uint8_t buffer[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +HAL_StatusTypeDef amsClearFlag() { + uint8_t buffer[CMD_BUFFER_SIZE(6)] = {[0 ... CMD_BUFFER_SIZE(6) - 1] = 0xFF}; return writeCMD(CLRFLAG, buffer, 6); } -uint8_t amsClearAux() { - uint8_t buffer[6]; - return writeCMD(CLRAUX, buffer, 0); +HAL_StatusTypeDef amsClearAux() { + return writeCMD(CLRAUX, CMD_EMPTY_BUFFER, 0); } -uint8_t amsClearCells() { - uint8_t buffer[6]; - return writeCMD(CLRCELL, buffer, 0); -} +HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) { + uint8_t rxbuffer[CMD_BUFFER_SIZE(CV_GROUP_A_SIZE)] = {}; -uint8_t amsReadCellVoltages(Cell_Module* module) { - uint8_t rxbuffer[CV_GROUP_A_SIZE]; CHECK_RETURN(readCMD(RDCVA, rxbuffer, CV_GROUP_A_SIZE)); - module->cellVoltages[0] = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8)); - module->cellVoltages[1] = mV_from_ADBMS6830(rxbuffer[2] | (rxbuffer[3] << 8)); - module->cellVoltages[2] = mV_from_ADBMS6830(rxbuffer[4] | (rxbuffer[5] << 8)); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); + module[i]->cellVoltages[0] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8)); + module[i]->cellVoltages[1] = mV_from_ADBMS6830(rxbuffer[offset + 2] | (rxbuffer[offset + 3] << 8)); + module[i]->cellVoltages[2] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8)); + } CHECK_RETURN(readCMD(RDCVB, rxbuffer, CV_GROUP_A_SIZE)); - module->cellVoltages[3] = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8)); - module->cellVoltages[4] = mV_from_ADBMS6830(rxbuffer[2] | (rxbuffer[3] << 8)); - module->cellVoltages[5] = mV_from_ADBMS6830(rxbuffer[4] | (rxbuffer[5] << 8)); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); + module[i]->cellVoltages[3] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8)); + module[i]->cellVoltages[4] = mV_from_ADBMS6830(rxbuffer[offset + 2] | (rxbuffer[offset + 3] << 8)); + module[i]->cellVoltages[5] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8)); + } CHECK_RETURN(readCMD(RDCVC, rxbuffer, CV_GROUP_A_SIZE)); - module->cellVoltages[6] = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8)); - module->cellVoltages[7] = mV_from_ADBMS6830(rxbuffer[2] | (rxbuffer[3] << 8)); - module->cellVoltages[8] = mV_from_ADBMS6830(rxbuffer[4] | (rxbuffer[5] << 8)); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); + module[i]->cellVoltages[6] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8)); + module[i]->cellVoltages[7] = mV_from_ADBMS6830(rxbuffer[offset + 2] | (rxbuffer[offset + 3] << 8)); + module[i]->cellVoltages[8] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8)); + } CHECK_RETURN(readCMD(RDCVD, rxbuffer, CV_GROUP_A_SIZE)); - module->cellVoltages[9] = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8)); - module->cellVoltages[10] = mV_from_ADBMS6830(rxbuffer[2] | (rxbuffer[3] << 8)); - module->cellVoltages[11] = mV_from_ADBMS6830(rxbuffer[4] | (rxbuffer[5] << 8)); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); + module[i]->cellVoltages[9] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8)); + module[i]->cellVoltages[10] = mV_from_ADBMS6830(rxbuffer[offset + 2] | (rxbuffer[offset + 3] << 8)); + module[i]->cellVoltages[11] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8)); + } CHECK_RETURN(readCMD(RDCVE, rxbuffer, CV_GROUP_A_SIZE)); - module->cellVoltages[12] = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8)); - module->cellVoltages[13] = mV_from_ADBMS6830(rxbuffer[2] | (rxbuffer[3] << 8)); - module->cellVoltages[14] = mV_from_ADBMS6830(rxbuffer[4] | (rxbuffer[5] << 8)); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); + module[i]->cellVoltages[12] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8)); + module[i]->cellVoltages[13] = mV_from_ADBMS6830(rxbuffer[offset + 2] | (rxbuffer[offset + 3] << 8)); + module[i]->cellVoltages[14] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8)); + } CHECK_RETURN(readCMD(RDCVF, rxbuffer, CV_GROUP_A_SIZE)); - module->cellVoltages[15] = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8)); + for (size_t i = 0; i < N_BMS; i++) { + size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); + module[i]->cellVoltages[15] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8)); + } - return 0; + return HAL_OK; } diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c index 2a7c360..8b2e892 100755 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c @@ -20,7 +20,6 @@ #warning ask about the timeout value SPI_HandleTypeDef* adbmsspi; -uint8_t command_queue[N_BMS][12] = {0}; uint8_t adbmsDriverInit(SPI_HandleTypeDef* hspi) { mcuAdbmsCSLow(); @@ -180,8 +179,6 @@ static uint8_t calculateDataPEC(uint8_t* data, uint8_t datalen) { data[datalen - 2] = (currentpec >> 8) & 0xFF; data[datalen - 1] = currentpec & 0xFF; - volatile uint8_t result = pec10_calc(true, datalen, data); - return 0; } else { return 1; diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/AMS_HighLevel.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/AMS_HighLevel.c index c3f697a..1cf03ef 100755 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/AMS_HighLevel.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/AMS_HighLevel.c @@ -15,7 +15,7 @@ #include #include -Cell_Module module = {}; +Cell_Module modules[N_BMS] = {}; uint32_t balancedCells = 0; bool balancingActive = false; @@ -41,15 +41,25 @@ void AMS_Init(SPI_HandleTypeDef* hspi) { pollingTimes = (struct pollingTimes) {HAL_GetTick(), HAL_GetTick()}; } +#define any(x) ({ \ + bool any = false; \ + for (size_t i = 0; i < N_BMS; i++) { \ + Cell_Module module = modules[i]; \ + any |= (x); \ + } \ + any; \ +}) + + uint8_t AMS_Idle_Loop() { if (!amsWakeUp()) { //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 } - packetChecksumFails += amsAuxAndStatusMeasurement(&module); + packetChecksumFails += amsAuxAndStatusMeasurement(&modules); - if (module.status.SLEEP) { + if (any(module.status.SLEEP)) { deviceSleeps++; if (deviceSleeps > MAX_DEVICE_SLEEP) { set_error_source(SEK_INTERNAL_BMS_TIMEOUT); @@ -58,23 +68,26 @@ uint8_t AMS_Idle_Loop() { } } - if (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) { - //ftcan_marshal_unsigned(&error_data[SEK_INTERNAL_BMS_FAULT].data[0], module.status.CS_FLT, 2); - const uint8_t* ptr = ((uint8_t*)&module.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 - // iteration. - amsClearFlag(); + 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)) { + + // TODO: handle errors + + // ftcan_marshal_unsigned(&error_data[SEK_INTERNAL_BMS_FAULT].data[0], module.status.CS_FLT, 2); + /* 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 + // iteration. + amsClearFlag(); } else { - clear_error_source(SEK_INTERNAL_BMS_FAULT); + clear_error_source(SEK_INTERNAL_BMS_FAULT); } - packetChecksumFails += amsCellMeasurement(&module); - packetChecksumFails += amsCheckUnderOverVoltage(&module); + packetChecksumFails += amsCellMeasurement(&modules); + packetChecksumFails += amsCheckUnderOverVoltage(&modules); if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) { set_error_source(SEK_INTERNAL_BMS_CHECKSUM_FAIL); @@ -85,12 +98,12 @@ uint8_t AMS_Idle_Loop() { bool overvolt = false; bool undervolt = false; for (size_t i = 0; i < numberofCells; i++) { - if (module.cellVoltages[i] < 2500) { + if (any(module.cellVoltages[i] < 2500)) { undervolt = true; error_data[SEK_UNDERVOLT].data[0] = i; uint8_t* ptr = &error_data[SEK_UNDERVOLT].data[1]; //ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2); - } else if (module.cellVoltages[i] > 4200) { + } else if (any(module.cellVoltages[i] > 4200)) { overvolt = true; error_data[SEK_OVERVOLT].data[0] = i; uint8_t* ptr = &error_data[SEK_OVERVOLT].data[1]; @@ -98,7 +111,7 @@ uint8_t AMS_Idle_Loop() { } } - if (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); set_error_source(SEK_INTERNAL_BMS_OVERTEMP); @@ -120,9 +133,5 @@ uint8_t AMS_Idle_Loop() { mcuDelay(10); - if ((module.overVoltage | module.underVoltage)) { - - } - return 0; }