Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
194f1ca
The beginnings of state machine implementation
kzwicker Jan 9, 2026
d3c9322
The beginnings of state machine implementation
kzwicker Jan 9, 2026
c1ed33e
Added the function signature of ECU_Tractive_System_Discharge_Start i…
XuChe777 Jan 9, 2026
35bc726
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 13, 2026
5e8a21b
Merge branch 'StateMachineImplementation' of https://github.com/Gauch…
kzwicker Jan 13, 2026
1114241
cleaned up data, switched to floats, etc
kzwicker Jan 13, 2026
6f38a83
Merge branch 'StateMachineImplementation' of https://github.com/Gauch…
kzwicker Jan 13, 2026
4008051
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 13, 2026
a72a587
add a placeholder
XuChe777 Jan 13, 2026
b2d1ef0
Merge branch 'main' into StateMachineImplementation
dchansen06 Jan 13, 2026
f33172e
volatile state lump
kzwicker Jan 16, 2026
6a27ff1
scopes
kzwicker Jan 16, 2026
cec19d0
adc basic functionality to ECU
khoulihan27 Jan 16, 2026
6fa0832
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 16, 2026
5c7f46b
Merge branch 'main' into StateMachineImplementation
dchansen06 Jan 16, 2026
beb3a2f
fixed LL stuff
khoulihan27 Jan 16, 2026
9a978d2
fixed LL implementation
khoulihan27 Jan 16, 2026
7921f1b
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 16, 2026
7434de7
fixed free() stuff
khoulihan27 Jan 16, 2026
f5a3ac2
Co-authored-by: Ng0710 <Ng0710@users.noreply.github.com>
khoulihan27 Jan 16, 2026
bfa3f4a
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 16, 2026
8bef2c1
Spread volatility over the state data lump for things to do better
dchansen06 Jan 16, 2026
787876c
removed switch-case for if-else, fixed function order in main
khoulihan27 Jan 16, 2026
d5ccf94
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 16, 2026
f0d0633
Use `const volatile` for `ECU_StateData` pointers that you should not…
dchansen06 Jan 16, 2026
9187de1
Automatic Clang-Format: Standardized formatting automatically
github-actions[bot] Jan 16, 2026
10e55cc
fixed stateLump not being declared volatile
khoulihan27 Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions ECU/Application/Inc/StateData.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,48 @@
* logic to access and modify the ECU's operational data.
*/
typedef struct ECU_StateData {
// DON'T TOUCH YET
GR_OLD_ECU_STATUS_1_MSG ecuStatus1;
GR_OLD_ECU_STATUS_2_MSG ecuStatus2;
GR_OLD_ECU_STATUS_3_MSG ecuStatus3;

// TODO: Remove unneeded states
int32_t dischargeStartMillis;
uint32_t lastECUStatusMsgTick;
uint32_t lastTSSIFlash;
int32_t last_drive_active_control_ms;

float min_amk_heat_cap_throttle_percent;
float ts_voltage;
float max_cell_temp; /** Temperature of hottest cell, celsius */

float vehicle_speed; /** Vehicle speed, MPH */
float fr_wheel_rpm; /** FR wheel, RPM */
float fl_wheel_rpm; /** FL wheel, RPM */
float rr_wheel_rpm; /** RRv wheel, RPM */
float rl_wheel_rpm; /** RL wheel, RPM */

// 0.5V when things go to shit (X_OK low)
// 3V when things almost poggers (X_OK high but SDC not reset)
// 2.4V when things are actually poggers (X_OK high and SDC is not triggered)
float ams_sense;
float imd_sense;
float bspd_sense;

float estop_sense;
uint16_t driving_heat_capacity_1;
uint16_t driving_heat_capacity_2;
uint16_t APPS1_Signal;
uint16_t APPS2_Signal;
uint16_t Brake_R_Signal;
uint16_t Brake_F_Signal;
uint16_t STEERING_ANGLE_SIGNAL;
int8_t ping_block[3]; /** Node timeout status bits (1=OK, 0=Timeout) */
uint8_t powerlevel_torquemap; /** Power lvl (4b) & torque map (4b) */
uint8_t tractivebattery_soc; /** Accumulator SoC, 20x/51=% */
uint8_t glv_soc; /** GLV SoC, 20x/51=% */
uint8_t acu_error_warning_bits;
uint8_t inverter_fault_map;
bool bse_apps_violation;
bool ts_active_button_engaged;
bool rtd_button_engaged;
GR_ECU_State ecu_state;
} ECU_StateData; // FIXME Add comments to each data field with descriptions and
// rules (eg -1 = invalid?, etc)
// Will also need to add information from ADC into this struct
Expand Down
24 changes: 18 additions & 6 deletions ECU/Application/Inc/StateTicks.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void ECU_State_Tick(void);
*
* @return void
*/
void ECU_GLV_Off(ECU_StateData *stateData);
void ECU_GLV_Off(volatile ECU_StateData *stateData);

