diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index 3bad50701..7fa4abfe0 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 */ @@ -81,6 +73,7 @@ typedef volatile struct ECU_StateData { float driving_heat_capacity_2; uint16_t APPS1_Signal; uint16_t APPS2_Signal; + uint16_t BSE_Signal; uint16_t Brake_R_Signal; uint16_t Brake_F_Signal; uint8_t status_bits[3]; diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index f8515a4e3..331dafe0c 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -20,6 +20,7 @@ uint32_t MillisecondsSinceBoot(void); #define THROTTLE_MIN_2 0 // TODO: need to be determined #define THROTTLE_MAX_2 4095 // TODO: need to be determined #define BSE_DEADZONE 0.05f +#define MAX_BSE_FAILURE_TIME 100 #define APPS_PROPORTION 2.0f // TODO: Need to be experimentally determined #define APPS_OFFSET 250.0f // TODO: Need to be experimentally determined @@ -29,17 +30,22 @@ 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); float CalcAccPedalTravel(volatile const ECU_StateData *stateData); bool APPS_Plausible(volatile const ECU_StateData *stateData); +bool BSE_Implausible(volatile const ECU_StateData *stateData); bool vehicle_is_moving(volatile const ECU_StateData *stateData); #endif diff --git a/ECU/Application/Src/CANutils.c b/ECU/Application/Src/CANutils.c index a05d12ea5..e79133310 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, diff --git a/ECU/Application/Src/Lights.c b/ECU/Application/Src/Lights.c index 66eb5832e..128af5075 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 % 286 < 143) { + if (MillisecondsSinceBoot() % 286 < 143) { 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 0a7d949c8..6fe7919b3 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,35 @@ 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; + } + + static uint32_t last_bse_plausible_millis; + if (!BSE_Implausible(stateData)) { + last_bse_plausible_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 || millis_since_boot - last_bse_plausible_millis > MAX_BSE_FAILURE_TIME) { 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 +238,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 d88d3fff9..eee733bc2 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -49,13 +49,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 @@ -96,6 +89,16 @@ bool APPS_Plausible(volatile const ECU_StateData *stateData) return diviation < 0.1 && diviation > -0.1; } +bool BSE_Implausible(volatile const ECU_StateData *stateData) +{ + // checks for BSE signal failures --> > max failure time (100 ms) then result in apps/bse violation and kill motors + // T.4.3.3 + if (stateData->BSE_Signal < BSE_DEADZONE) { // TODO: fix deadzone l8r + return true; + } + return false; +} + bool vehicle_is_moving(volatile const ECU_StateData *stateData) { const float tolerance = 0.1; // In MPH diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 0ad5307fc..a208a3049 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -117,7 +117,7 @@ void read_digital(void) void write_adc_values_to_state_data() { // analog - // TODO: bse signal idk what to do ADC_outputs[0] + stateLump.BSE_Signal = ADC_outputs[0]; // TODO: bspd signal --> ADC_outputs[1], find use stateLump.APPS1_Signal = ADC_outputs[2]; stateLump.APPS2_Signal = ADC_outputs[3]; @@ -433,9 +433,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"); @@ -456,7 +458,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 000000000..f9ccecdc9 --- /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 940034ce1..1680aaf99 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;