refactor: more work on error handling and logging, as well as general cleanup

This commit is contained in:
Kilian Bracher 2025-02-23 16:12:30 +01:00
parent 522ef539be
commit f3aa252b0e
Signed by: k.bracher
SSH Key Fingerprint: SHA256:mXpyZkK7RDiJ7qeHCKJX108woM0cl5TrCvNBJASu6lM
8 changed files with 360 additions and 332 deletions

View File

@ -2,15 +2,16 @@
#ifndef __CONFIG_ADBMS6830_H #ifndef __CONFIG_ADBMS6830_H
#define __CONFIG_ADBMS6830_H #define __CONFIG_ADBMS6830_H
#include "main.h" #include "main.h"
#define N_BMS 2
[[maybe_unused]] static void mcuAdbmsCSLow() { #define N_BMS 2
#define ADBMS_SPI_TIMEOUT 100 // Timeout in ms
[[maybe_unused]] static inline void mcuAdbmsCSLow() {
HAL_GPIO_WritePin(AMS_CS_GPIO_Port, AMS_CS_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(AMS_CS_GPIO_Port, AMS_CS_Pin, GPIO_PIN_RESET);
} }
[[maybe_unused]] static void mcuAdbmsCSHigh() { [[maybe_unused]] static inline void mcuAdbmsCSHigh() {
HAL_GPIO_WritePin(AMS_CS_GPIO_Port, AMS_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(AMS_CS_GPIO_Port, AMS_CS_Pin, GPIO_PIN_SET);
} }
#endif //__CONFIG_ADBMS6830_H #endif //__CONFIG_ADBMS6830_H

View File

@ -52,7 +52,8 @@ static inline uint32_t __swo_putc(uint32_t c, unsigned int channel) {
return (c); return (c);
} }
#define DEBUG_CHANNEL_ENABLED(channel) ({ \ #define DEBUG_CHANNEL_ENABLED(channel) \
({ \
unsigned int ch = (channel); \ unsigned int ch = (channel); \
(ch < 32) ? __ITM_channel_enabled(ch) : false; \ (ch < 32) ? __ITM_channel_enabled(ch) : false; \
}) })

View File

@ -9,10 +9,11 @@
#define INC_ADBMS_ABSTRACTION_H_ #define INC_ADBMS_ABSTRACTION_H_
#include "ADBMS_CMD_MAKROS.h" #include "ADBMS_CMD_MAKROS.h"
#include "ADBMS_LL_Driver.h"
#include "ADBMS_Driver.h" #include "ADBMS_Driver.h"
#include "ADBMS_LL_Driver.h"
#include "main.h" #include "main.h"
// see table 103 in datasheet (page 71) // see table 103 in datasheet (page 71)
#define DEFAULT_UV 417 // VUV * 16 * 150 uV + 1.5 V Default Setting 2.5V #define DEFAULT_UV 417 // VUV * 16 * 150 uV + 1.5 V Default Setting 2.5V
#define DEFAULT_OV 1125 // VOV * 16 * 150 uV + 1.5 V Default Setting 4.2V #define DEFAULT_OV 1125 // VOV * 16 * 150 uV + 1.5 V Default Setting 4.2V

View File

