ams-master-23/Core/Src/slave_monitoring.c

133 lines
4.2 KiB
C
Raw Normal View History

2023-03-12 21:06:23 +01:00
#include "slave_monitoring.h"
2023-04-30 00:57:42 +02:00
#include "can.h"
2023-03-12 21:15:32 +01:00
#include "main.h"
2023-03-12 21:06:23 +01:00
#include "ts_state_machine.h"
2023-03-18 20:24:07 +01:00
#include "can-halal.h"
2023-03-15 18:07:38 +01:00
2024-04-23 17:37:17 +02:00
#include "stm32h7xx_hal.h"
2023-03-12 21:15:32 +01:00
2023-03-12 21:06:23 +01:00
#include <stdint.h>
#include <string.h>
SlaveHandle slaves[N_SLAVES];
uint16_t min_voltage;
int16_t max_temp;
static uint8_t slave_id_to_index[128] = {0xFF};
static size_t get_slave_index(uint8_t slave_id) {
// Slave IDs are 7-bit, so we can use a 128-element array to map them to
// indices. 0xFF is used to mark unseen slave IDs, since the highest index we
// could need is N_SLAVES - 1 (i.e. 5).
static size_t next_slave_index = 0;
if (slave_id_to_index[slave_id] == 0xFF) {
if (next_slave_index >= N_SLAVES) {
// We've seen more than N_SLAVES slave IDs, this shouldn't happen.
Error_Handler();
}
slave_id_to_index[slave_id] = next_slave_index;
slaves[next_slave_index].id = slave_id;
next_slave_index++;
}
return slave_id_to_index[slave_id];
}
2023-03-12 21:06:23 +01:00
void slaves_init() {
memset(slave_id_to_index, 0xFF, sizeof(slave_id_to_index));
2023-03-12 21:06:23 +01:00
for (int i = 0; i < N_SLAVES; i++) {
slaves[i].id = 0xFF;
2023-03-12 21:06:23 +01:00
slaves[i].error.kind = SLAVE_ERR_NONE;
slaves[i].last_message = 0;
2023-04-15 22:01:22 +02:00
slaves[i].min_voltage = 0;
slaves[i].max_voltage = 0;
slaves[i].max_temp = 0;
2023-03-12 21:06:23 +01:00
}
2023-03-12 21:15:32 +01:00
HAL_GPIO_WritePin(SLAVE_POWER_0_GPIO_Port, SLAVE_POWER_0_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SLAVE_POWER_1_GPIO_Port, SLAVE_POWER_1_Pin, GPIO_PIN_SET);
2023-03-12 21:15:32 +01:00
HAL_GPIO_WritePin(SLAVE_POWER_DSEL_GPIO_Port, SLAVE_POWER_DSEL_Pin,
GPIO_PIN_RESET);
// TODO: Enable & read out current
HAL_GPIO_WritePin(SLAVE_POWER_DEN_GPIO_Port, SLAVE_POWER_DEN_Pin,
GPIO_PIN_RESET);
2023-03-12 21:06:23 +01:00
}
void slaves_check() {
int any_slave_error = 0;
TSErrorKind slave_error = TS_ERRORKIND_NONE;
2023-03-12 21:06:23 +01:00
uint32_t now = HAL_GetTick();
uint16_t min_voltage_new = 0xFFFF;
int16_t max_temp_new = 0xFFFF;
2023-03-12 21:06:23 +01:00
for (int i = 0; i < N_SLAVES; i++) {
2023-04-30 00:57:42 +02:00
// Update timeout errors
2023-03-12 21:06:23 +01:00
if (now - slaves[i].last_message >= SLAVE_TIMEOUT) {
// Don't overwrite a different error kind
if (slaves[i].error.kind == SLAVE_ERR_NONE) {
slaves[i].error.kind = SLAVE_ERR_TIMEOUT;
2023-04-30 00:57:42 +02:00
can_send_error(TS_ERRORKIND_SLAVE_TIMEOUT, slaves[i].id);
2023-03-12 21:06:23 +01:00
}
} else if (slaves[i].error.kind == SLAVE_ERR_TIMEOUT) {
slaves[i].error.kind = SLAVE_ERR_NONE;
}
2023-04-30 00:57:42 +02:00
// Determine min/max
2023-04-15 22:01:22 +02:00
if (slaves[i].min_voltage < min_voltage_new) {
min_voltage_new = slaves[i].min_voltage;
2023-03-12 21:06:23 +01:00
}
2023-04-15 22:01:22 +02:00
if (slaves[i].max_temp > max_temp_new) {
max_temp_new = slaves[i].max_temp;
2023-03-12 21:06:23 +01:00
}
if (slaves[i].error.kind != SLAVE_ERR_NONE) {
any_slave_error = 1;
slave_error = (slaves[i].error.kind == SLAVE_ERR_TIMEOUT) ? TS_ERRORKIND_SLAVE_TIMEOUT : TS_ERRORKIND_SLAVE_PANIC;
2023-03-12 21:06:23 +01:00
}
}
min_voltage = min_voltage_new;
max_temp = max_temp_new;
ts_sm_set_error_source(TS_ERROR_SOURCE_SLAVES, slave_error, any_slave_error);
2023-03-12 21:06:23 +01:00
}
2023-03-15 18:07:38 +01:00
void slaves_handle_panic(const uint8_t *data) {
2023-07-03 14:20:24 +02:00
const uint8_t **ptr = &data;
uint8_t slave_id = ftcan_unmarshal_unsigned(ptr, 1);
uint8_t idx = get_slave_index(slave_id);
2023-07-03 14:20:24 +02:00
uint8_t error_kind = ftcan_unmarshal_unsigned(ptr, 1);
2023-03-15 18:07:38 +01:00
switch (error_kind) {
case SLAVE_PANIC_OT ... SLAVE_PANIC_INTERNAL_BMS_FAULT:
2024-04-01 20:43:36 +02:00
slaves[idx].error.kind = error_kind + 2; //SlaveErrorKind on master is 2 higher than on slave (errors.h in slave firmware)
break;
default:
slaves[idx].error.kind = SLAVE_ERR_UNKNOWN;
break;
2023-03-12 21:06:23 +01:00
}
slaves[idx].error.data = ftcan_unmarshal_unsigned(&data, 4);
slaves[idx].last_message = HAL_GetTick();
ts_sm_set_error_source(TS_ERROR_SOURCE_SLAVES, TS_ERRORKIND_SLAVE_PANIC, 1);
2023-04-30 00:57:42 +02:00
can_send_error(TS_ERRORKIND_SLAVE_PANIC, slave_id);
2023-03-12 21:06:23 +01:00
}
2023-04-15 22:01:22 +02:00
void slaves_handle_status(const uint8_t *data) {
uint8_t slave_id = data[0] & 0x7F;
uint8_t idx = get_slave_index(slave_id);
2023-04-15 22:01:22 +02:00
int error = data[0] & 0x80;
2023-07-12 19:34:30 +02:00
if (!error) {
slaves[idx].error.kind = SLAVE_ERR_NONE;
2023-04-15 22:01:22 +02:00
}
slaves[idx].soc = data[1];
2023-04-15 22:01:22 +02:00
const uint8_t *ptr = &data[2];
slaves[idx].min_voltage = ftcan_unmarshal_unsigned(&ptr, 2);
slaves[idx].max_voltage = ftcan_unmarshal_unsigned(&ptr, 2);
slaves[idx].max_temp = ftcan_unmarshal_unsigned(&ptr, 2);
slaves[idx].last_message = HAL_GetTick();
2023-04-15 22:01:22 +02:00
}
2023-03-15 18:07:38 +01:00
void slaves_handle_log(const uint8_t *data) {
2023-03-12 21:06:23 +01:00
// TODO
}