cleanup part 1

This commit is contained in:
Kilian Bracher 2025-05-07 23:43:48 +02:00
parent 976eba57d4
commit 2c0d7350e3
Signed by: k.bracher
SSH Key Fingerprint: SHA256:mXpyZkK7RDiJ7qeHCKJX108woM0cl5TrCvNBJASu6lM
20 changed files with 86 additions and 160 deletions

View File

@ -1,3 +1,5 @@
#ifndef INC_NTC_H_
#define INC_NTC_H_
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
@ -21,9 +23,10 @@
[[gnu::optimize("fast-math")]] [[gnu::optimize("fast-math")]]
static inline uint16_t ntc_mv_to_celsius(int16_t adc) { static inline uint16_t ntc_mv_to_celsius(int16_t adc) {
float log_ohms = logf(1 / ((VREF / adc) - 1)); const float log_ohms = logf(1 / ((VREF / adc) - 1));
return (uint16_t) (TEMP_CONV / (NTC_A1 + NTC_B1 * log_ohms + NTC_C1 * log_ohms * log_ohms + NTC_D1 * log_ohms * log_ohms * log_ohms) - CELSIUS_TO_KELVIN_SCALED); return (uint16_t) (TEMP_CONV / (NTC_A1 + NTC_B1 * log_ohms + NTC_C1 * log_ohms * log_ohms + NTC_D1 * log_ohms * log_ohms * log_ohms) - CELSIUS_TO_KELVIN_SCALED);
} }
#else #else
// Lookup Table coming soon; not really needed but fun? // Lookup Table coming soon; not really needed but fun?
#endif #endif
#endif

View File

@ -8,7 +8,6 @@
#ifndef INC_ADBMS_CMD_MAKROS_H_ #ifndef INC_ADBMS_CMD_MAKROS_H_
#define INC_ADBMS_CMD_MAKROS_H_ #define INC_ADBMS_CMD_MAKROS_H_
#include <stdint.h>
#define WRCFGA 0x0001 // Write Configuration Register Group A #define WRCFGA 0x0001 // Write Configuration Register Group A
#define RDCFGA 0x0002 // Read Configuration Register Group A #define RDCFGA 0x0002 // Read Configuration Register Group A
#define WRCFGB 0x0024 // Write Configuration Register Group B #define WRCFGB 0x0024 // Write Configuration Register Group B

View File

@ -89,8 +89,6 @@ typedef struct {
int16_t auxVoltages[MAXIMUM_AUX_VOLTAGES]; int16_t auxVoltages[MAXIMUM_AUX_VOLTAGES];
} Cell_Module; } Cell_Module;
extern uint32_t error_sources; // Bitfield of error sources
extern SlaveErrorData error_data[NUM_ERROR_KINDS];
extern Cell_Module modules[N_BMS]; 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

@ -1,18 +0,0 @@
//
// Created by kbracher on 2/6/25.
//
#ifndef AMS_MASTER_CODE_ADBMS_ERROR_H
#define AMS_MASTER_CODE_ADBMS_ERROR_H
#include "ADBMS_Driver.h"
#include <limits.h>
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_Status source);
void clear_error_source(ADBMS_Status source);
#endif //AMS_MASTER_CODE_ADBMS_ERROR_H

View File

@ -1,33 +0,0 @@
/*
* AMS_HighLevel.h
*
* Created on: 20.07.2022
* Author: max
*/
#ifndef INC_AMS_HIGHLEVEL_H_
#define INC_AMS_HIGHLEVEL_H_
#include "ADBMS_Abstraction.h"
#include "ADBMS_CMD_MAKROS.h"
#include "ADBMS_LL_Driver.h"
#include "config_ADBMS6830.h"
#include <stdbool.h>
typedef enum {
AMSDEACTIVE,
AMSIDLE,
AMSCHARGING,
AMSIDLEBALANCING,
AMSDISCHARGING,
AMSWARNING,
AMSERROR
} amsState;
extern amsState currentAMSState;
extern Cell_Module modules[N_BMS];
extern uint32_t balancedCells;
extern bool BalancingActive;
#endif /* INC_AMS_HIGHLEVEL_H_ */

View File