/**
* @brief State handler for the GLV On state.
Expand All @@ -33,7 +33,7 @@ void ECU_GLV_Off(ECU_StateData *stateData);
*
* @return void
*/
void ECU_GLV_On(ECU_StateData *stateData);
void ECU_GLV_On(volatile ECU_StateData *stateData);

/**
* @brief State handler for the Precharge Engaged state.
Expand All @@ -44,7 +44,7 @@ void ECU_GLV_On(ECU_StateData *stateData);
*
* @return void
*/
void ECU_Precharge_Engaged(ECU_StateData *stateData);
void ECU_Precharge_Engaged(volatile ECU_StateData *stateData);

/**
* @brief State handler for the Precharge Complete state.
Expand All @@ -55,7 +55,7 @@ void ECU_Precharge_Engaged(ECU_StateData *stateData);
*
* @return void
*/
void ECU_Precharge_Complete(ECU_StateData *stateData);
void ECU_Precharge_Complete(volatile ECU_StateData *stateData);

/**
* @brief State handler for the Precharge Fault state.
Expand All @@ -66,7 +66,19 @@ void ECU_Precharge_Complete(ECU_StateData *stateData);
*
* @return void
*/
void ECU_Drive_Active(ECU_StateData *stateData);
void ECU_Drive_Active(volatile ECU_StateData *stateData);

/**
* @brief Init function for ECU_Tractive_System_Discharge_Start.
*
* Resets Tractive System discharge timer and switches on the Tractive System
* Discharge state.
*
* @param stateData Pointer to the ECU state data structure.
*
* @return void
*/
void ECU_Tractive_System_Discharge_Start(volatile ECU_StateData *stateData);

/**
* @brief State handler for the Tractive System Discharge state.
Expand All @@ -78,6 +90,6 @@ void ECU_Drive_Active(ECU_StateData *stateData);
*
* @return void
*/
void ECU_Tractive_System_Discharge(ECU_StateData *stateData);
void ECU_Tractive_System_Discharge(volatile ECU_StateData *stateData);

#endif
12 changes: 6 additions & 6 deletions ECU/Application/Inc/StateUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
#define APPS_OFFSET 250.0f // TODO: Need to be experimentally determined

// Checks stateData for critical errors
bool CriticalError(const ECU_StateData *stateData);
bool CommunicationError(const ECU_StateData *stateData);
bool APPS_BSE_Violation(const ECU_StateData *stateData);
bool PressingBrake(const ECU_StateData *stateData);
float CalcBrakePercent(const ECU_StateData *stateData);
float CalcPedalTravel(const ECU_StateData *stateData);
bool CriticalError(volatile const ECU_StateData *stateData);
bool CommunicationError(volatile const ECU_StateData *stateData);
bool APPS_BSE_Violation(volatile const ECU_StateData *stateData);
bool PressingBrake(volatile const ECU_StateData *stateData);
float CalcBrakePercent(volatile const ECU_StateData *stateData);
float CalcPedalTravel(volatile const ECU_StateData *stateData);

#endif
108 changes: 74 additions & 34 deletions ECU/Application/Src/StateTicks.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@
*
* @remark Intentionally not a globally accessible variable
*/
ECU_StateData stateLump = {0};
volatile ECU_StateData stateLump = {0};

#define ECU_STATUS_MSG_PERIOD (100)
#define TRACTIVE_SYSTEM_MAX_DISCHARGE_TIME (10000) // TODO: determine an appropriate wait time

