diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index 641d0389..2cab5243 100644 --- a/ECU/Application/Inc/StateData.h +++ b/ECU/Application/Inc/StateData.h @@ -51,14 +51,6 @@ typedef volatile struct ECU_StateData { // TODO: Remove unneeded states - uint32_t millisSinceBoot; - uint32_t can_msg_cooldown_tick; - - int32_t dischargeStartMillis; - uint32_t lastECUStatusMsgMillis; - uint32_t lastTSSIFlash; - int32_t last_drive_active_control_ms; - float min_amk_heat_cap_throttle_percent; float ts_voltage; float max_cell_temp_c; /** Temperature of hottest cell, celsius */ diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index f8515a4e..5c1498c1 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -29,12 +29,16 @@ uint32_t MillisecondsSinceBoot(void); #define MAX_CURRENT_AMPS 42.0f // TODO: Change as appropriate #define MAX_REVERSE_CURRENT_AMPS 20.0f // TODO: Change as appropriate +#define MAX_PRECHARGE_TIME 15000 // in ms + +#define ECU_STATUS_MSG_PERIOD_MILLIS (1000) +#define TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS (5000) + // Checks stateData for critical errors bool CriticalError(volatile const ECU_StateData *stateData); bool bmsFailure(volatile const ECU_StateData *stateData); bool imdFailure(volatile const ECU_StateData *stateData); bool bspdFailure(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); diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index f00fa29e..a3e842af 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -58,8 +58,8 @@ void ECU_CAN_MessageHandler(ECU_StateData *state_data, GR_OLD_BUS_ID bus_id, GR_ break; } GR_OLD_BCU_STATUS_1_MSG *bcu_status_1 = (GR_OLD_BCU_STATUS_1_MSG *)data; - state_data->tractivebattery_soc = bcu_status_1->tractivebattery_soc * 0.01; - state_data->glv_soc = bcu_status_1->glv_soc * 20 / 51; + state_data->tractivebattery_soc = bcu_status_1->tractivebattery_soc; + state_data->glv_soc = bcu_status_1->glv_soc; state_data->ts_voltage = bcu_status_1->ts_voltage * 0.01; break; diff --git a/ECU/Application/Src/CANutils.c b/ECU/Application/Src/CANutils.c index bbf562db..e7913331 100644 --- a/ECU/Application/Src/CANutils.c +++ b/ECU/Application/Src/CANutils.c @@ -9,6 +9,7 @@ #include "StateUtils.h" #include "can.h" #include "main.h" +#include "stm32g4xx_hal_fdcan.h" #include "string.h" uint32_t lastTickECUStateDataSent = 0; @@ -24,7 +25,7 @@ void ECU_CAN_Send(GR_OLD_BUS_ID bus, GR_OLD_NODE_ID destNode, GR_OLD_MSG_ID mess FDCAN_TxHeaderTypeDef header = { .Identifier = ID, - .IdType = FDCAN_STANDARD_ID, + .IdType = FDCAN_EXTENDED_ID, .TxFrameType = FDCAN_DATA_FRAME, .ErrorStateIndicator = FDCAN_ESI_ACTIVE, .DataLength = size, @@ -101,8 +102,8 @@ void SendECUStateDataOverCAN(ECU_StateData *stateData) .StatusBits = {stateData->status_bits[0], stateData->status_bits[1], stateData->status_bits[2]}, .PowerLevelTorqueMap = stateData->powerlevel_torquemap, .MaxCellTemp = (uint8_t)(stateData->max_cell_temp_c * 4), - .AccumulatorStateOfCharge = (uint8_t)(stateData->tractivebattery_soc * 51 / 20), - .GLVStateOfCharge = (uint8_t)(stateData->glv_soc * 51 / 20), + .AccumulatorStateOfCharge = (uint8_t)(stateData->tractivebattery_soc), + .GLVStateOfCharge = (uint8_t)(stateData->glv_soc), .TractiveSystemVoltage = (uint16_t)(stateData->ts_voltage * 100), .VehicleSpeed = (uint16_t)(stateData->vehicle_speed_mph * 100), .FRWheelRPM = (uint16_t)(stateData->fr_wheel_rpm * 10 + 32768), diff --git a/ECU/Application/Src/Lights.c b/ECU/Application/Src/Lights.c index 48f1f63b..a6be65a5 100644 --- a/ECU/Application/Src/Lights.c +++ b/ECU/Application/Src/Lights.c @@ -23,7 +23,7 @@ void TSSILightControl(ECU_StateData *stateLump) // Here we chose a period of 350ms if (stateLump->tssi_fault) { LL_GPIO_ResetOutputPin(TSSI_G_CONTROL_GPIO_Port, TSSI_G_CONTROL_Pin); - if (stateLump->millisSinceBoot % 350 < 175) { + if (MillisecondsSinceBoot() % 350 < 175) { LL_GPIO_SetOutputPin(TSSI_R_CONTROL_GPIO_Port, TSSI_R_CONTROL_Pin); } else { LL_GPIO_ResetOutputPin(TSSI_R_CONTROL_GPIO_Port, TSSI_R_CONTROL_Pin); diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 0a7d949c..92024f40 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -25,24 +25,21 @@ * * @remark Intentionally not a globally accessible variable */ + ECU_StateData stateLump = {.ecu_state = GR_GLV_ON, .bcu_software_latch = 1}; -static uint32_t buzzer_start_millis; -static uint32_t last_can_inverter_request_millis; CANHandle *primary_can; CANHandle *data_can; -#define ECU_STATUS_MSG_PERIOD_MILLIS (1000) -// EV.5.6.3: The Discharge Circuit must be designed to handle the maximum Tractive System voltage for minimum 15 seconds -#define TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS (15000) - +static uint32_t millis_since_boot; void ECU_State_Tick(void) { - stateLump.millisSinceBoot = MillisecondsSinceBoot(); + millis_since_boot = MillisecondsSinceBoot(); - if (stateLump.millisSinceBoot - stateLump.lastECUStatusMsgMillis >= ECU_STATUS_MSG_PERIOD_MILLIS) { + static uint32_t last_ECU_status_msg_millis; + if (millis_since_boot - last_ECU_status_msg_millis >= ECU_STATUS_MSG_PERIOD_MILLIS) { LOGOMATIC("ECU Current State: %d\n", stateLump.ecu_state); - stateLump.lastECUStatusMsgMillis = stateLump.millisSinceBoot; + last_ECU_status_msg_millis = millis_since_boot; } if (bmsFailure(&stateLump) || imdFailure(&stateLump)) { @@ -86,19 +83,21 @@ void ECU_GLV_Off(ECU_StateData *stateData) void ECU_GLV_On(ECU_StateData *stateData) { if (stateData->ts_voltage >= SAFE_VOLTAGE_LIMIT) { - ECU_Transition_To_Tractive_System_Discharge(stateData); LOGOMATIC("Error: TS Voltage >= %d!\n", SAFE_VOLTAGE_LIMIT); + ECU_Transition_To_Tractive_System_Discharge(stateData); ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_DEBUGGER, MSG_DEBUG_2_0, "TS-Runwy", 8); return; } if (stateData->ts_active_button_active /* && stateData->ir_plus*/) { // TODO: Talk to Owen if this is correct for precharge start confirmation - ECU_Transition_To_Precharge_Engaged(stateData); LOGOMATIC("GLV ON to PRECHARGE START!\n"); + ECU_Transition_To_Precharge_Engaged(stateData); return; } } +static uint32_t time_start_precharge; // for potential comms errors while precharging + void ECU_Transition_To_Precharge_Engaged(ECU_StateData *stateData) { /*send message to BCU to start precharging*/ @@ -106,6 +105,7 @@ void ECU_Transition_To_Precharge_Engaged(ECU_StateData *stateData) ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_BCU, MSG_BCU_PRECHARGE, &message, sizeof(message)); stateData->ecu_state = GR_PRECHARGE_ENGAGED; LOGOMATIC("PRECHARGE START to PRECHARGE ENGAGED!\n"); + time_start_precharge = millis_since_boot; return; } @@ -117,10 +117,10 @@ void ECU_Precharge_Engaged(ECU_StateData *stateData) return; } - if (!stateData->ts_active_button_active || CommunicationError(stateData)) { - ECU_Transition_To_Tractive_System_Discharge(stateData); + if (!stateData->ts_active_button_active || CriticalError(stateData) || (millis_since_boot - time_start_precharge) >= MAX_PRECHARGE_TIME) { LOGOMATIC("ERROR or ts_active OFF! PRECHARGE ENGAGED to TS DISCHARGE START!\n"); ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_DEBUGGER, MSG_DEBUG_2_0, "TS-P-ITR", 8); + ECU_Transition_To_Tractive_System_Discharge(stateData); return; } } @@ -129,13 +129,13 @@ void ECU_Precharge_Engaged(ECU_StateData *stateData) void ECU_Precharge_Complete(ECU_StateData *stateData) { if (!stateData->ts_active_button_active) { - ECU_Transition_To_Tractive_System_Discharge(stateData); LOGOMATIC("TS Active Toggled Off. Discharging Tractive System.\n"); + ECU_Transition_To_Tractive_System_Discharge(stateData); return; } if (CriticalError(stateData)) { - ECU_Transition_To_Tractive_System_Discharge(stateData); LOGOMATIC("Error: Critical Error Occurred. Discharging Tractive System.\n"); + ECU_Transition_To_Tractive_System_Discharge(stateData); ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_DEBUGGER, MSG_DEBUG_2_0, "HV-CritE", 8); return; } @@ -149,23 +149,24 @@ void ECU_Precharge_Complete(ECU_StateData *stateData) } } +static uint32_t buzzer_start_millis; + void ECU_Transition_To_Drive_Active(ECU_StateData *stateData) { - buzzer_start_millis = stateData->millisSinceBoot; - last_can_inverter_request_millis = stateData->millisSinceBoot; + buzzer_start_millis = millis_since_boot; stateData->ecu_state = GR_DRIVE_ACTIVE; } void ECU_Drive_Active(ECU_StateData *stateData) { if (!stateData->ts_active_button_active || CriticalError(stateData)) { - ECU_Transition_To_Tractive_System_Discharge(stateData); LOGOMATIC("Error: Critical Error Occured. Discharging Tractive System.\n"); + ECU_Transition_To_Tractive_System_Discharge(stateData); ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_DEBUGGER, MSG_DEBUG_2_0, "DA-CritE", 8); return; } - if (stateData->millisSinceBoot - buzzer_start_millis > 2000) { + if (millis_since_boot - buzzer_start_millis > 2000) { LL_GPIO_ResetOutputPin(RTD_CONTROL_GPIO_Port, RTD_CONTROL_Pin); } else { LL_GPIO_SetOutputPin(RTD_CONTROL_GPIO_Port, RTD_CONTROL_Pin); @@ -192,28 +193,30 @@ void ECU_Drive_Active(ECU_StateData *stateData) static uint32_t last_apps_plausible_frame_millis; if (APPS_Plausible(stateData)) { - last_apps_plausible_frame_millis = stateData->millisSinceBoot; + last_apps_plausible_frame_millis = millis_since_boot; } // Stop throttle if implausible for > 100ms - if (stateData->apps_bse_violation || stateData->millisSinceBoot - last_apps_plausible_frame_millis > 100) { + if (stateData->apps_bse_violation || millis_since_boot - last_apps_plausible_frame_millis > 100) { torque_request = 0; } - if (stateData->millisSinceBoot - last_can_inverter_request_millis > 10) { + static uint32_t last_can_inverter_request_millis; + if (millis_since_boot - last_can_inverter_request_millis > 10) { GR_OLD_INVERTER_COMMAND_MSG message = {.ac_current = torque_request * 100 + 32768, .dc_current = torque_request * 100 + 32768, .drive_enable = 1, .rpm_limit = 0}; ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_GR_INVERTER_1, MSG_INVERTER_COMMAND, &message, sizeof(message)); - last_can_inverter_request_millis = stateData->millisSinceBoot; + last_can_inverter_request_millis = millis_since_boot; } } +static uint32_t discharge_start_millis; void ECU_Transition_To_Tractive_System_Discharge(ECU_StateData *stateData) { stateData->ecu_state = GR_TS_DISCHARGE; LOGOMATIC("ECU: BCU discharge Tractive System\n"); GR_OLD_BCU_PRECHARGE_MSG message = {.precharge = 0}; ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_BCU, MSG_BCU_PRECHARGE, &message, sizeof(message)); - stateData->dischargeStartMillis = stateData->millisSinceBoot; + discharge_start_millis = millis_since_boot; } void ECU_Tractive_System_Discharge(ECU_StateData *stateData) @@ -230,8 +233,16 @@ void ECU_Tractive_System_Discharge(ECU_StateData *stateData) If TS fails to discharge over time then stay and emit a warning, see #129 */ - if (stateData->millisSinceBoot - stateData->dischargeStartMillis > TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS) { - LOGOMATIC("Warning: Tractive System fails to discharge in time.\n"); + if (millis_since_boot - discharge_start_millis > TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS) { + LOGOMATIC("Warning: Tractive System fails to discharge in %d seconds.\n", TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS); ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_DEBUGGER, MSG_DEBUG_2_0, "TS-D-TLE", 8); } + + // Discharge the car @ 100 Hz + static uint32_t last_discharge_request_millis; + if (millis_since_boot - last_discharge_request_millis > 10) { + GR_OLD_BCU_PRECHARGE_MSG message = {.precharge = 0}; + ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_BCU, MSG_BCU_PRECHARGE, &message, sizeof(message)); + last_discharge_request_millis = millis_since_boot; + } } diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index 2d4bf958..9ec8c468 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -48,13 +48,6 @@ bool bspdFailure(volatile const ECU_StateData *stateData) // TODO: shutdown switch stuff } -bool CommunicationError(volatile const ECU_StateData *stateData) -{ - UNUSED(stateData); - // TODO: Check for communication errors - return false; -} - bool APPS_BSE_Violation(volatile const ECU_StateData *stateData) { // Checks 2 * APPS_1 is within 10% of APPS_2 and break + throttle at the same time diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 3ea450de..6c08dd27 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -436,9 +436,11 @@ int main(void) if (MillisecondsSinceBoot() >= nextPing) { pingAll(); + // TODO: implement error handling if (nextPing != 0) { if (getRTT(GR_BCU) == PINGTIMEOUT_VALUE) { LOGOMATIC("ERROR: BCU is not responding to pings!\n"); + ECU_CAN_Send(GR_OLD_BUS_PRIMARY, GR_DEBUGGER, MSG_DEBUG_2_0, "ECU-P-ITR", 8); } if (getRTT(GR_DASH_PANEL) == PINGTIMEOUT_VALUE) { LOGOMATIC("ERROR: Dash Panel is not responding to pings!\n"); @@ -459,7 +461,7 @@ int main(void) write_adc_values_to_state_data(); ECU_State_Tick(); lightControl(&stateLump); - LOGOMATIC("Main Loop Tick Complete. I use Arch btw\n"); + // LOGOMATIC("Main Loop Tick Complete. I use Arch btw\n"); } /* USER CODE END 3 */ } diff --git a/ECU/Test/Inc/stm32g4xx_hal_fdcan.h b/ECU/Test/Inc/stm32g4xx_hal_fdcan.h new file mode 100644 index 00000000..f9ccecdc --- /dev/null +++ b/ECU/Test/Inc/stm32g4xx_hal_fdcan.h @@ -0,0 +1,6 @@ +#ifndef STM32G4xx_HAL_FDCAN_H +#define STM32G4xx_HAL_FDCAN_H + +#define FDCAN_EXTENDED_ID ((uint32_t)0x40000000U) /*!< Extended ID element */ + +#endif diff --git a/ECU/Test/Src/StateTicksTest.c b/ECU/Test/Src/StateTicksTest.c index c2f9e849..9bc8466b 100644 --- a/ECU/Test/Src/StateTicksTest.c +++ b/ECU/Test/Src/StateTicksTest.c @@ -7,6 +7,7 @@ #include "StateUtils.h" #include "can.h" #include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_fdcan.h" /* - GLV ON @@ -21,18 +22,10 @@ - TS DISCHARGE (ts voltage > 60), then less than 60 -> GLV ON */ -#define ECU_STATUS_MSG_PERIOD_MILLIS (1000) -// EV.5.6.3: The Discharge Circuit must be designed to handle the maximum Tractive System voltage for minimum 15 seconds -#define TRACTIVE_SYSTEM_MAX_PERMITTED_DISCHARGE_TIME_MILLIS (15000) - // static void ECU_Pseudo_Time_Progress(uint32_t dt) { stateLumpTest.millisSinceBoot += dt; } static void ECU_Pseudo_State_Tick(ECU_StateData *stateLumpTest) { - if (stateLumpTest->millisSinceBoot - stateLumpTest->lastECUStatusMsgMillis >= ECU_STATUS_MSG_PERIOD_MILLIS) { - LOGOMATIC("ECU Current State: %d\n", stateLumpTest->ecu_state); - stateLumpTest->lastECUStatusMsgMillis = stateLumpTest->millisSinceBoot; - } if (bmsFailure(stateLumpTest) || imdFailure(stateLumpTest)) { stateLumpTest->tssi_fault = true;