Compare commits
2 Commits
3f8e1290fa
...
468ba1d7e7
Author | SHA1 | Date | |
---|---|---|---|
468ba1d7e7 | |||
f910f899a4 |
@ -14,7 +14,7 @@
|
|||||||
#define VREF 3000.0f // 3V
|
#define VREF 3000.0f // 3V
|
||||||
#define TEMP_CONV 100.0f // 655.35°C max
|
#define TEMP_CONV 100.0f // 655.35°C max
|
||||||
#define CELSIUS_TO_KELVIN 273.15f
|
#define CELSIUS_TO_KELVIN 273.15f
|
||||||
#define CELSIUS_TO_KELVIN_SCALED CELSIUS_TO_KELVIN * TEMP_CONV
|
#define CELSIUS_TO_KELVIN_SCALED (CELSIUS_TO_KELVIN * TEMP_CONV)
|
||||||
|
|
||||||
// More efficient (?) calc using:
|
// More efficient (?) calc using:
|
||||||
// R_T = R_Pullup / (V_REF / ADC - 1)
|
// R_T = R_Pullup / (V_REF / ADC - 1)
|
||||||
@ -24,7 +24,8 @@
|
|||||||
[[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) {
|
||||||
const 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?
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "stm32h7xx_hal.h"
|
#include "stm32h7xx_hal.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Minimum vehicle side voltage to exit precharge
|
// Minimum vehicle side voltage to exit precharge
|
||||||
#define MIN_VEHICLE_SIDE_VOLTAGE 150000 // mV
|
#define MIN_VEHICLE_SIDE_VOLTAGE 150000 // mV
|
||||||
@ -22,15 +22,7 @@
|
|||||||
// Time to wait between closing relays
|
// Time to wait between closing relays
|
||||||
#define RELAY_CLOSE_WAIT 10 // ms
|
#define RELAY_CLOSE_WAIT 10 // ms
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { TS_INACTIVE, TS_ACTIVE, TS_PRECHARGE, TS_DISCHARGE, TS_ERROR, TS_CHARGING_CHECK, TS_CHARGING } TSState;
|
||||||
TS_INACTIVE,
|
|
||||||
TS_ACTIVE,
|
|
||||||
TS_PRECHARGE,
|
|
||||||
TS_DISCHARGE,
|
|
||||||
TS_ERROR,
|
|
||||||
TS_CHARGING_CHECK,
|
|
||||||
TS_CHARGING
|
|
||||||
} TSState;
|
|
||||||
|
|
||||||
static inline const char *TSStateToString(TSState state) {
|
static inline const char *TSStateToString(TSState state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -62,10 +54,7 @@ typedef enum {
|
|||||||
TS_ERRORKIND_SHUNT_OVERTEMP = 0x05
|
TS_ERRORKIND_SHUNT_OVERTEMP = 0x05
|
||||||
} TSErrorKind;
|
} TSErrorKind;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { TS_ERROR_SOURCE_SHUNT = (1 << 0), TS_ERROR_SOURCE_SLAVES = (1 << 1) } TSErrorSource;
|
||||||
TS_ERROR_SOURCE_SHUNT = (1 << 0),
|
|
||||||
TS_ERROR_SOURCE_SLAVES = (1 << 1)
|
|
||||||
} TSErrorSource;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TSState current_state;
|
TSState current_state;
|
||||||
|
@ -70,7 +70,6 @@
|
|||||||
|
|
||||||
#define DIAGN 0x0715 // Diagnos MUX and Poll Status
|
#define DIAGN 0x0715 // Diagnos MUX and Poll Status
|
||||||
|
|
||||||
|
|
||||||
#define WRCOMM 0x0721 // Write COMM Register Group
|
#define WRCOMM 0x0721 // Write COMM Register Group
|
||||||
#define RDCOMM 0x0722 // Read COMM Register Group
|
#define RDCOMM 0x0722 // Read COMM Register Group
|
||||||
#define STCOMM 0x0723 // Start I2C/SPI Communication
|
#define STCOMM 0x0723 // Start I2C/SPI Communication
|
||||||
@ -91,8 +90,6 @@
|
|||||||
|
|
||||||
#define RDSID 0x002C // Read Serial ID
|
#define RDSID 0x002C // Read Serial ID
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* GPIO Selection for ADC Converion
|
/* GPIO Selection for ADC Converion
|
||||||
* 000: GPIO1 to 5, 2nd Reference, GPIO 6 to 9
|
* 000: GPIO1 to 5, 2nd Reference, GPIO 6 to 9
|
||||||
* 001: GPIO1 and GPIO6
|
* 001: GPIO1 and GPIO6
|
||||||
|
@ -19,8 +19,7 @@ typedef enum : uint16_t {
|
|||||||
NUM_ERROR_KINDS
|
NUM_ERROR_KINDS
|
||||||
} ADBMS_Status;
|
} ADBMS_Status;
|
||||||
|
|
||||||
static const char* ADBMS_Status_Names[NUM_ERROR_KINDS] = {
|
static const char *ADBMS_Status_Names[NUM_ERROR_KINDS] = {"ADBMS_NO_ERROR",
|
||||||
"ADBMS_NO_ERROR",
|
|
||||||
"ADBMS_OVERTEMP",
|
"ADBMS_OVERTEMP",
|
||||||
"ADBMS_UNDERTEMP",
|
"ADBMS_UNDERTEMP",
|
||||||
"ADBMS_OVERVOLT",
|
"ADBMS_OVERVOLT",
|
||||||
@ -29,8 +28,7 @@ static const char* ADBMS_Status_Names[NUM_ERROR_KINDS] = {
|
|||||||
"ADBMS_INTERNAL_BMS_TIMEOUT",
|
"ADBMS_INTERNAL_BMS_TIMEOUT",
|
||||||
"ADBMS_INTERNAL_BMS_CHECKSUM_FAIL",
|
"ADBMS_INTERNAL_BMS_CHECKSUM_FAIL",
|
||||||
"ADBMS_INTERNAL_BMS_OVERTEMP",
|
"ADBMS_INTERNAL_BMS_OVERTEMP",
|
||||||
"ADBMS_INTERNAL_BMS_FAULT"
|
"ADBMS_INTERNAL_BMS_FAULT"};
|
||||||
};
|
|
||||||
|
|
||||||
static inline const char* ADBMS_Status_ToString(ADBMS_Status status) {
|
static inline const char* ADBMS_Status_ToString(ADBMS_Status status) {
|
||||||
return (status < NUM_ERROR_KINDS) ? ADBMS_Status_Names[status] : "UNKNOWN";
|
return (status < NUM_ERROR_KINDS) ? ADBMS_Status_Names[status] : "UNKNOWN";
|
||||||
|
@ -13,6 +13,16 @@ typedef enum {
|
|||||||
ADBMS_TIMEOUT,
|
ADBMS_TIMEOUT,
|
||||||
} ADBMS_Internal_Status;
|
} ADBMS_Internal_Status;
|
||||||
|
|
||||||
|
#define CRITICAL_SECTION_VAR(counter) bool primask_##counter = (__get_PRIMASK() == 0)
|
||||||
|
#define CRITICAL_SECTION_ENTER(counter) do { __disable_irq(); } while(0)
|
||||||
|
#define CRITICAL_SECTION_EXIT(counter) ({do { if (primask_##counter) __enable_irq(); } while(0);})
|
||||||
|
|
||||||
|
#define CRITICAL_SECTION() \
|
||||||
|
CRITICAL_SECTION_VAR(__COUNTER__); \
|
||||||
|
asm volatile ("dmb"); \
|
||||||
|
CRITICAL_SECTION_ENTER(__COUNTER__); \
|
||||||
|
for(int _cs_flag_##__COUNTER__ = 1; _cs_flag_##__COUNTER__; _cs_flag_##__COUNTER__ = 0, CRITICAL_SECTION_EXIT(__COUNTER__))
|
||||||
|
|
||||||
[[maybe_unused, gnu::always_inline]]
|
[[maybe_unused, gnu::always_inline]]
|
||||||
static inline void mcuAdbmsCSLow() {
|
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);
|
||||||
@ -29,20 +39,32 @@ static inline void mcuAdbmsCSHigh() {
|
|||||||
|
|
||||||
[[maybe_unused, gnu::always_inline, gnu::access(read_only, 2, 3), gnu::nonnull(1)]]
|
[[maybe_unused, gnu::always_inline, gnu::access(read_only, 2, 3), gnu::nonnull(1)]]
|
||||||
static inline ADBMS_Internal_Status mcuSPITransmit(USER_PTR_TYPE user_ptr, const uint8_t* buffer, uint8_t buffersize, uint32_t timeout) {
|
static inline ADBMS_Internal_Status mcuSPITransmit(USER_PTR_TYPE user_ptr, const uint8_t* buffer, uint8_t buffersize, uint32_t timeout) {
|
||||||
|
ADBMS_Internal_Status adbms_status;
|
||||||
|
CRITICAL_SECTION() {
|
||||||
const HAL_StatusTypeDef status = HAL_SPI_Transmit(user_ptr, buffer, buffersize, timeout);
|
const HAL_StatusTypeDef status = HAL_SPI_Transmit(user_ptr, buffer, buffersize, timeout);
|
||||||
return (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR;
|
adbms_status = (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR;
|
||||||
|
}
|
||||||
|
return adbms_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused, gnu::always_inline, gnu::access(read_write, 2, 3), gnu::nonnull(1)]]
|
[[maybe_unused, gnu::always_inline, gnu::access(read_write, 2, 3), gnu::nonnull(1)]]
|
||||||
static inline ADBMS_Internal_Status mcuSPIReceive(USER_PTR_TYPE user_ptr, uint8_t* buffer, uint8_t buffersize, uint32_t timeout) {
|
static inline ADBMS_Internal_Status mcuSPIReceive(USER_PTR_TYPE user_ptr, uint8_t* buffer, uint8_t buffersize, uint32_t timeout) {
|
||||||
|
ADBMS_Internal_Status adbms_status;
|
||||||
|
CRITICAL_SECTION() {
|
||||||
const HAL_StatusTypeDef status = HAL_SPI_Receive(user_ptr, buffer, buffersize, timeout);
|
const HAL_StatusTypeDef status = HAL_SPI_Receive(user_ptr, buffer, buffersize, timeout);
|
||||||
return (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR;
|
adbms_status = (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR;
|
||||||
|
}
|
||||||
|
return adbms_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused, gnu::always_inline, gnu::access(read_write, 2, 4), gnu::access(read_only, 3, 4), gnu::nonnull(1, 2)]]
|
[[maybe_unused, gnu::always_inline, gnu::access(read_write, 2, 4), gnu::access(read_only, 3, 4), gnu::nonnull(1, 2)]]
|
||||||
static inline ADBMS_Internal_Status mcuSPITransmitReceive(USER_PTR_TYPE user_ptr, uint8_t* rxbuffer, const uint8_t* txbuffer, uint8_t buffersize, uint32_t timeout) {
|
static inline ADBMS_Internal_Status mcuSPITransmitReceive(USER_PTR_TYPE user_ptr, uint8_t* rxbuffer, const uint8_t* txbuffer, uint8_t buffersize, uint32_t timeout) {
|
||||||
|
ADBMS_Internal_Status adbms_status;
|
||||||
|
CRITICAL_SECTION() {
|
||||||
const HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(user_ptr, txbuffer, rxbuffer, buffersize, timeout);
|
const HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(user_ptr, txbuffer, rxbuffer, buffersize, timeout);
|
||||||
return (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR;
|
adbms_status = (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR;
|
||||||
|
}
|
||||||
|
return adbms_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay by `delay` milliseconds
|
// Delay by `delay` milliseconds
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef ADBMS_LL_DRIVER_H_
|
#ifndef ADBMS_LL_DRIVER_H_
|
||||||
#define ADBMS_LL_DRIVER_H_
|
#define ADBMS_LL_DRIVER_H_
|
||||||
|
|
||||||
#include "config_ADBMS6830.h"
|
|
||||||
#include "ADBMS_Intern.h"
|
#include "ADBMS_Intern.h"
|
||||||
|
#include "config_ADBMS6830.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@ -21,8 +21,7 @@ static inline ADBMS_Internal_Status __writeCMD(uint16_t command, uint8_t * args,
|
|||||||
return ___writeCMD(command, args, arglen);
|
return ___writeCMD(command, args, arglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define writeCMD(command, args, arglen) \
|
#define writeCMD(command, args, arglen) __writeCMD(command, args, arglen, CMD_BUFFER_SIZE(arglen))
|
||||||
__writeCMD(command, args, arglen, CMD_BUFFER_SIZE(arglen))
|
|
||||||
|
|
||||||
ADBMS_Internal_Status ___readCMD(uint16_t command, uint8_t *buffer, size_t arglen);
|
ADBMS_Internal_Status ___readCMD(uint16_t command, uint8_t *buffer, size_t arglen);
|
||||||
|
|
||||||
@ -31,13 +30,12 @@ static inline ADBMS_Internal_Status __readCMD(uint16_t command, uint8_t * buffer
|
|||||||
return ___readCMD(command, buffer, arglen);
|
return ___readCMD(command, buffer, arglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define readCMD(command, buffer, buflen) \
|
#define readCMD(command, buffer, buflen) __readCMD(command, buffer, buflen, CMD_BUFFER_SIZE(buflen))
|
||||||
__readCMD(command, buffer, buflen, CMD_BUFFER_SIZE(buflen))
|
|
||||||
|
|
||||||
ADBMS_Internal_Status __pollCMD(uint16_t command, uint8_t waitTime);
|
ADBMS_Internal_Status __pollCMD(uint16_t command, uint8_t waitTime);
|
||||||
|
|
||||||
#define pollCMD(command) \
|
// poll is only valid after 2 * N_BMS clock cycles, +1 for safety, see datasheet page 55
|
||||||
__pollCMD(command, (N_BMS * 2) + 1) //poll is only valid after 2 * N_BMS clock cycles, +1 for safety, see datasheet page 55
|
#define pollCMD(command) __pollCMD(command, (N_BMS * 2) + 1)
|
||||||
|
|
||||||
void initSPI(USER_PTR_TYPE ptr);
|
void initSPI(USER_PTR_TYPE ptr);
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "ADBMS_Abstraction.h"
|
#include "ADBMS_Abstraction.h"
|
||||||
#include "ADBMS_CMD_Defines.h"
|
#include "ADBMS_CMD_Defines.h"
|
||||||
|
#include "ADBMS_Intern.h"
|
||||||
#include "ADBMS_LL_Driver.h"
|
#include "ADBMS_LL_Driver.h"
|
||||||
#include "config_ADBMS6830.h"
|
#include "config_ADBMS6830.h"
|
||||||
#include "ADBMS_Intern.h"
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
@ -12,9 +12,10 @@ static const char* const ADBMS_Statuses[] = {"ADBMS_OK", "ADBMS_ERROR", "ADBMS_B
|
|||||||
do { \
|
do { \
|
||||||
ADBMS_Internal_Status status = x; \
|
ADBMS_Internal_Status status = x; \
|
||||||
if (status != 0) { \
|
if (status != 0) { \
|
||||||
debug_log(ADBMS_LOG_LEVEL_ERROR, "in %s:%d@%s: %s failed with status %d (%s)", __FILE_NAME__, __LINE__, __func__,\
|
debug_log(ADBMS_LOG_LEVEL_ERROR, "in %s:%d@%s: %s failed with status %d (%s)", __FILE_NAME__, __LINE__, \
|
||||||
#x, status, \
|
__func__, #x, status, \
|
||||||
(status < (sizeof(ADBMS_Statuses) / sizeof(ADBMS_Statuses[0]))) ? ADBMS_Statuses[status] : "Unknown"); \
|
(status < (sizeof(ADBMS_Statuses) / sizeof(ADBMS_Statuses[0]))) ? ADBMS_Statuses[status] \
|
||||||
|
: "Unknown"); \
|
||||||
return status; \
|
return status; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#include "ADBMS_Abstraction.h"
|
#include "ADBMS_Abstraction.h"
|
||||||
#include "ADBMS_Driver.h"
|
#include "ADBMS_Driver.h"
|
||||||
#include "config_ADBMS6830.h"
|
|
||||||
#include "ADBMS_Intern.h"
|
#include "ADBMS_Intern.h"
|
||||||
|
#include "config_ADBMS6830.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
BMS_Chip bms_data[N_BMS] = {};
|
BMS_Chip bms_data[N_BMS] = {};
|
||||||
|
|
||||||
uint8_t packetChecksumFails = 0;
|
uint8_t packetChecksumFails = 0;
|
||||||
@ -24,8 +23,8 @@ struct pollingTimes pollingTimes = {0, 0};
|
|||||||
static constexpr ADBMS_DetailedStatus NO_ERROR = {ADBMS_NO_ERROR};
|
static constexpr ADBMS_DetailedStatus NO_ERROR = {ADBMS_NO_ERROR};
|
||||||
|
|
||||||
ADBMS_DetailedStatus AMS_Init(USER_PTR_TYPE ptr) {
|
ADBMS_DetailedStatus AMS_Init(USER_PTR_TYPE ptr) {
|
||||||
debug_log(ADBMS_LOG_LEVEL_INFO, "ADBMS6830B HAL - configured for %d controllers and %d cells per controller...", N_BMS,
|
debug_log(ADBMS_LOG_LEVEL_INFO, "ADBMS6830B HAL - configured for %d controllers and %d cells per controller...",
|
||||||
N_CELLS);
|
N_BMS, N_CELLS);
|
||||||
if (initAMS(ptr) != ADBMS_OK) {
|
if (initAMS(ptr) != ADBMS_OK) {
|
||||||
debug_log(ADBMS_LOG_LEVEL_ERROR, "ADBMS6830B HAL - initialization failed");
|
debug_log(ADBMS_LOG_LEVEL_ERROR, "ADBMS6830B HAL - initialization failed");
|
||||||
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT, -1};
|
return (ADBMS_DetailedStatus){ADBMS_INTERNAL_BMS_FAULT, -1};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "ADBMS_LL_Driver.h"
|
#include "ADBMS_LL_Driver.h"
|
||||||
#include "config_ADBMS6830.h"
|
|
||||||
#include "ADBMS_Intern.h"
|
#include "ADBMS_Intern.h"
|
||||||
|
#include "config_ADBMS6830.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
@ -147,7 +147,6 @@ static void print_spi_details() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ADBMS_Internal_Status ___writeCMD(uint16_t command, uint8_t * args, size_t arglen) {
|
ADBMS_Internal_Status ___writeCMD(uint16_t command, uint8_t * args, size_t arglen) {
|
||||||
ADBMS_Internal_Status ret;
|
ADBMS_Internal_Status ret;
|
||||||
if (arglen > 0) {
|
if (arglen > 0) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "isotp_log_backend.h"
|
#include "isotp_log_backend.h"
|
||||||
#include "log.h"
|
|
||||||
#include "isotp.h"
|
#include "isotp.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#ifndef __LOG_H
|
#ifndef __LOG_H
|
||||||
#define __LOG_H
|
#define __LOG_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Configuration */
|
/* Configuration */
|
||||||
#define MAX_MESSAGE_LENGTH 384
|
#define MAX_MESSAGE_LENGTH 384
|
||||||
|
@ -85,7 +85,8 @@ static void swo_backend_write(const log_message_t* message) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Assuming message->message is ensured to be non-NULL by the logger core if message itself is not NULL.
|
// Assuming message->message is ensured to be non-NULL by the logger core if message itself is not NULL.
|
||||||
// Or, if message->message can be NULL, the caller of swo_util_puts should handle it or swo_util_puts should be robust to it.
|
// Or, if message->message can be NULL, the caller of swo_util_puts should handle it or swo_util_puts should be
|
||||||
|
// robust to it.
|
||||||
|
|
||||||
#if USE_MULTIPLE_CHANNELS
|
#if USE_MULTIPLE_CHANNELS
|
||||||
swo_util_puts(message->message, message->level);
|
swo_util_puts(message->message, message->level);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "swo_util.h"
|
#include "swo_util.h"
|
||||||
#include "stm32h7xx.h" // For ITM registers, __NOP() and ITM_TCR_ITMENA_Msk, ITM_TER_TER_Msk
|
#include "stm32h7xx.h" // For ITM registers, __NOP() and ITM_TCR_ITMENA_Msk, ITM_TER_TER_Msk
|
||||||
#include <stdint.h> // For uint32_t
|
|
||||||
#include <stddef.h> // For NULL
|
#include <stddef.h> // For NULL
|
||||||
|
#include <stdint.h> // For uint32_t
|
||||||
|
|
||||||
// Core function to send a character to a specific SWO ITM port
|
// Core function to send a character to a specific SWO ITM port
|
||||||
// Adapted from ITM_SendChar() in the CMSIS-Core
|
// Adapted from ITM_SendChar() in the CMSIS-Core
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
#include "NTC.h"
|
#include "NTC.h"
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
#include "config_ADBMS6830.h"
|
#include "config_ADBMS6830.h"
|
||||||
#include "ts_state_machine.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "ts_state_machine.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define SWO_LOG_PREFIX "[BATTERY] "
|
#define SWO_LOG_PREFIX "[BATTERY] "
|
||||||
#include "swo_log.h"
|
#include "swo_log.h"
|
||||||
@ -73,8 +73,7 @@ HAL_StatusTypeDef battery_init(SPI_HandleTypeDef *hspi) {
|
|||||||
HAL_StatusTypeDef battery_update() {
|
HAL_StatusTypeDef battery_update() {
|
||||||
auto const ret = AMS_Idle_Loop();
|
auto const 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));
|
|
||||||
if (ret.bms_id != -1) {
|
if (ret.bms_id != -1) {
|
||||||
debug_log_cont(LOG_LEVEL_ERROR, " (on BMS ID: %hd)", ret.bms_id);
|
debug_log_cont(LOG_LEVEL_ERROR, " (on BMS ID: %hd)", ret.bms_id);
|
||||||
}
|
}
|
||||||
@ -82,12 +81,10 @@ 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";
|
||||||
const uint32_t voltage_flags = (ret.status == ADBMS_OVERVOLT) ?
|
const uint32_t voltage_flags = (ret.status == ADBMS_OVERVOLT) ? bms_data[ret.bms_id].overVoltage
|
||||||
bms_data[ret.bms_id].overVoltage :
|
: bms_data[ret.bms_id].underVoltage;
|
||||||
bms_data[ret.bms_id].underVoltage;
|
|
||||||
|
|
||||||
debug_log(LOG_LEVEL_ERROR, "Cell %s detected on module %d, affected cells: ",
|
debug_log(LOG_LEVEL_ERROR, "Cell %s detected on module %d, affected cells: ", error_type, ret.bms_id);
|
||||||
error_type, ret.bms_id);
|
|
||||||
|
|
||||||
for (size_t cell = 0; cell < N_CELLS; cell++) {
|
for (size_t cell = 0; cell < N_CELLS; cell++) {
|
||||||
if (voltage_flags & (1UL << cell)) {
|
if (voltage_flags & (1UL << cell)) {
|
||||||
@ -141,7 +138,6 @@ HAL_StatusTypeDef battery_update() {
|
|||||||
for (size_t j = 0; j < 10; j++) { // 10 GPIOs
|
for (size_t j = 0; j < 10; j++) { // 10 GPIOs
|
||||||
battery.module[i].cellTemps[j] = ntc_mv_to_celsius(bms_data[i].auxVoltages[j]);
|
battery.module[i].cellTemps[j] = ntc_mv_to_celsius(bms_data[i].auxVoltages[j]);
|
||||||
|
|
||||||
|
|
||||||
// For new battery struct
|
// For new battery struct
|
||||||
if (battery.module[i].cellTemps[j] > battery.pack.max_temp) {
|
if (battery.module[i].cellTemps[j] > battery.pack.max_temp) {
|
||||||
battery.pack.max_temp = battery.module[i].cellTemps[j];
|
battery.pack.max_temp = battery.module[i].cellTemps[j];
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#include "can.h"
|
#include "can.h"
|
||||||
|
|
||||||
#include "ADBMS_Driver.h"
|
#include "ADBMS_Driver.h"
|
||||||
|
#include "battery.h"
|
||||||
#include "imd_monitoring.h"
|
#include "imd_monitoring.h"
|
||||||
#include "isotp.h"
|
#include "isotp.h"
|
||||||
#include "isotp_user_defs.h"
|
|
||||||
#include "isotp_log_backend.h"
|
#include "isotp_log_backend.h"
|
||||||
|
#include "isotp_user_defs.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "shunt_monitoring.h"
|
#include "shunt_monitoring.h"
|
||||||
#include "battery.h"
|
|
||||||
#include "soc_estimation.h"
|
#include "soc_estimation.h"
|
||||||
#include "ts_state_machine.h"
|
#include "ts_state_machine.h"
|
||||||
|
|
||||||
@ -24,9 +24,7 @@ bool isotp_transmit(uint16_t id, const uint8_t *data, size_t datalen) {
|
|||||||
return ftcan_transmit(id, data, datalen) == HAL_OK;
|
return ftcan_transmit(id, data, datalen) == HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t isotp_get_time() {
|
uint32_t isotp_get_time() { return HAL_GetTick(); }
|
||||||
return HAL_GetTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
void can_init(FDCAN_HandleTypeDef *handle) {
|
void can_init(FDCAN_HandleTypeDef *handle) {
|
||||||
ftcan_init(handle);
|
ftcan_init(handle);
|
||||||
@ -62,9 +60,8 @@ HAL_StatusTypeDef can_send_status() {
|
|||||||
if (ret != HAL_OK) {
|
if (ret != HAL_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
data[0] = (sdc_closed_nodelay << 0) | (ts_error << 1) | (hv_active << 2) |
|
data[0] = (sdc_closed_nodelay << 0) | (ts_error << 1) | (hv_active << 2) | (neg_air_closed << 3) |
|
||||||
(neg_air_closed << 3) | (pos_air_closed << 4) |
|
(pos_air_closed << 4) | (precharge_closed << 5) | (pre_and_air_open << 6);
|
||||||
(precharge_closed << 5) | (pre_and_air_open << 6);
|
|
||||||
return ftcan_transmit(CAN_ID_AMS_SIGNALS, data, 1);
|
return ftcan_transmit(CAN_ID_AMS_SIGNALS, data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,28 +44,23 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *handle) {
|
|||||||
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
|
||||||
if (imd_data.freq > FREQ_NORMAL - FREQ_TOLERANCE &&
|
if (imd_data.freq > FREQ_NORMAL - FREQ_TOLERANCE && imd_data.freq < FREQ_NORMAL + FREQ_TOLERANCE) {
|
||||||
imd_data.freq < FREQ_NORMAL + FREQ_TOLERANCE) {
|
|
||||||
imd_data.state = IMD_STATE_NORMAL;
|
imd_data.state = IMD_STATE_NORMAL;
|
||||||
} else if (imd_data.freq > FREQ_UNDERVOLTAGE - FREQ_TOLERANCE &&
|
} else if (imd_data.freq > FREQ_UNDERVOLTAGE - FREQ_TOLERANCE &&
|
||||||
imd_data.freq < FREQ_UNDERVOLTAGE + FREQ_TOLERANCE) {
|
imd_data.freq < FREQ_UNDERVOLTAGE + FREQ_TOLERANCE) {
|
||||||
imd_data.state = IMD_STATE_UNDERVOLTAGE;
|
imd_data.state = IMD_STATE_UNDERVOLTAGE;
|
||||||
} else if (imd_data.freq > FREQ_SST - FREQ_TOLERANCE &&
|
} else if (imd_data.freq > FREQ_SST - FREQ_TOLERANCE && imd_data.freq < FREQ_SST + FREQ_TOLERANCE) {
|
||||||
imd_data.freq < FREQ_SST + FREQ_TOLERANCE) {
|
|
||||||
imd_data.state = IMD_STATE_SST;
|
imd_data.state = IMD_STATE_SST;
|
||||||
} else if (imd_data.freq > FREQ_DEV_ERROR - FREQ_TOLERANCE &&
|
} else if (imd_data.freq > FREQ_DEV_ERROR - FREQ_TOLERANCE && imd_data.freq < FREQ_DEV_ERROR + FREQ_TOLERANCE) {
|
||||||
imd_data.freq < FREQ_DEV_ERROR + FREQ_TOLERANCE) {
|
|
||||||
imd_data.state = IMD_STATE_DEV_ERROR;
|
imd_data.state = IMD_STATE_DEV_ERROR;
|
||||||
} else if (imd_data.freq > FREQ_GND_FAULT - FREQ_TOLERANCE &&
|
} else if (imd_data.freq > FREQ_GND_FAULT - FREQ_TOLERANCE && imd_data.freq < FREQ_GND_FAULT + FREQ_TOLERANCE) {
|
||||||
imd_data.freq < FREQ_GND_FAULT + FREQ_TOLERANCE) {
|
|
||||||
imd_data.state = IMD_STATE_GND_FAULT;
|
imd_data.state = IMD_STATE_GND_FAULT;
|
||||||
} else {
|
} else {
|
||||||
imd_data.state = IMD_STATE_UNKNOWN;
|
imd_data.state = IMD_STATE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate R_iso
|
// Calculate R_iso
|
||||||
if (imd_data.state == IMD_STATE_NORMAL ||
|
if (imd_data.state == IMD_STATE_NORMAL || imd_data.state == IMD_STATE_UNDERVOLTAGE) {
|
||||||
imd_data.state == IMD_STATE_UNDERVOLTAGE) {
|
|
||||||
if (imd_data.duty_cycle < RISO_MIN_DUTY_CYCLE) {
|
if (imd_data.duty_cycle < RISO_MIN_DUTY_CYCLE) {
|
||||||
imd_data.r_iso = RISO_MAX;
|
imd_data.r_iso = RISO_MAX;
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,8 +79,7 @@ void soc_update() {
|
|||||||
current_was_flowing = 0;
|
current_was_flowing = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now - last_current_time >= SOC_ESTIMATION_NO_CURRENT_TIME ||
|
if (now - last_current_time >= SOC_ESTIMATION_NO_CURRENT_TIME || last_current_time == 0) {
|
||||||
last_current_time == 0) {
|
|
||||||
// Assume we're measuring OCV if there's been no current for a while (or
|
// Assume we're measuring OCV if there's been no current for a while (or
|
||||||
// we've just turned on the battery).
|
// we've just turned on the battery).
|
||||||
battery.pack.soc = soc_for_ocv(battery.pack.min_voltage);
|
battery.pack.soc = soc_for_ocv(battery.pack.min_voltage);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user