@ -103,7 +103,7 @@ HAL_StatusTypeDef amsAuxAndStatusMeasurement(Cell_Module (*module)[N_BMS]) {
uint8_t rxbuf[CMD_BUFFER_SIZE(STATUS_GROUP_C_SIZE)] = {}; uint8_t rxbuf[CMD_BUFFER_SIZE(STATUS_GROUP_C_SIZE)] = {};
CHECK_RETURN(readCMD(RDSTATC, rxbuf, STATUS_GROUP_C_SIZE)); CHECK_RETURN(readCMD(RDSTATC, rxbuf, STATUS_GROUP_C_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_C_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_C_SIZE);
(*module)[i].status.CS_FLT = rxbuf[offset + 0] | (rxbuf[offset + 1] << 8); (*module)[i].status.CS_FLT = rxbuf[offset + 0] | (rxbuf[offset + 1] << 8);
(*module)[i].status.CCTS = rxbuf[offset + 2] | (rxbuf[offset + 3] << 8); (*module)[i].status.CCTS = rxbuf[offset + 2] | (rxbuf[offset + 3] << 8);
(*module)[i].status.VA_OV = (rxbuf[offset + 4] >> 7) & 0x01; (*module)[i].status.VA_OV = (rxbuf[offset + 4] >> 7) & 0x01;
@ -136,7 +136,7 @@ HAL_StatusTypeDef amsAuxAndStatusMeasurement(Cell_Module (*module)[N_BMS]) {
for (size_t group = 0; group < 4; group++) { for (size_t group = 0; group < 4; group++) {
CHECK_RETURN(readCMD(auxCommands[group], rxbuf, auxGroupSizes[group])); CHECK_RETURN(readCMD(auxCommands[group], rxbuf, auxGroupSizes[group]));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, auxGroupSizes[group]); const size_t offset = BUFFER_BMS_OFFSET(i, auxGroupSizes[group]);
for (size_t j = 0; j < auxVoltagesPerGroup[group]; j++) { for (size_t j = 0; j < auxVoltagesPerGroup[group]; j++) {
(*module)[i].auxVoltages[group * 3 + j] = mV_from_ADBMS6830(rxbuf[offset + j * 2] | (rxbuf[offset + j * 2 + 1] << 8)); (*module)[i].auxVoltages[group * 3 + j] = mV_from_ADBMS6830(rxbuf[offset + j * 2] | (rxbuf[offset + j * 2 + 1] << 8));
} }
@ -146,13 +146,13 @@ HAL_StatusTypeDef amsAuxAndStatusMeasurement(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDSTATA, rxbuf, STATUS_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDSTATA, rxbuf, STATUS_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_A_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_A_SIZE);
(*module)[i].internalDieTemp = (mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8)) / 7.5f) - 273; //datasheet page 72 (*module)[i].internalDieTemp = (mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8)) / 7.5f) - 273; //datasheet page 72
} }
CHECK_RETURN(readCMD(RDSTATB, rxbuf, STATUS_GROUP_B_SIZE)); CHECK_RETURN(readCMD(RDSTATB, rxbuf, STATUS_GROUP_B_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_B_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_B_SIZE);
(*module)[i].digitalSupplyVoltage = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8)); (*module)[i].digitalSupplyVoltage = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8));
(*module)[i].analogSupplyVoltage = mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8)); (*module)[i].analogSupplyVoltage = mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8));
(*module)[i].refVoltage = mV_from_ADBMS6830(rxbuf[offset + 4] | (rxbuf[offset + 5] << 8)); (*module)[i].refVoltage = mV_from_ADBMS6830(rxbuf[offset + 4] | (rxbuf[offset + 5] << 8));
@ -175,12 +175,12 @@ HAL_StatusTypeDef amsConfigBalancing(const uint32_t channels[static N_BMS], uint
CHECK_RETURN(readCMD(RDPWMB, rxbufB, PWM_GROUP_B_SIZE)); CHECK_RETURN(readCMD(RDPWMB, rxbufB, PWM_GROUP_B_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offsetA = BUFFER_BMS_OFFSET(i, PWM_GROUP_A_SIZE); const size_t offsetA = BUFFER_BMS_OFFSET(i, PWM_GROUP_A_SIZE);
size_t offsetB = BUFFER_BMS_OFFSET(i, PWM_GROUP_B_SIZE); const size_t offsetB = BUFFER_BMS_OFFSET(i, PWM_GROUP_B_SIZE);
for (size_t c = 0; c < 16; c += 2) { for (size_t c = 0; c < 16; c += 2) {
uint8_t high = (channels[i] & (1 << (c + 1))) ? (dutyCycle << 4) : 0; const uint8_t high = (channels[i] & (1 << (c + 1))) ? (dutyCycle << 4) : 0;
uint8_t low = (channels[i] & (1 << c)) ? dutyCycle : 0; const uint8_t low = (channels[i] & (1 << c)) ? dutyCycle : 0;
if (c < 12) { if (c < 12) {
rxbufA[offsetA + (c / 2)] = high | low; rxbufA[offsetA + (c / 2)] = high | low;
@ -231,7 +231,7 @@ HAL_StatusTypeDef amsConfigOverUnderVoltage(uint16_t overVoltage, uint16_t under
} }
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CFG_GROUP_B_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, CFG_GROUP_B_SIZE);
// UV // UV
buffer[offset + 0] = (uint8_t)(underVoltage & 0xFF); buffer[offset + 0] = (uint8_t)(underVoltage & 0xFF);
@ -253,7 +253,7 @@ HAL_StatusTypeDef amsCheckUnderOverVoltage(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDSTATD, regbuffer, STATUS_GROUP_D_SIZE)); CHECK_RETURN(readCMD(RDSTATD, regbuffer, STATUS_GROUP_D_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_D_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_D_SIZE);
uint32_t ov_uv_data = 0; uint32_t ov_uv_data = 0;
ov_uv_data = (regbuffer[offset + 0] << 0) | (regbuffer[offset + 1] << 8) | (regbuffer[offset + 2] << 16) | ov_uv_data = (regbuffer[offset + 0] << 0) | (regbuffer[offset + 1] << 8) | (regbuffer[offset + 2] << 16) |
(regbuffer[offset + 3] << 24); (regbuffer[offset + 3] << 24);
@ -289,7 +289,7 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDCVA, rxbuffer, CV_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDCVA, rxbuffer, CV_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); const 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[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[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)); (*module)[i].cellVoltages[2] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8));
@ -297,7 +297,7 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDCVB, rxbuffer, CV_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDCVB, rxbuffer, CV_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); const 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[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[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)); (*module)[i].cellVoltages[5] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8));
@ -305,7 +305,7 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDCVC, rxbuffer, CV_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDCVC, rxbuffer, CV_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); const 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[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[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)); (*module)[i].cellVoltages[8] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8));
@ -313,7 +313,7 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDCVD, rxbuffer, CV_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDCVD, rxbuffer, CV_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); const 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[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[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)); (*module)[i].cellVoltages[11] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8));
@ -321,7 +321,7 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDCVE, rxbuffer, CV_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDCVE, rxbuffer, CV_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); const 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[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[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)); (*module)[i].cellVoltages[14] = mV_from_ADBMS6830(rxbuffer[offset + 4] | (rxbuffer[offset + 5] << 8));
@ -329,7 +329,7 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
CHECK_RETURN(readCMD(RDCVF, rxbuffer, CV_GROUP_A_SIZE)); CHECK_RETURN(readCMD(RDCVF, rxbuffer, CV_GROUP_A_SIZE));
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, CV_GROUP_A_SIZE); const 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)); (*module)[i].cellVoltages[15] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8));
} }
@ -352,7 +352,7 @@ HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t* dat
} }
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << i))) { if (!(bms_mask & (1 << i))) {
buffer[offset + 0] = I2C_SEND_NOTRANSFER; buffer[offset + 0] = I2C_SEND_NOTRANSFER;
@ -362,12 +362,12 @@ HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t* dat
} }
} }
size_t packet_count = const size_t packet_count =
((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0); // number of 3 byte packets needed to send all data ((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++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE); const size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j))) if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected continue; // skip BMS that are not selected
@ -426,7 +426,7 @@ HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t* dat
} }
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE); const size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << i))) { if (!(bms_mask & (1 << i))) {
buffer[offset + 0] = I2C_SEND_NOTRANSFER; buffer[offset + 0] = I2C_SEND_NOTRANSFER;
@ -436,7 +436,7 @@ HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t* dat
} }
} }
size_t packet_count = ((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0); const size_t packet_count = ((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0);
for (size_t i = 0; i < (packet_count * 3); 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) i++) { // i - 1 is the number of data bytes sent so far (1 byte for the address)
@ -480,7 +480,7 @@ HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t* dat
CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE)); CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE));
for (size_t j = 0; j < N_BMS; j++) { for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE); const size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j))) if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected continue; // skip BMS that are not selected
@ -504,7 +504,7 @@ HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t* dat
CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE)); CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE));
for (size_t j = 0; j < N_BMS; j++) { for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE); const size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j))) if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected continue; // skip BMS that are not selected

