BMS carrier is the board which is responsible for monitoring and managing the main battery pack. It interfaces with the AFE (analog front end) board and the Current Sense board to get readings from the main pack.
Other Resources:
FWXIV BMS Carrier notes
Components
Current Sense - connected via I2C, and provides current readings and cell temperature,
AFEs - 3 AFE boards, daisy-chained over iso-spi. These provide per-cell-unit voltage readings and Ambient temperature readings, as well as performing load balancing
Relays + killswitch monitoring - Positive and negative relays must both be closed for the battery to be connected to the rest of the car. Killswitch monitor reads state of manual killswitch to batteries
HV Neg relay
HV Pos Relay
HV Solar Relay
Fans - Used to provide cooling to batteries. Controlled via PWM and monitored for fault
Fault Conditions
These are all fault conditions which will trigger a BPS fault. They are split into Minor, in which the issue is likely to not be dangerous and the driver can take time coming to a stop, and Major in which the driver should exit the car as quickly as possible due to dangerous conditions or the potential for thermal runaway.
Note: Cell refers to individual input AFE measurements, which in reality is several physical cells. Cell group refers to an area managed by a single AFE.
AFE:
Undervoltage - One Cell Falls < 2.5V (minor)
Overvoltage - One cell > 4.5V (Major)
Balance - Across entire pack, if difference between max and min cells is > 0.05V (Major)
Temperature - if any thermistor reads > 60deg (Major)
Note: If thermistors read > 45deg, open solar relay to disable charging, but this is not a fault
Current Sense
Overcurrent - reading > 58.2A (Minor)
Temp > 60Deg (major)
KillSwitch
Will shutoff batteries by itself, but we will treat it as a BPS fault (minor)
Operation
BMS carrier sends/receives messages, which help it start up and operate properly.
Startup
Car turns on to power main or power aux, BMS board receives power from Aux
On startup, do all initial checks that are possible
If everything checks out, start transmitting BPS heartbeat to indicate successful startup
Wait for message from Centre Console to close relays
Close relays
Continue to monitor and send BPS heartbeat messages, data, in normal operation
Shutdown
Centre console (when power off is pressed) will send a close relays message
Centre console will cut power to BMS via Power distribution once it has confirmed that relays are closed
Faults
AFEs
Current Sense
Fan Faults
Data Output
(this is just documentation on what was done in FW14, and is subject to change)
BMS Outputs the following over the CAN bus:
cell voltages
cell temperatures
avg current
avg voltage
relay states
fan states
AFEs
The AFEs (analog front end) handle interactions with the main battery pack. There are multiple AFEs (LTC6811 chips) which handle reading cell voltages, reading thermistors to determine cell temperatures, and doing load balancing for the cells. These multiple AFE units are daisy-chained through one SPI interface. This SPI interface is interacted with the same as normal spi, but through hardware is translated to isoSPI and back to SPI for improved reliability.
AFE Configuration
The AFE operation revolves around two main data structures.
typedef struct LtcAfeSettings { GpioAddress cs; GpioAddress mosi; GpioAddress miso; GpioAddress sclk; const SpiPort spi_port; uint32_t spi_baudrate; LtcAfeAdcMode adc_mode; uint16_t cell_bitset[LTC_AFE_MAX_DEVICES]; uint16_t aux_bitset[LTC_AFE_MAX_DEVICES]; size_t num_devices; size_t num_cells; size_t num_thermistors; } LtcAfeSettings; typedef struct LtcAfeStorage { // Only used for storage in the FSM so we store data for the correct cells uint16_t aux_index; uint16_t retry_count; uint16_t cell_voltages[LTC_AFE_MAX_CELLS]; uint16_t aux_voltages[LTC_AFE_MAX_THERMISTORS]; uint16_t discharge_bitset[LTC_AFE_MAX_DEVICES]; uint16_t cell_result_lookup[LTC_AFE_MAX_CELLS]; uint16_t aux_result_lookup[LTC_AFE_MAX_THERMISTORS]; uint16_t discharge_cell_lookup[LTC_AFE_MAX_CELLS]; LtcAfeSettings settings; } LtcAfeStorage;
The settings struct holds all the configuration for the hardware being used with the AFEs, including the number of AFEs, number of cells, and number of thermistors. The cell_bitset and aux_bitset indicate which of the total set of cells/thermistors we should read as inputs.
The storage struct holds the information from the settings, as well as memory for all of the readings taken.
AFE Readings
AFE readings are taken via the daisy-chain method, meaning that a read of a certain register on one AFE will be replied to with the values of all of the AFEs connected. (For example, the reading of the voltage register A of one of the AFE will be replied to with x 64 bit readings, where x is the number of AFEs connected)
Cell Sense
Cell sense readings happen in ltc_afe_impl_read_cells
. Essentially, we iterate through the number of voltage registers (4) and for each we read the 3 uint16_t voltages and one 16-bit Packet Error Check from each of the AFEs at this register. These results are then placed at the correct position in the cell_voltages
array based on the cell_bitset and cell_result_lookup
Aux Sense
Aux sense, used for the thermistors, is done on a per-cell basis. Essentially, each read is done for an individual input thermistor. Due to the daisy-chain, this result will be the width of readings*x afes.
This reading must be initiated repeatedly for the number of thermistors connected to the afes
AFE FSM
The LTC AFE FSM is responsible for handling the different states required for generating cell sense and a data (cell voltages) as well as aux data (thermistor readings). Once it is initialized, it will start reading cell sense values from the ltc6811, processing these values, and then doing the same for thermistor values in a continuous cycle.
LTC AFE Driver FSM Structure:
States:
LTC_AFE_IDLE (TBD)
Only needed if we need to execute error functionality while not running commands on the ltc6811
LTC_AFE_TRIGGER_CELL_CONV
Trigger conversion of voltage values
Output:
Send command to start conversion of cell voltage values
Input func:
Check to see if 10ms has passed
Transition to read cells
LTC_AFE_READ_CELLS
Output function:
SPI exchange to read/store all cell values, store in results array
Check for faults in readings
Input function transitions to aux conversion assuming no faults
LTC_AFE_TRIGGER_AUX_CONV
Output:
Send command to start read temperature values of a cell (we should maybe change to set of cells)
Input
Transition to read aux if 6 ms have passed
LTC_AFE_READ_AUX
Output:
Read current cell, increment cell number
Input
if cell number == number of cells, aux is done reading → transition to complete
else transition back to trigger aux conversion for next conversion
LTC_AUX_COMPLETE
Fault Behaviour:
Just transition to Idle for now. We will signal main BMS if an error occurs
Transitions:
LTC_AFE_TRIGGER_CELL_CONV → LTC_AFE_READ_CELLS
LTC_AFE_READ_CELLS → LTC_AFE_TRIGGER_AUX_CONV
LTC_AFE_READ_CELLS → LTC_AFE_READ_CELLS
LTC_AFE_TRIGGER_AUX_CONV → LTC_AFE_READ_AUX
LTC_AFE_READ_AUX → LTC_AFE_TRIGGER_AUX_CONV
LTC_AFE_READ_AUX → LTC_AFE_AUX_COMPLETE
LTC_AFE_READ_AUX → LTC_AFE_READ_AUX
LTC_AFE_AUX_COMPLETE → LTC_AFE_TRIGGER_CELL_CONV
Transitions continue in this loop format for the entirety of the time that BMS is operational.
The states should also be able to transition to and from LTC_AFE_STATE_IDLE if this is how we decide to operate our error states.
AFE Discharge/Load Balancing
Based on the results received, we iterate through and determine what the minimum and maximum voltage values are per cell. We are checking for a difference