mv-bms/Core/Src/AMS_HighLevel.c

187 lines
4.5 KiB
C
Executable File

/*
* AMS_HighLevel.c
*
* Created on: 20.07.2022
* Author: max
*/
#include "AMS_HighLevel.h"
Cell_Module module = {};
uint32_t balancedCells = 0;
bool balancingActive = false;
uint16_t amsuv = 0;
uint16_t amsov = 0;
uint8_t numberofCells = 13;
uint8_t numberofAux = 0;
uint8_t packetChecksumFails = 0;
#define MAX_PACKET_CHECKSUM_FAILS 5
uint8_t deviceSleeps = 0;
#define MAX_DEVICE_SLEEP 3 //TODO: change to correct value
#define MAX_CELL_VOLTAGE 4100 //change to 4200
#define MIN_CELL_VOLTAGE 3100 //change to 3000
amsState currentAMSState = AMSDEACTIVE;
amsState lastAMSState = AMSDEACTIVE;
struct pollingTimes {
uint32_t S_ADC_OW_CHECK;
uint32_t TMP1075;
};
struct pollingTimes pollingTimes = {0, 0};
void AMS_Init(SPI_HandleTypeDef* hspi) {
initAMS(hspi, numberofCells, numberofAux);
amsov = DEFAULT_OV;
amsuv = DEFAULT_UV;
pollingTimes = (struct pollingTimes) {HAL_GetTick(), HAL_GetTick()};
currentAMSState = AMSIDLE;
}
void AMS_Loop() {
// On Transition Functions called ones if the State Changed
if (currentAMSState != lastAMSState) {
switch (currentAMSState) {
case AMSIDLE:
break;
case AMSDEACTIVE:
break;
case AMSCHARGING:
break;
case AMSIDLEBALANCING:
break;
case AMSDISCHARGING:
break;
case AMSWARNING:
break;
case AMSERROR:
break;
}
lastAMSState = currentAMSState;
}
// Main Loops for different AMS States
switch (currentAMSState) {
case AMSIDLE:
AMS_Idle_Loop();
break;
case AMSDEACTIVE:
break;
case AMSCHARGING:
break;
case AMSIDLEBALANCING:
AMS_Idle_Loop();
break;
case AMSDISCHARGING:
break;
case AMSWARNING:
AMS_Warning_Loop();
break;
case AMSERROR:
break;
}
}
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);
if (module.status.SLEEP) {
deviceSleeps++;
if (deviceSleeps > MAX_DEVICE_SLEEP) {
error_data.data_kind = SEK_INTERNAL_BMS_TIMEOUT;
set_error_source(ERROR_SOURCE_INTERNAL);
} else {
amsReset();
}
}
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) {
error_data.data_kind = SEK_INTERNAL_BMS_FAULT;
set_error_source(ERROR_SOURCE_INTERNAL);
}
if (module.status.THSD) {
error_data.data_kind = SEK_INTERNAL_BMS_OVERTEMP;
set_error_source(ERROR_SOURCE_INTERNAL);
}
packetChecksumFails += amsCellMeasurement(&module);
packetChecksumFails += amsCheckUnderOverVoltage(&module);
if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) {
error_data.data_kind = SEK_INTERNAL_BMS_CHECKSUM_FAIL;
set_error_source(ERROR_SOURCE_INTERNAL);
}
int any_voltage_error = 0;
for (size_t i = 0; i < numberofCells; i++) {
if (module.cellVoltages[i] < MIN_CELL_VOLTAGE) {
any_voltage_error = 1;
error_data.data_kind = SEK_UNDERVOLT;
error_data.data[0] = i;
uint8_t* ptr = &error_data.data[1];
ptr = ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2);
} else if (module.cellVoltages[i] > MAX_CELL_VOLTAGE) {
any_voltage_error = 1;
error_data.data_kind = SEK_OVERVOLT;
error_data.data[0] = i;
uint8_t* ptr = &error_data.data[1];
ptr = ftcan_marshal_unsigned(ptr, module.cellVoltages[i], 2);
}
}
if (module.internalDieTemp > 28000) { //TODO: change to correct value
error_data.data_kind = SEK_INTERNAL_BMS_OVERTEMP;
uint8_t* ptr = &error_data.data[0];
ptr = ftcan_marshal_unsigned(ptr, module.internalDieTemp, 2);
set_error_source(ERROR_SOURCE_INTERNAL);
} else {
clear_error_source(ERROR_SOURCE_INTERNAL);
}
if (any_voltage_error) {
set_error_source(ERROR_SOURCE_VOLTAGES);
} else {
clear_error_source(ERROR_SOURCE_VOLTAGES);
}
mcuDelay(10);
if ((module.overVoltage | module.underVoltage)) {
}
return 0;
}
uint8_t AMS_Warning_Loop() { return 0; }
uint8_t AMS_Error_Loop() { return 0; }
uint8_t AMS_Charging_Loop() { return 0; }
uint8_t AMS_Discharging_Loop() { return 0; }
uint8_t AMS_Balancing_Loop() {
//TODO: implement
return 0;
}