Skip to content

Commit

Permalink
Dj90864/open wire check (#1129)
Browse files Browse the repository at this point in the history
### Summary
<!-- Quick summary of changes, optional -->
Implemented Open Wire Check Feature for Cell Voltages

### Changelist 
<!-- Give a list of the changes covered in this PR. This will help both
you and the reviewer keep this PR within scope. -->

### Testing Done
<!-- Outline the testing that was done to demonstrate the changes are
solid. This could be unit tests, integration tests, testing on the car,
etc. Include relevant code snippets, screenshots, etc as needed. -->
Testing done with pseudo segment board

### Resolved Issues
<!-- Link any issues that this PR resolved like so: `Resolves #1, #2,
and #5` (Note: Using this format, Github will automatically close the
issue(s) when this PR is merged in). -->

### Checklist
*Please change `[ ]` to `[x]` when you are ready.*
- [ ] I have read and followed the code conventions detailed in
[README.md](../README.md) (*This will save time for both you and the
reviewer!*).
- [ ] If this pull request is longer then **500** lines, I have provided
*explicit* justification in the summary above explaining why I *cannot*
break this up into multiple pull requests (*Small PR's are faster and
less painful for everyone involved!*).
  • Loading branch information
DJ90864 authored Feb 3, 2024
1 parent 4add42d commit 1ea9fd7
Show file tree
Hide file tree
Showing 10 changed files with 463 additions and 5 deletions.
8 changes: 7 additions & 1 deletion can_bus/thruna/BMS/BMS_alerts.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
"ChargerDisconnectedDuringCharge",
"ChargerExternalShutdown",
"TractiveSystemOvercurrent",
"PrechargeFailure"
"PrechargeFailure",
"OpenWireCheckFault",
"OpenWireCheck_Segment0_GND",
"OpenWireCheck_Segment1_GND",
"OpenWireCheck_Segment2_GND",
"OpenWireCheck_Segment3_GND",
"OpenWireCheck_Segment4_GND"
]
}
29 changes: 29 additions & 0 deletions can_bus/thruna/BMS/BMS_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -359,5 +359,34 @@
"bits": 1
}
}
},
"OWC_Segment0to2_Status": {
"msg_id": 141,
"cycle_time": 100,
"description": "Open Wire Check Segment 0 to 2 Status",
"signals": {
"Segment0_OWC_Cells_Status": {
"bits": 16
},
"Segment1_OWC_Cells_Status": {
"bits": 16
},
"Segment2_OWC_Cells_Status": {
"bits": 16
}
}
},
"OWC_Segment3to4_Status": {
"msg_id": 142,
"cycle_time": 100,
"description": "Open Wire Check Segment 3 to 4 Status",
"signals": {
"Segment3_OWC_Cells_Status": {
"bits": 16
},
"Segment4_OWC_Cells_Status": {
"bits": 16
}
}
}
}
2 changes: 2 additions & 0 deletions firmware/shared/src/app/app_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#define SET_BIT_HIGH(input, bit) (input | (1U << bit))
#define SET_BIT_LOW(input, bit) (input & ~(1U << bit))

#define APPROX_EQUAL(a, b, threshold) ((bool)(fabs((a) - (b)) < threshold))

// Extra guard because HAL defines the same macro
#ifndef UNUSED
#define UNUSED(x) (void)(x)
Expand Down
157 changes: 155 additions & 2 deletions firmware/thruna/BMS/src/app/app_accumulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
// Max number of PEC15 to occur before faulting
#define MAX_NUM_COMM_TRIES (3U)

// Number of open wire check commands (ADOW) to send before open wire check
#define OPEN_WIRE_CHECK_NUM_ADOW_CMDS (2)

// Open Wire Check Modes
#define PULL_UP (1U)
#define PULL_DOWN (0U)

// Discharging cells continuously generates too much heat.
// So balance cells for 100 ticks (the cell monitoring code runs in the 100Hz task, so 100 ticks = 1s),
// then disable discharge for the next 100 ticks to keep temperatures manageable.
Expand Down Expand Up @@ -49,6 +56,14 @@ typedef enum
GET_CELL_TEMP_STATE,
} AccumulatorMonitorState;

typedef enum
{
START_OPEN_WIRE_CHECK = 0U,
GET_PU_CELL_VOLTAGE_STATE,
GET_PD_CELL_VOLTAGE_STATE,
CHECK_OPEN_WIRE_FAULT_STATE,
} AccumulatorOpenWireCheckState;

typedef struct
{
uint8_t segment;
Expand All @@ -64,13 +79,23 @@ typedef struct
float pack_voltage;
} VoltageStats;