@ -1,7 +1,7 @@
#ifndef ADBMS_DRIVER_H #ifndef ADBMS_DRIVER_H
#define ADBMS_DRIVER_H #define ADBMS_DRIVER_H
#include "stm32h7xx_hal.h" #include "config_ADBMS6830.h"
#include <stdint.h> #include <stdint.h>
#define ERROR_TIME_THRESH 150 // ms #define ERROR_TIME_THRESH 150 // ms
@ -13,8 +13,8 @@ typedef enum : uint16_t {
ADBMS_OVERVOLT, ADBMS_OVERVOLT,
ADBMS_UNDERVOLT, ADBMS_UNDERVOLT,
ADBMS_OPENWIRE, ADBMS_OPENWIRE,
ADBMS_INTERNAL_BMS_TIMEOUT, ADBMS_INTERNAL_BMS_TIMEOUT, // BMS went to sleep too many times
ADBMS_INTERNAL_BMS_CHECKSUM_FAIL, ADBMS_INTERNAL_BMS_CHECKSUM_FAIL, // BMS CRC failed too many times
ADBMS_INTERNAL_BMS_OVERTEMP, ADBMS_INTERNAL_BMS_OVERTEMP,
ADBMS_INTERNAL_BMS_FAULT, ADBMS_INTERNAL_BMS_FAULT,
NUM_ERROR_KINDS NUM_ERROR_KINDS
@ -76,6 +76,7 @@ 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];
extern Cell_Module modules[N_BMS];
[[gnu::nonnull]] ADBMS_DetailedStatus AMS_Init(SPI_HandleTypeDef* hspi); [[gnu::nonnull]] ADBMS_DetailedStatus AMS_Init(SPI_HandleTypeDef* hspi);

View File