void ECU_State_Tick(void)
{
LOGOMATIC("ECU Current State: %d\n", stateLump.ecuStatus1.ecu_status);
if (stateLump.lastECUStatusMsgTick >= ECU_STATUS_MSG_PERIOD) {
LOGOMATIC("ECU Current State: %d\n", stateLump.ecu_state);
stateLump.lastECUStatusMsgTick = 0;
} else {
stateLump.lastECUStatusMsgTick++;
}

switch (stateLump.ecuStatus1.ecu_status) {
switch (stateLump.ecu_state) {
case GR_GLV_OFF:
ECU_GLV_Off(&stateLump);
break;
Expand All @@ -40,9 +48,9 @@ void ECU_State_Tick(void)
ECU_Tractive_System_Discharge(&stateLump);
break;
default:
LOGOMATIC("ECU Current State Unknown: %d\n", stateLump.ecuStatus1.ecu_status);
LOGOMATIC("ECU Current State Unknown: %d\n", stateLump.ecu_state);
LOGOMATIC("ECU: Resetting to GLV On\n");
stateLump.ecuStatus1.ecu_status = GR_GLV_ON;
stateLump.ecu_state = GR_GLV_ON;
break;
}
}
Expand All @@ -54,52 +62,46 @@ transitioning state

*/

void ECU_GLV_Off(ECU_StateData *stateData)
void ECU_GLV_Off(volatile ECU_StateData *stateData)
{
UNUSED(stateData);
// TODO Implement functionality
// ERROR --> GLV_OFF should never be reached
}

void ECU_GLV_On(ECU_StateData *stateData)
void ECU_GLV_On(volatile ECU_StateData *stateData)
{
UNUSED(stateData);
/*
if(stateData->TractiveSystemVoltage >= 60){ // should never happen but
has to be accounted for stateData->currentState = GR_TS_DISCHARGE;
emit an error
break;
if (stateData->ts_voltage >= 60) { // should never happen but has to be accounted for
ECU_Tractive_System_Discharge_Start(stateData);
// emit an error
return;
}
*/

// TODO Implement functionality
if (stateData->ts_active_button_engaged) {
stateData->ecuStatus1.ecu_status = GR_PRECHARGE_ENGAGED;
stateData->ecu_state = GR_PRECHARGE_ENGAGED;
}
}

void ECU_Precharge_Engaged(ECU_StateData *stateData)
void ECU_Precharge_Engaged(volatile ECU_StateData *stateData)
{
UNUSED(stateData);
if (stateData->ecuStatus2.ts_voltage > 60) {
// Go to TS discharge
stateData->ecuStatus1.ecu_status = GR_TS_DISCHARGE;
// Emit an error
if (stateData->ts_voltage >= 60) {
ECU_Tractive_System_Discharge_Start(stateData);
// emit an error
return;
}
// TODO Implement functionality
/*if(not TS Active || Communication Error (CAN)){
stateData->currentState = GR_TS_DISCHARGE
break;
}*/
if (!stateData->ts_active_button_engaged || CommunicationError(stateData)) {
ECU_Tractive_System_Discharge_Start(stateData);
return;
}
/*if(1 Isolation relay close && second isolation relay close){ --> CAN!
stateData->currentState = GR_PRECHARGE_COMPLETE
}*/
}

void ECU_Precharge_Complete(ECU_StateData *stateData)
void ECU_Precharge_Complete(volatile ECU_StateData *stateData)
{
UNUSED(stateData);
// TODO Implement functionality
/*
On but idle
Expand All @@ -111,7 +113,7 @@ void ECU_Precharge_Complete(ECU_StateData *stateData)
if (TS pressed or critical error) {
stateData->currentState = GR_TS_DISCHARGE
emit error
break;
return;
}
*/
/*
Expand All @@ -121,11 +123,19 @@ void ECU_Precharge_Complete(ECU_StateData *stateData)
*/

// Pseudocode
if (stateData->ts_active_button_engaged || CriticalError(stateData)) {
ECU_Tractive_System_Discharge_Start(stateData);
// emit an error
return;
}

if (PressingBrake(stateData) && stateData->rtd_button_engaged) {
stateData->ecu_state = GR_DRIVE_ACTIVE;
}
}

void ECU_Drive_Active(ECU_StateData *stateData)
void ECU_Drive_Active(volatile ECU_StateData *stateData)
{
UNUSED(stateData);
// TODO Implement functionality
/*
If APPS/BSE Violation --> Don't drive until resolved (no state
Expand All @@ -151,21 +161,51 @@ void ECU_Drive_Active(ECU_StateData *stateData)
- calcPedalTravel func :p
- make tuna-ble function
*/

if (!stateData->ts_active_button_engaged || CriticalError(stateData)) {
ECU_Tractive_System_Discharge_Start(stateData);
return;
}

if (!stateData->rtd_button_engaged) {
stateData->ecu_state = GR_PRECHARGE_COMPLETE;
// emit a warning if not moving
return;
}
}

void ECU_Tractive_System_Discharge(ECU_StateData *stateData)
void ECU_Tractive_System_Discharge_Start(volatile ECU_StateData *stateData)
{
stateData->ecu_state = GR_TS_DISCHARGE;
LOGOMATIC("tell the BCU to discharge TS");
stateData->dischargeStartMillis = 0;
}

void ECU_Tractive_System_Discharge(volatile ECU_StateData *stateData)
{
UNUSED(stateData);
// TODO Implement functionality of state itself
/*
Discharge the tractive system to below 60 volts
If TS voltage < 60 --> stateData->GLV_ON
*/
if (stateData->ecuStatus2.ts_voltage < 60) {
stateData->ecuStatus1.ecu_status = GR_GLV_ON;
// TODO: Discharge TC through CAN
LOGOMATIC("CAN: please discharge the Tractive System");
if (stateData->ts_voltage < 60) {
stateData->ecu_state = GR_GLV_ON;
stateData->dischargeStartMillis = 0;
return;
}
/*
If TS fails to discharge over time then stay and emit a warning,
see #129
*/
// TODO: Determine the maximum time to wait for TC to discharge.
if (stateData->dischargeStartMillis > TRACTIVE_SYSTEM_MAX_DISCHARGE_TIME) {
// TODO: Research appropriate ways to buffer warning messages.
LOGOMATIC("Tractive System fails to discharge in time.");
}

if (stateData->dischargeStartMillis < INT32_MAX) {
stateData->dischargeStartMillis++;
}
}
Loading
Loading