View File

@ -1,17 +0,0 @@
#include "ADBMS_Error.h"
#include "stm32h7xx_hal.h"
SlaveErrorData error_data[NUM_ERROR_KINDS] = {};
uint32_t error_sources = 0;
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_Status source) {
error_data[source].errors_since = 0;
error_sources &= ~(1 << source);
}

View File

@ -4,8 +4,6 @@
* Created on: 20.07.2022 * Created on: 20.07.2022
* Author: max * Author: max
*/ */
#include "ADBMS_HighLevel.h"
#include "ADBMS_Abstraction.h" #include "ADBMS_Abstraction.h"
#include "ADBMS_Driver.h" #include "ADBMS_Driver.h"
#include "config_ADBMS6830.h" #include "config_ADBMS6830.h"
@ -17,8 +15,6 @@
#include "swo_log.h" #include "swo_log.h"
Cell_Module modules[N_BMS] = {}; Cell_Module modules[N_BMS] = {};
uint32_t balancedCells = 0;
bool balancingActive = false;
uint8_t packetChecksumFails = 0; uint8_t packetChecksumFails = 0;
#define MAX_PACKET_CHECKSUM_FAILS 5 #define MAX_PACKET_CHECKSUM_FAILS 5

View File

@ -34,9 +34,8 @@ uint8_t adbmsDriverInit(SPI_HandleTypeDef* hspi) {
return 0; return 0;
} }
static HAL_StatusTypeDef mcuSPITransmit(uint8_t* buffer, uint8_t buffersize) { static HAL_StatusTypeDef mcuSPITransmit(const uint8_t* buffer, uint8_t buffersize) {
HAL_StatusTypeDef status; const HAL_StatusTypeDef status = HAL_SPI_Transmit(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
status = HAL_SPI_Transmit(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
__HAL_SPI_CLEAR_OVRFLAG(adbmsspi); __HAL_SPI_CLEAR_OVRFLAG(adbmsspi);
return status; return status;
} }
@ -45,7 +44,7 @@ static HAL_StatusTypeDef mcuSPIReceive(uint8_t* buffer, uint8_t buffersize) {
return HAL_SPI_Receive(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT); return HAL_SPI_Receive(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
} }
static HAL_StatusTypeDef mcuSPITransmitReceive(uint8_t* rxbuffer, uint8_t* txbuffer, uint8_t buffersize) { static HAL_StatusTypeDef mcuSPITransmitReceive(uint8_t* rxbuffer, const uint8_t* txbuffer, uint8_t buffersize) {
return HAL_SPI_TransmitReceive(adbmsspi, txbuffer, rxbuffer, buffersize, ADBMS_SPI_TIMEOUT); return HAL_SPI_TransmitReceive(adbmsspi, txbuffer, rxbuffer, buffersize, ADBMS_SPI_TIMEOUT);
} }
@ -70,17 +69,17 @@ static uint16_t computeCRC15(const uint8_t* data, size_t length) {
static uint8_t calculateCommandPEC(uint8_t* data, uint8_t datalen) { static uint8_t calculateCommandPEC(uint8_t* data, uint8_t datalen) {
if (datalen < 3) { return 1; } if (datalen < 3) { return 1; }
uint16_t pec = computeCRC15(data, datalen - 2); const uint16_t pec = computeCRC15(data, datalen - 2);
data[datalen - 2] = (uint8_t)((pec >> 7) & 0xFF); data[datalen - 2] = (uint8_t)((pec >> 7) & 0xFF);
data[datalen - 1] = (uint8_t)((pec << 1) & 0xFF); data[datalen - 1] = (uint8_t)((pec << 1) & 0xFF);
return 0; return 0;
} }
static uint8_t checkCommandPEC(uint8_t* data, uint8_t datalen) { static uint8_t checkCommandPEC(const uint8_t* data, uint8_t datalen) {
if (datalen <= 3) { return 255; } if (datalen <= 3) { return 255; }
uint16_t pec = computeCRC15(data, datalen - 2); const uint16_t pec = computeCRC15(data, datalen - 2);
uint8_t pech = (uint8_t)((pec >> 7) & 0xFF); const uint8_t pech = (uint8_t)((pec >> 7) & 0xFF);
uint8_t pecl = (uint8_t)((pec << 1) & 0xFF); const uint8_t pecl = (uint8_t)((pec << 1) & 0xFF);
return ((pech == data[datalen - 2]) && (pecl == data[datalen - 1])) ? 0 : 1; return ((pech == data[datalen - 2]) && (pecl == data[datalen - 1])) ? 0 : 1;
} }
@ -118,13 +117,13 @@ static uint16_t computeCRC10(const uint8_t* data, size_t length, bool rx_cmd) {
static uint8_t calculateDataPEC(uint8_t* data, uint8_t datalen) { static uint8_t calculateDataPEC(uint8_t* data, uint8_t datalen) {
if (datalen < 3) { return 1; } if (datalen < 3) { return 1; }
uint16_t crcVal = computeCRC10(data, datalen - 2, true); const uint16_t crcVal = computeCRC10(data, datalen - 2, true);
data[datalen - 2] = (uint8_t)((crcVal >> 8) & 0xFF); data[datalen - 2] = (uint8_t)((crcVal >> 8) & 0xFF);
data[datalen - 1] = (uint8_t)(crcVal & 0xFF); data[datalen - 1] = (uint8_t)(crcVal & 0xFF);
return 0; return 0;
} }
static uint8_t checkDataPEC(uint8_t* data, uint8_t len) { static uint8_t checkDataPEC(const uint8_t* data, uint8_t len) {
if (len <= 2) { return 255; } if (len <= 2) { return 255; }
// Zero remainder means a valid CRC. // Zero remainder means a valid CRC.
return (computeCRC10(data, len, false) == 0) ? 0 : 1; return (computeCRC10(data, len, false) == 0) ? 0 : 1;
@ -133,7 +132,7 @@ static uint8_t checkDataPEC(uint8_t* data, uint8_t len) {
static const char* const HAL_Statuses[] = {"HAL_OK", "HAL_ERROR", "HAL_BUSY", "HAL_TIMEOUT"}; static const char* const HAL_Statuses[] = {"HAL_OK", "HAL_ERROR", "HAL_BUSY", "HAL_TIMEOUT"};
static void print_spi_details() { static void print_spi_details() {
uint32_t spi_error = HAL_SPI_GetError(adbmsspi); const uint32_t spi_error = HAL_SPI_GetError(adbmsspi);
typedef struct { typedef struct {
uint32_t mask; uint32_t mask;
@ -176,15 +175,12 @@ HAL_StatusTypeDef ___writeCMD(uint16_t command, uint8_t * args, size_t arglen) {
if (DEBUG_CHANNEL_ENABLED(LOG_LEVEL_NOISY)) { if (DEBUG_CHANNEL_ENABLED(LOG_LEVEL_NOISY)) {
debug_log(LOG_LEVEL_NOISY, "%lu W | %02X %02X ", HAL_GetTick(), args[0], args[1]); debug_log(LOG_LEVEL_NOISY, "%lu W | %02X %02X ", HAL_GetTick(), args[0], args[1]);
//print out data bytes
if (arglen > 0) {
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
debug_log_cont(LOG_LEVEL_NOISY, "%d: ", i); debug_log_cont(LOG_LEVEL_NOISY, "%d: ", i);
for (size_t j = 0; j < arglen; j++) { for (size_t j = 0; j < arglen; j++) {
debug_log_cont(LOG_LEVEL_NOISY, "%02X ", args[BUFFER_BMS_OFFSET(i, arglen) + j]); debug_log_cont(LOG_LEVEL_NOISY, "%02X ", args[BUFFER_BMS_OFFSET(i, arglen) + j]);
} }
} }
}
} }
calculateCommandPEC(args, 4); calculateCommandPEC(args, 4);
@ -223,7 +219,7 @@ HAL_StatusTypeDef ___readCMD(uint16_t command, uint8_t * buffer, size_t arglen)
calculateCommandPEC(buffer, 4); calculateCommandPEC(buffer, 4);
mcuAdbmsCSLow(); mcuAdbmsCSLow();
HAL_StatusTypeDef status = mcuSPITransmitReceive(buffer, buffer, CMD_BUFFER_SIZE(arglen)); const HAL_StatusTypeDef status = mcuSPITransmitReceive(buffer, buffer, CMD_BUFFER_SIZE(arglen));
mcuAdbmsCSHigh(); mcuAdbmsCSHigh();
if (status != HAL_OK) { if (status != HAL_OK) {
@ -256,7 +252,7 @@ HAL_StatusTypeDef ___readCMD(uint16_t command, uint8_t * buffer, size_t arglen)
//check data PEC //check data PEC
for (size_t i = 0; i < N_BMS; i++) { for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, arglen); const size_t offset = BUFFER_BMS_OFFSET(i, arglen);
if (checkDataPEC(&buffer[offset], arglen + 2) != 0) { if (checkDataPEC(&buffer[offset], arglen + 2) != 0) {
debug_log(LOG_LEVEL_ERROR, "Invalid data PEC when reading BMS %d", i); debug_log(LOG_LEVEL_ERROR, "Invalid data PEC when reading BMS %d", i);
debug_log(LOG_LEVEL_ERROR, "Received: "); debug_log(LOG_LEVEL_ERROR, "Received: ");
@ -286,7 +282,7 @@ HAL_StatusTypeDef __pollCMD(uint16_t command, uint8_t waitTime) {
calculateCommandPEC(buffer, 4); calculateCommandPEC(buffer, 4);
mcuAdbmsCSLow(); mcuAdbmsCSLow();
HAL_StatusTypeDef status = mcuSPITransmitReceive(buffer, buffer, sizeof buffer); const HAL_StatusTypeDef status = mcuSPITransmitReceive(buffer, buffer, sizeof buffer);
mcuAdbmsCSHigh(); mcuAdbmsCSHigh();
if (status != HAL_OK) { if (status != HAL_OK) {

View File

@ -33,8 +33,8 @@ static bool buffer_message(const log_message_t* message) {
uint32_t* write_pos = using_buffer_2 ? &message_buffer.write_pos_2 : &message_buffer.write_pos; uint32_t* write_pos = using_buffer_2 ? &message_buffer.write_pos_2 : &message_buffer.write_pos;
/* Calculate buffer offset - buffer 2 starts at ISOTP_LOG_BUFFER_1_BYTES */ /* Calculate buffer offset - buffer 2 starts at ISOTP_LOG_BUFFER_1_BYTES */
uint32_t buffer_offset = using_buffer_2 ? ISOTP_LOG_BUFFER_1_BYTES : 0; const uint32_t buffer_offset = using_buffer_2 ? ISOTP_LOG_BUFFER_1_BYTES : 0;
uint32_t max_size = using_buffer_2 ? ISOTP_LOG_BUFFER_2_BYTES : ISOTP_LOG_BUFFER_1_BYTES; // Each buffer has its own size const uint32_t max_size = using_buffer_2 ? ISOTP_LOG_BUFFER_2_BYTES : ISOTP_LOG_BUFFER_1_BYTES; // Each buffer has its own size
/* Check if we have enough space in the current buffer */ /* Check if we have enough space in the current buffer */
if (*write_pos + message->message_length > max_size) { if (*write_pos + message->message_length > max_size) {
@ -54,7 +54,7 @@ static bool buffer_message(const log_message_t* message) {
/* Swap buffers and prepare for sending */ /* Swap buffers and prepare for sending */
static bool swap_buffers_for_sending() { static bool swap_buffers_for_sending() {
/* Don't swap if there's nothing to send */ /* Don't swap if there's nothing to send */
uint32_t* current_pos = using_buffer_2 ? &message_buffer.write_pos_2 : &message_buffer.write_pos; const uint32_t* current_pos = using_buffer_2 ? &message_buffer.write_pos_2 : &message_buffer.write_pos;
if (*current_pos == 0) { if (*current_pos == 0) {
return false; return false;
} }
@ -102,7 +102,7 @@ void isotp_log_backend_init(void) {
isotp_backend_registered = log_register_backend(&isotp_backend); isotp_backend_registered = log_register_backend(&isotp_backend);
/* Set up ISO-TP connection */ /* Set up ISO-TP connection */
int status = isotp_add_connection(ISOTP_LOG_FC_CAN_ID, ISOTP_LOG_CAN_ID, ISOTP_FLAGS_NONE); const int status = isotp_add_connection(ISOTP_LOG_FC_CAN_ID, ISOTP_LOG_CAN_ID, ISOTP_FLAGS_NONE);
if (status < 0) { if (status < 0) {
log_error("Failed to add ISO-TP connection: %s", isotp_status_to_string((isotp_status_t)status)); log_error("Failed to add ISO-TP connection: %s", isotp_status_to_string((isotp_status_t)status));
return; return;
@ -154,12 +154,12 @@ static void isotp_backend_flush(void) {
/* Swap buffers if we have data to send and we're ready to send */ /* Swap buffers if we have data to send and we're ready to send */
if (streaming_enabled) { if (streaming_enabled) {
/* Get the buffer that is currently being written to */ /* Get the buffer that is currently being written to */
uint32_t buffer_offset = !using_buffer_2 ? 0 : ISOTP_LOG_BUFFER_1_BYTES; const uint32_t buffer_offset = !using_buffer_2 ? 0 : ISOTP_LOG_BUFFER_1_BYTES;
uint32_t buffer_size = !using_buffer_2 ? message_buffer.write_pos : message_buffer.write_pos_2; const uint32_t buffer_size = !using_buffer_2 ? message_buffer.write_pos : message_buffer.write_pos_2;
/* Only send if we have data and a previous send is not in progress */ /* Only send if we have data and a previous send is not in progress */
if (buffer_size > 0) { if (buffer_size > 0) {
isotp_status_t status = isotp_add_message( const isotp_status_t status = isotp_add_message(
isotp_connection_id, isotp_connection_id,
message_buffer.buffer + buffer_offset, message_buffer.buffer + buffer_offset,
buffer_size buffer_size

View File

@ -11,7 +11,7 @@
#include "stm32h7xx_hal.h" #include "stm32h7xx_hal.h"
/* Backend management */ /* Backend management */
static const log_backend_t* registered_backends[MAX_LOG_BACKENDS] = {0}; static const log_backend_t* registered_backends[MAX_LOG_BACKENDS] = {};
static uint8_t backend_count = 0; static uint8_t backend_count = 0;
/* Register a new logging backend */ /* Register a new logging backend */

View File

@ -46,7 +46,7 @@ static inline void update_error_window(bool error, int id) {
} }
HAL_StatusTypeDef battery_init(SPI_HandleTypeDef *hspi) { HAL_StatusTypeDef battery_init(SPI_HandleTypeDef *hspi) {
auto ret = AMS_Init(hspi); const auto ret = AMS_Init(hspi);
if (ret.status != ADBMS_NO_ERROR) { if (ret.status != ADBMS_NO_ERROR) {
debug_log(LOG_LEVEL_ERROR, "Failed to initialize BMS: %s", debug_log(LOG_LEVEL_ERROR, "Failed to initialize BMS: %s",
ADBMS_Status_ToString(ret.status)); ADBMS_Status_ToString(ret.status));
@ -61,7 +61,7 @@ HAL_StatusTypeDef battery_init(SPI_HandleTypeDef *hspi) {
[[gnu::optimize("no-math-errno")]] [[gnu::optimize("no-math-errno")]]
HAL_StatusTypeDef battery_update() { HAL_StatusTypeDef battery_update() {
auto ret = AMS_Idle_Loop(); const auto ret = AMS_Idle_Loop();
if (ret.status != ADBMS_NO_ERROR) { if (ret.status != ADBMS_NO_ERROR) {
debug_log(LOG_LEVEL_ERROR, "Error while updating battery data: %s", debug_log(LOG_LEVEL_ERROR, "Error while updating battery data: %s",
ADBMS_Status_ToString(ret.status)); ADBMS_Status_ToString(ret.status));
@ -72,7 +72,7 @@ HAL_StatusTypeDef battery_update() {
if (ret.status == ADBMS_OVERVOLT || ret.status == ADBMS_UNDERVOLT) { if (ret.status == ADBMS_OVERVOLT || ret.status == ADBMS_UNDERVOLT) {
if (ret.bms_id != -1 && ret.bms_id < N_BMS) { if (ret.bms_id != -1 && ret.bms_id < N_BMS) {
const char* error_type = (ret.status == ADBMS_OVERVOLT) ? "overvoltage" : "undervoltage"; const char* error_type = (ret.status == ADBMS_OVERVOLT) ? "overvoltage" : "undervoltage";
uint32_t voltage_flags = (ret.status == ADBMS_OVERVOLT) ? const uint32_t voltage_flags = (ret.status == ADBMS_OVERVOLT) ?
modules[ret.bms_id].overVoltage : modules[ret.bms_id].overVoltage :
modules[ret.bms_id].underVoltage; modules[ret.bms_id].underVoltage;
@ -117,7 +117,7 @@ HAL_StatusTypeDef battery_update() {
// Second pass: calculate variance // Second pass: calculate variance
for (size_t j = 0; j < N_CELLS; j++) { for (size_t j = 0; j < N_CELLS; j++) {
float diff = modules[i].cellVoltages[j] - mean; const float diff = modules[i].cellVoltages[j] - mean;
variance += diff * diff; variance += diff * diff;
} }
variance /= N_CELLS; variance /= N_CELLS;

View File

@ -35,7 +35,7 @@ void can_init(FDCAN_HandleTypeDef *handle) {
ftcan_add_filter(CAN_ID_AMS_DETAILS_FC, 0xFFF); ftcan_add_filter(CAN_ID_AMS_DETAILS_FC, 0xFFF);
ftcan_add_filter(ISOTP_LOG_FC_CAN_ID, 0xFFF); ftcan_add_filter(ISOTP_LOG_FC_CAN_ID, 0xFFF);
auto status = isotp_add_connection(CAN_ID_AMS_DETAILS_FC, CAN_ID_AMS_DETAILS, ISOTP_FLAGS_NONE); const auto status = isotp_add_connection(CAN_ID_AMS_DETAILS_FC, CAN_ID_AMS_DETAILS, ISOTP_FLAGS_NONE);
if (status < 0) { if (status < 0) {
log_warning("Failed to add ISO-TP connection: %s", isotp_status_to_string((isotp_status_t)status)); log_warning("Failed to add ISO-TP connection: %s", isotp_status_to_string((isotp_status_t)status));
} }
@ -58,7 +58,7 @@ HAL_StatusTypeDef can_send_status() {
} else { } else {
data[7] = 0xFF; data[7] = 0xFF;
} }
HAL_StatusTypeDef ret = ftcan_transmit(CAN_ID_AMS_STATUS, data, sizeof(data)); const HAL_StatusTypeDef ret = ftcan_transmit(CAN_ID_AMS_STATUS, data, sizeof(data));
if (ret != HAL_OK) { if (ret != HAL_OK) {
return ret; return ret;
} }
@ -71,7 +71,7 @@ HAL_StatusTypeDef can_send_status() {
HAL_StatusTypeDef can_send_details() { HAL_StatusTypeDef can_send_details() {
static uint8_t module_index = 0; static uint8_t module_index = 0;
static uint8_t data[103] = {}; //sizeof(Cell_Module) + 10 + 1 static uint8_t data[103] = {}; //sizeof(Cell_Module) + 10 + 1
auto module = &modules[module_index]; const auto module = &modules[module_index];
auto data_ptr = &data[1]; auto data_ptr = &data[1];
isotp_status_t status = isotp_try_add_message(isotp_connection_id, data, sizeof(data)); isotp_status_t status = isotp_try_add_message(isotp_connection_id, data, sizeof(data));
@ -164,7 +164,7 @@ void ftcan_msg_received_cb(uint16_t id, size_t len, const uint8_t *data) {
switch (id) { switch (id) {
case ISOTP_LOG_FC_CAN_ID: case ISOTP_LOG_FC_CAN_ID:
case CAN_ID_AMS_DETAILS_FC: case CAN_ID_AMS_DETAILS_FC:
auto status = isotp_handle_incoming(id, data, len); const auto status = isotp_handle_incoming(id, data, len);
if (status != ISOTP_OK) { if (status != ISOTP_OK) {
log_debug("Error when handling flow control: %s", isotp_status_to_string(status)); log_debug("Error when handling flow control: %s", isotp_status_to_string(status));
} }
@ -172,5 +172,7 @@ void ftcan_msg_received_cb(uint16_t id, size_t len, const uint8_t *data) {
case CAN_ID_AMS_IN: case CAN_ID_AMS_IN:
ts_sm_handle_ams_in(data); ts_sm_handle_ams_in(data);
break; break;
default:
break;
} }
} }

View File

@ -32,7 +32,7 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *handle) {
if (handle != htim || htim->Channel != HAL_TIM_ACTIVE_CHANNEL_1) { if (handle != htim || htim->Channel != HAL_TIM_ACTIVE_CHANNEL_1) {
return; return;
} }
uint32_t period = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); const uint32_t period = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
if (period == 0) { if (period == 0) {
// First edge, ignore // First edge, ignore
return; return;
@ -40,7 +40,7 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *handle) {
imd_data.last_high = HAL_GetTick(); imd_data.last_high = HAL_GetTick();
imd_data.freq = FREQ_TIMER / period; imd_data.freq = FREQ_TIMER / period;
uint32_t high_time = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); const uint32_t high_time = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
imd_data.duty_cycle = (100 * high_time) / period; imd_data.duty_cycle = (100 * high_time) / period;
// Check PWM frequency for state determination // Check PWM frequency for state determination

View File

@ -12,7 +12,7 @@
#include "swo_log_backend.h" #include "swo_log_backend.h"
void print_master_status() { void print_master_status() {
auto backend = swo_log_get_backend(); const auto backend = swo_log_get_backend();
if (!backend->is_enabled(LOG_LEVEL_INFO)) { if (!backend->is_enabled(LOG_LEVEL_INFO)) {
return; // No need to print if the backend is not enabled for this log level return; // No need to print if the backend is not enabled for this log level

View File

@ -8,7 +8,7 @@
#include "swo_log_backend.h" #include "swo_log_backend.h"
void print_battery_info() { void print_battery_info() {
auto backend = swo_log_get_backend(); const auto backend = swo_log_get_backend();
if (!backend->is_enabled(LOG_LEVEL_INFO)) { if (!backend->is_enabled(LOG_LEVEL_INFO)) {
return; // No need to print if the backend is not enabled for this log level return; // No need to print if the backend is not enabled for this log level

View File

@ -35,14 +35,14 @@ void shunt_handle_can_msg(uint16_t id, const uint8_t *data) {
shunt_data.last_message = HAL_GetTick(); shunt_data.last_message = HAL_GetTick();
// All result messages contain a big-endian 6-byte integer // All result messages contain a big-endian 6-byte integer
uint64_t result = ftcan_unmarshal_unsigned(&data, 6); const uint64_t result = ftcan_unmarshal_unsigned(&data, 6);
switch (id) { switch (id) {
case CAN_ID_SHUNT_CURRENT: case CAN_ID_SHUNT_CURRENT:
shunt_data.current = result; shunt_data.current = result;
if (shunt_data.last_current_message > 0) { if (shunt_data.last_current_message > 0) {
uint32_t now = HAL_GetTick(); const uint32_t now = HAL_GetTick();
float dt = (now - shunt_data.last_current_message) * 0.001f; const float dt = (now - shunt_data.last_current_message) * 0.001f;
shunt_data.current_counter += shunt_data.current * dt; shunt_data.current_counter += shunt_data.current * dt;
} }
shunt_data.last_current_message = HAL_GetTick(); shunt_data.last_current_message = HAL_GetTick();

View File

@ -32,7 +32,7 @@ void soc_init() {
} }
void soc_update() { void soc_update() {
uint32_t now = HAL_GetTick(); const uint32_t now = HAL_GetTick();
if (abs(shunt_data.current) >= SOC_ESTIMATION_NO_CURRENT_THRESH) { if (abs(shunt_data.current) >= SOC_ESTIMATION_NO_CURRENT_THRESH) {
last_current_time = now; last_current_time = now;
if (!current_was_flowing) { if (!current_was_flowing) {
@ -51,15 +51,15 @@ void soc_update() {
current_soc = soc_for_ocv(min_voltage); current_soc = soc_for_ocv(min_voltage);
} else { } else {
// Otherwise, use the current counter to update SoC // Otherwise, use the current counter to update SoC
float as_delta = shunt_data.current_counter - mAs_before_current; const float as_delta = shunt_data.current_counter - mAs_before_current;
float soc_delta = as_delta / SOC_ESTIMATION_BATTERY_CAPACITY * 100; const float soc_delta = as_delta / SOC_ESTIMATION_BATTERY_CAPACITY * 100;
current_soc = soc_before_current - soc_delta; current_soc = soc_before_current - soc_delta;
} }
} }
float soc_for_ocv(uint16_t ocv) { float soc_for_ocv(uint16_t ocv) {
size_t i = 0; size_t i = 0;
size_t array_length = sizeof(OCV_SOC_PAIRS) / sizeof(*OCV_SOC_PAIRS); 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 // Find the index of the first element with OCV greater than the target OCV
while (i < array_length && OCV_SOC_PAIRS[i].ocv <= ocv) { while (i < array_length && OCV_SOC_PAIRS[i].ocv <= ocv) {
i++; i++;
@ -78,13 +78,13 @@ float soc_for_ocv(uint16_t ocv) {
} }
// Perform linear interpolation // Perform linear interpolation
uint16_t ocv1 = OCV_SOC_PAIRS[i - 1].ocv; const uint16_t ocv1 = OCV_SOC_PAIRS[i - 1].ocv;
uint16_t ocv2 = OCV_SOC_PAIRS[i].ocv; const uint16_t ocv2 = OCV_SOC_PAIRS[i].ocv;
float soc1 = OCV_SOC_PAIRS[i - 1].soc; const float soc1 = OCV_SOC_PAIRS[i - 1].soc;
float soc2 = OCV_SOC_PAIRS[i].soc; const float soc2 = OCV_SOC_PAIRS[i].soc;
float slope = (soc2 - soc1) / (ocv2 - ocv1); const float slope = (soc2 - soc1) / (ocv2 - ocv1);
float interpolated_soc = soc1 + slope * (ocv - ocv1); const float interpolated_soc = soc1 + slope * (ocv - ocv1);
return interpolated_soc; return interpolated_soc;
} }

View File

@ -19,15 +19,15 @@ typedef enum {
uint32_t count = 0; uint32_t count = 0;
bool main_led = false; bool main_led = false;
LedColor led_1 = (LedColor) {.red = 0, .green = 0, .blue = 0}; auto led_1 = (LedColor) {.red = 0, .green = 0, .blue = 0};
LedColor led_2 = (LedColor) {.red = 0, .green = 0, .blue = 0}; auto led_2 = (LedColor) {.red = 0, .green = 0, .blue = 0};
#define ITER_COUNT 20 #define ITER_COUNT 20
#define INTERN_ERROR_COUNT 7500 #define INTERN_ERROR_COUNT 7500
static void set_led_color_hw(LedColor color) { static void set_led_color_hw(LedColor color) {
GPIO_PinState red = color.red ? GPIO_PIN_RESET : GPIO_PIN_SET; const GPIO_PinState red = color.red ? GPIO_PIN_RESET : GPIO_PIN_SET;
GPIO_PinState green = color.green ? GPIO_PIN_RESET : GPIO_PIN_SET; const GPIO_PinState green = color.green ? GPIO_PIN_RESET : GPIO_PIN_SET;
GPIO_PinState blue = color.blue ? GPIO_PIN_RESET : GPIO_PIN_SET; const GPIO_PinState blue = color.blue ? GPIO_PIN_RESET : GPIO_PIN_SET;
HAL_GPIO_WritePin(STATUS_LED_R_GPIO_Port, STATUS_LED_R_Pin, red); HAL_GPIO_WritePin(STATUS_LED_R_GPIO_Port, STATUS_LED_R_Pin, red);
HAL_GPIO_WritePin(STATUS_LED_G_GPIO_Port, STATUS_LED_G_Pin, green); HAL_GPIO_WritePin(STATUS_LED_G_GPIO_Port, STATUS_LED_G_Pin, green);

View File

@ -27,7 +27,7 @@ void ts_sm_update() {
ts_state.current_state = TS_ERROR; ts_state.current_state = TS_ERROR;
} }
auto old_state = ts_state.current_state; const auto old_state = ts_state.current_state;
switch (ts_state.current_state) { switch (ts_state.current_state) {
case TS_INACTIVE: case TS_INACTIVE:
@ -106,7 +106,7 @@ TSState ts_sm_update_precharge() {
} }
if (shunt_data.voltage_veh > MIN_VEHICLE_SIDE_VOLTAGE && if (shunt_data.voltage_veh > MIN_VEHICLE_SIDE_VOLTAGE &&
shunt_data.voltage_veh > 0.95 * shunt_data.voltage_bat) { shunt_data.voltage_veh > 0.95 * shunt_data.voltage_bat) {
uint32_t now = HAL_GetTick(); const uint32_t now = HAL_GetTick();
if (precharge_95_reached_timestamp == 0) { if (precharge_95_reached_timestamp == 0) {
precharge_95_reached_timestamp = now; precharge_95_reached_timestamp = now;
} else if ((now - precharge_95_reached_timestamp) >= } else if ((now - precharge_95_reached_timestamp) >=
@ -133,7 +133,7 @@ TSState ts_sm_update_discharge() {
TSState ts_sm_update_error() { TSState ts_sm_update_error() {
static uint32_t no_error_since = 0; static uint32_t no_error_since = 0;
if (ts_state.error_source == 0) { if (ts_state.error_source == 0) {
uint32_t now = HAL_GetTick(); const uint32_t now = HAL_GetTick();
if (no_error_since == 0) { if (no_error_since == 0) {
no_error_since = now; no_error_since = now;
} else if (now - no_error_since > NO_ERROR_TIME) { } else if (now - no_error_since > NO_ERROR_TIME) {
@ -205,7 +205,7 @@ void ts_sm_set_relay_position(Relay relay, int closed) {
static int pos_closed = 0; static int pos_closed = 0;
static int pre_closed = 0; static int pre_closed = 0;
GPIO_PinState state = closed ? GPIO_PIN_SET : GPIO_PIN_RESET; const GPIO_PinState state = closed ? GPIO_PIN_SET : GPIO_PIN_RESET;
switch (relay) { switch (relay) {
case RELAY_NEG: case RELAY_NEG:
ts_sm_check_close_wait(&neg_closed, closed); ts_sm_check_close_wait(&neg_closed, closed);
@ -227,7 +227,7 @@ void ts_sm_check_close_wait(int *is_closed, int should_close) {
if (should_close != *is_closed) { if (should_close != *is_closed) {
*is_closed = should_close; *is_closed = should_close;
if (should_close) { if (should_close) {
uint32_t dt = HAL_GetTick() - last_close_timestamp; const uint32_t dt = HAL_GetTick() - last_close_timestamp;
if (dt < RELAY_CLOSE_WAIT) { if (dt < RELAY_CLOSE_WAIT) {
HAL_Delay(RELAY_CLOSE_WAIT - dt); HAL_Delay(RELAY_CLOSE_WAIT - dt);
} }