typedef struct
{
uint16_t owcStatus[ACCUMULATOR_NUM_SEGMENTS];
bool owcFaultGND[ACCUMULATOR_NUM_SEGMENTS];
bool owcGlobalFault;
} OWCFaults;

typedef struct
{
// Cells information
uint8_t num_comm_tries;
VoltageStats voltage_stats;
AccumulatorMonitorState state;

// OWC information
OWCFaults owc_faults;
AccumulatorOpenWireCheckState owc_state;
// Balancing information
bool balance_enabled;
bool cells_to_balance[ACCUMULATOR_NUM_SEGMENTS][ACCUMULATOR_NUM_SERIES_CELLS_PER_SEGMENT];
Expand All @@ -79,6 +104,8 @@ typedef struct
} Accumulator;

static Accumulator data;
static uint8_t open_wire_pu_readings;
static uint8_t open_wire_pd_readings;

static void app_accumulator_calculateVoltageStats(void)
{
Expand Down Expand Up @@ -203,6 +230,10 @@ void app_accumulator_init(void)

// Balancing information
memset(&data.cells_to_balance, 0U, sizeof(data.cells_to_balance));

open_wire_pu_readings = 0;
open_wire_pd_readings = 0;
data.owc_state = START_OPEN_WIRE_CHECK;
}

void app_accumulator_writeDefaultConfig()
Expand Down Expand Up @@ -248,6 +279,112 @@ void app_accumulator_runOnTick100Hz(void)
}
}

static void app_accumulator_owcCalculateFaults(void)
{
OWCFaults owcFaults = { .owcStatus = { 0U }, .owcFaultGND = { 0U }, .owcGlobalFault = 0U };

owcFaults.owcGlobalFault = io_ltc6813CellVoltages_getGlobalOpenWireFault();

if (owcFaults.owcGlobalFault)
{
for (uint8_t segment = 0; segment < ACCUMULATOR_NUM_SEGMENTS; segment++)
{
if (io_ltc6813CellVoltages_getOpenWireFault(segment, 0))
{
owcFaults.owcFaultGND[segment] = true;
owcFaults.owcStatus[segment] = (uint16_t)1;
}
else
{
for (uint8_t cell = 1; cell < ACCUMULATOR_NUM_SERIES_CELLS_PER_SEGMENT; cell++)
{
if (io_ltc6813CellVoltages_getOpenWireFault(segment, cell))
{
owcFaults.owcStatus[segment] |= ((uint16_t)(1 << cell));
}
}
}
}
}

data.owc_faults = owcFaults;
}

bool app_accumulator_openWireCheck(void)
{
bool is_finished = false;

switch (data.owc_state)
{
case START_OPEN_WIRE_CHECK:
{
// update the number of commands that've been run already before starting Open Wire Check
open_wire_pu_readings = 0;
open_wire_pd_readings = 0;

// Set up or acquire the Mutex for iso-SPI
bool Mutex_Acquired = true; // this line is just a reminder to fix it with proper code

if (Mutex_Acquired)
{
io_ltc6813CellVoltages_owcStart(PULL_UP);
open_wire_pu_readings++;
data.owc_state = GET_PU_CELL_VOLTAGE_STATE;
}
break;
}
case GET_PU_CELL_VOLTAGE_STATE:
{
if (open_wire_pu_readings >= OPEN_WIRE_CHECK_NUM_ADOW_CMDS)
{
UPDATE_PEC15_ERROR_COUNT(io_ltc6813CellVoltages_owcReadVoltages(PULL_UP), data.num_comm_tries);

io_ltc6813CellVoltages_owcStart(PULL_DOWN);
open_wire_pd_readings++;
data.owc_state = GET_PD_CELL_VOLTAGE_STATE;
}
else
{
io_ltc6813CellVoltages_owcStart(PULL_UP);
open_wire_pu_readings++;
}
break;
}
case GET_PD_CELL_VOLTAGE_STATE:
{
if (open_wire_pd_readings >= OPEN_WIRE_CHECK_NUM_ADOW_CMDS)
{
UPDATE_PEC15_ERROR_COUNT(io_ltc6813CellVoltages_owcReadVoltages(PULL_DOWN), data.num_comm_tries);

data.owc_state = CHECK_OPEN_WIRE_FAULT_STATE;
}
else
{
io_ltc6813CellVoltages_owcStart(PULL_DOWN);
open_wire_pd_readings++;
}
break;
}
case CHECK_OPEN_WIRE_FAULT_STATE:
{
io_ltc6813CellVoltages_checkOpenWireStatus();
data.owc_state = START_OPEN_WIRE_CHECK;

app_accumulator_owcCalculateFaults();

// give away mutex for iso-SPI

break;
}
default:
{
break;
}
}

return is_finished;
}