@ -14,11 +14,17 @@
extern uint8_t numberofCells; extern uint8_t numberofCells;
static const char* const HAL_Statuses[] = {"HAL_OK", "HAL_ERROR", "HAL_BUSY", "HAL_TIMEOUT"};
#define CHECK_RETURN(x) \ #define CHECK_RETURN(x) \
do { \ do { \
HAL_StatusTypeDef status = x; \ HAL_StatusTypeDef status = x; \
if (status != 0) \ if (status != 0) { \
debug_log(LOG_LEVEL_ERROR, "@%s:%s:%d: %s failed with status %d (%s)", __FILE_NAME__, __func__, __LINE__, \
#x, status, \
(status < (sizeof(HAL_Statuses) / sizeof(HAL_Statuses[0]))) ? HAL_Statuses[status] : "Unknown"); \
return status; \ return status; \
} \
} while (0) } while (0)
HAL_StatusTypeDef amsReset() { HAL_StatusTypeDef amsReset() {
@ -26,7 +32,21 @@ HAL_StatusTypeDef amsReset() {
readCMD(SRST, CMD_EMPTY_BUFFER, 0); readCMD(SRST, CMD_EMPTY_BUFFER, 0);
uint8_t sidbuffer[CMD_BUFFER_SIZE(SID_GROUP_SIZE)] = {}; uint8_t sidbuffer[CMD_BUFFER_SIZE(SID_GROUP_SIZE)] = {};
CHECK_RETURN(readCMD(RDSID, sidbuffer, SID_GROUP_SIZE)); if (readCMD(RDSID, sidbuffer, SID_GROUP_SIZE) != HAL_OK) {
bool nonzero = false;
for (size_t i = 0; i < N_BMS; i++) {
if (sidbuffer[BUFFER_BMS_OFFSET(i, SID_GROUP_SIZE)] != 0) {
nonzero = true;
}
}
if (nonzero) {
debug_log(LOG_LEVEL_ERROR,
"CRC failure when reading BMS IDs, but some IDs are nonzero. --- Intermittent connection?");
} else {
debug_log(LOG_LEVEL_ERROR, "CRC failure when reading BMS IDs, all IDs are zero. --- No connection?");
}
return HAL_ERROR;
}
debug_log(LOG_LEVEL_INFO, "BMS reset complete"); debug_log(LOG_LEVEL_INFO, "BMS reset complete");
@ -69,7 +89,7 @@ HAL_StatusTypeDef amsWakeUp() {
} }
HAL_StatusTypeDef amsCellMeasurement(Cell_Module (*module)[N_BMS]) { HAL_StatusTypeDef amsCellMeasurement(Cell_Module (*module)[N_BMS]) {
#warning check conversion counter to ensure that continous conversion has not been stopped #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 #warning check for OW conditions: ADSV | ADSV_OW_0 / ADSV_OW_1
return amsReadCellVoltages(module); return amsReadCellVoltages(module);
} }
@ -317,8 +337,10 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
return HAL_OK; return HAL_OK;
} }
//Each selected BMS must have a corresponding address, and the data array for that BMS must be at least datalens[i] bytes long // Each selected BMS must have a corresponding address, and the data array for that BMS must be at least datalens[i]
HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t * data[static N_BMS], const uint8_t datalens[static N_BMS], uint32_t bms_mask) { // bytes long
HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t* data[static N_BMS],
const uint8_t datalens[static N_BMS], uint32_t bms_mask) {
uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {}; uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {};
// COMM register works in 3 bytes max per go, interleaved with control information // COMM register works in 3 bytes max per go, interleaved with control information
@ -341,7 +363,8 @@ HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t * da
} }
} }
size_t packet_count = ((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0); //number of 3 byte packets needed to send all data size_t packet_count =
((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0); // number of 3 byte packets needed to send all data
for (size_t i = 0; i < (packet_count * 3); i++) { //i - 1 is the number of data bytes sent so far (1 byte for the address) for (size_t i = 0; i < (packet_count * 3); i++) { //i - 1 is the number of data bytes sent so far (1 byte for the address)
for (size_t j = 0; j < N_BMS; j++) { for (size_t j = 0; j < N_BMS; j++) {
@ -390,8 +413,10 @@ HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t * da
return HAL_OK; return HAL_OK;
} }
//Each selected BMS must have a corresponding address, and the data array for that BMS must be at least datalens[i] bytes long // Each selected BMS must have a corresponding address, and the data array for that BMS must be at least datalens[i]
HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t * data[static N_BMS], const uint8_t datalens[static N_BMS], uint32_t bms_mask) { // bytes long
HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t* data[static N_BMS],
const uint8_t datalens[static N_BMS], uint32_t bms_mask) {
uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {}; uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {};
uint8_t max_datalen = 0; uint8_t max_datalen = 0;

View File

@ -54,7 +54,7 @@ ADBMS_DetailedStatus AMS_Init(SPI_HandleTypeDef* hspi) {
int first_match = -1; \ int first_match = -1; \
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]; \
if (x) { \ if ((x)) { \
first_match = __any_intern_i; \ first_match = __any_intern_i; \
break; \ break; \
} \ } \
@ -68,7 +68,7 @@ ADBMS_DetailedStatus AMS_Idle_Loop() {
// 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
} }
packetChecksumFails += amsAuxAndStatusMeasurement(&modules); packetChecksumFails += (amsAuxAndStatusMeasurement(&modules) == HAL_ERROR);
static int match = 0; static int match = 0;
if ((match = any(module.status.SLEEP))) { if ((match = any(module.status.SLEEP))) {
@ -94,8 +94,8 @@ ADBMS_DetailedStatus AMS_Idle_Loop() {
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT, match}; return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT, match};
} }
packetChecksumFails += amsCellMeasurement(&modules); packetChecksumFails += (amsCellMeasurement(&modules) == HAL_ERROR);
packetChecksumFails += amsCheckUnderOverVoltage(&modules); packetChecksumFails += (amsCheckUnderOverVoltage(&modules) == HAL_ERROR);
if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) { if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) {
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_CHECKSUM_FAIL, -1}; return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_CHECKSUM_FAIL, -1};

View File

@ -15,8 +15,6 @@
#define INITIAL_COMMAND_PEC 0x0010 #define INITIAL_COMMAND_PEC 0x0010
#define INITIAL_DATA_PEC 0x0010 #define INITIAL_DATA_PEC 0x0010
#define ADBMS_SPI_TIMEOUT 100 // Timeout in ms
#warning ask about the timeout value
SPI_HandleTypeDef* adbmsspi; SPI_HandleTypeDef* adbmsspi;

View File

@ -10,7 +10,7 @@ target: AMS Master Nucleo
# Can be C or C++ # Can be C or C++
language: C language: C
optimization: Og optimization: O2
# MCU settings # MCU settings
targetMCU: stm32h7x targetMCU: stm32h7x
@ -43,6 +43,7 @@ cFlags:
- -ffunction-sections - -ffunction-sections
- -std=gnu23 - -std=gnu23
- -flto - -flto
# - -fanalyzer
assemblyFlags: assemblyFlags:
- -Wall - -Wall