void app_accumulator_broadcast(void)
{
// Broadcast pack voltage.
Expand Down Expand Up @@ -278,6 +415,13 @@ void app_accumulator_broadcast(void)
app_canTx_BMS_MinTempIdx_set(min_loc);
app_canTx_BMS_MaxTempIdx_set(max_loc);

// Broadcast OWC information
app_canTx_BMS_Segment0_OWC_Cells_Status_set(data.owc_faults.owcStatus[0]);
app_canTx_BMS_Segment1_OWC_Cells_Status_set(data.owc_faults.owcStatus[1]);
app_canTx_BMS_Segment2_OWC_Cells_Status_set(data.owc_faults.owcStatus[2]);
app_canTx_BMS_Segment3_OWC_Cells_Status_set(data.owc_faults.owcStatus[3]);
app_canTx_BMS_Segment4_OWC_Cells_Status_set(data.owc_faults.owcStatus[4]);

// Calculate and broadcast pack power.
const float available_power =
MIN(app_math_linearDerating(max_cell_temp, MAX_POWER_LIMIT_W, CELL_ROLL_OFF_TEMP_DEGC, CELL_FULLY_DERATED_TEMP),
Expand Down Expand Up @@ -319,8 +463,17 @@ bool app_accumulator_checkFaults(void)
app_canAlerts_BMS_Fault_CellOvertemp_set(overtemp_fault);
app_canAlerts_BMS_Fault_ModuleCommunicationError_set(communication_fault);

const bool acc_fault =
overtemp_fault || undertemp_fault || overvoltage_fault || undervoltage_fault || communication_fault;
bool owc_fault = data.owc_faults.owcGlobalFault;

app_canAlerts_BMS_Fault_OpenWireCheckFault_set(data.owc_faults.owcGlobalFault);
app_canAlerts_BMS_Fault_OpenWireCheck_Segment0_GND_set(data.owc_faults.owcFaultGND[0]);
app_canAlerts_BMS_Fault_OpenWireCheck_Segment1_GND_set(data.owc_faults.owcFaultGND[1]);
app_canAlerts_BMS_Fault_OpenWireCheck_Segment2_GND_set(data.owc_faults.owcFaultGND[2]);
app_canAlerts_BMS_Fault_OpenWireCheck_Segment3_GND_set(data.owc_faults.owcFaultGND[3]);
app_canAlerts_BMS_Fault_OpenWireCheck_Segment4_GND_set(data.owc_faults.owcFaultGND[4]);

const bool acc_fault = overtemp_fault || undertemp_fault || overvoltage_fault || undervoltage_fault ||
communication_fault || owc_fault;

return acc_fault;
}
Expand Down
5 changes: 5 additions & 0 deletions firmware/thruna/BMS/src/app/app_accumulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ void app_accumulator_writeDefaultConfig(void);
*/
void app_accumulator_runOnTick100Hz(void);

/**
* Open Wire Check state machine
*/
bool app_accumulator_openWireCheck(void);

/**
* Broadcast state of the accumulator over CAN.
*/
Expand Down
16 changes: 15 additions & 1 deletion firmware/thruna/BMS/src/app/states/app_allStates.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ void app_allStates_runOnTick1Hz(void)
}
}

uint32_t owcCounter = 0;

bool app_allStates_runOnTick100Hz(void)
{
app_canTx_BMS_Heartbeat_set(true);
Expand All @@ -43,7 +45,19 @@ bool app_allStates_runOnTick100Hz(void)
app_heartbeatMonitor_tick();
app_heartbeatMonitor_broadcastFaults();

app_accumulator_runOnTick100Hz();
owcCounter++;
if (owcCounter >= 500) // run Open Wire Check every 5 seconds
{
if (app_accumulator_openWireCheck())
{
owcCounter = 0;
}
}
else
{
app_accumulator_runOnTick100Hz();
}

app_thermistors_updateAuxThermistorTemps();

app_accumulator_broadcast();
Expand Down
4 changes: 4 additions & 0 deletions firmware/thruna/BMS/src/app/states/app_initState.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#define TS_DISCHARGED_THRESHOLD_V (10.0f)

extern uint32_t owcCounter;

static void initStateRunOnEntry(void)
{
app_canTx_BMS_State_set(BMS_INIT_STATE);
Expand All @@ -18,6 +20,8 @@ static void initStateRunOnEntry(void)
// Should always be opened at this point from other states, this is only for redundancy since we really don't want
// AIR+ closed in init
io_airs_openPositive();

owcCounter = 0;
}

static void initStateRunOnTick1Hz(void)
Expand Down
Loading

0 comments on commit 1ea9fd7

Please sign in to comment.