diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index 6ac3ebe94..ece6e9844 100644 --- a/ECU/Application/Inc/StateData.h +++ b/ECU/Application/Inc/StateData.h @@ -54,6 +54,7 @@ typedef volatile struct ECU_StateData { float min_amk_heat_cap_throttle_percent; float ts_voltage; + float glv_voltage_20V; float max_cell_temp_c; /** Temperature of hottest cell, celsius */ float vehicle_speed_mph; /** Vehicle speed, MPH */ @@ -62,10 +63,8 @@ typedef volatile struct ECU_StateData { float rr_wheel_rpm; /** RRv wheel, RPM */ float rl_wheel_rpm; /** RL wheel, RPM */ - // 0.5V when things go to shit (X_OK low) (BAD) - // 3V when things almost poggers (X_OK high but SDC not reset) (BAD) - // 2.4V when things are actually poggers (X_OK high and SDC is not triggered) - float ams_sense; + + float bms_sense; float imd_sense; float bspd_sense; diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index 0be6ed429..34bcee8a6 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -69,8 +69,17 @@ uint32_t MillisecondsSinceBoot(void); */ #define RATE_LIMIT_10_HZ(x, y) (x - y > 100) +typedef enum { + SDC_OK, + SDC_ONGOING_FAILURE, + SDC_LATCHED_FAILURE +} SDC_Level; + // Checks stateData for critical errors bool CriticalError(volatile const ECU_StateData *stateData); +SDC_Level bmsLevel(volatile const ECU_StateData *stateData); +SDC_Level imdLevel(volatile const ECU_StateData *stateData); +SDC_Level bspdLevel(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); diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index 7e9b271af..6875b3d74 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -80,6 +80,7 @@ void ECU_CAN_MessageHandler(ECU_StateData *state_data, GRCAN_BUS_ID bus_id, GRCA state_data->ir_minus = GETBIT(acu_status_2->precharge_latch_flags, 4); state_data->ir_plus = GETBIT(acu_status_2->precharge_latch_flags, 5); state_data->acu_software_latch = GETBIT(acu_status_2->precharge_latch_flags, 6); + state_data->glv_voltage_20V = acu_status_2->_20v_voltage * 0.1f; break; case GRCAN_INV_STATUS_1: diff --git a/ECU/Application/Src/CANutils.c b/ECU/Application/Src/CANutils.c index 4f1a04898..ea78cffb6 100644 --- a/ECU/Application/Src/CANutils.c +++ b/ECU/Application/Src/CANutils.c @@ -130,7 +130,6 @@ void SendECUAnalogDataOverCAN(ECU_StateData *stateData) uint32_t millis_since_boot = MillisecondsSinceBoot(); static uint32_t last_can_tcm_request_millis = 0; - if (millis_since_boot - last_can_tcm_request_millis > 100) { GRCAN_ECU_ANALOG_DATA_MSG message = {.bspd_signal = stateData->bspd_signal, .bse_signal = stateData->bse_signal, diff --git a/ECU/Application/Src/Lights.c b/ECU/Application/Src/Lights.c index 12817b010..f12effd15 100644 --- a/ECU/Application/Src/Lights.c +++ b/ECU/Application/Src/Lights.c @@ -18,11 +18,35 @@ void BrakeLightControl(ECU_StateData *stateLump) } } +static bool SDCStartupCondition = true; // prevent false positive TSSI on startup +// PRECONDITION: IMD assumed to give valid readings before this is run void TSSILightControl(ECU_StateData *stateLump) { // EV.5.11.5: Flash, 2 Hz to 5 Hz, 50% duty cycle // Here we chose a period of 286ms - if (stateLump->tssi_fault) { + + bool redCar; + + // if we are before SDC is reset, don't red car unless there is an active failure + if (SDCStartupCondition) { + redCar = false; + + SDC_Level bms = bmsLevel(stateLump); + SDC_Level imd = imdLevel(stateLump); + + if (bms == SDC_OK && imd == SDC_OK) { + SDCStartupCondition = false; + } else if (bms == SDC_ONGOING_FAILURE || imd == SDC_ONGOING_FAILURE) { + SDCStartupCondition = false; + redCar = true; + } + } else { + redCar = bmsFailure(stateLump) || imdFailure(stateLump); + } + + + // if red car blink tssi + if (redCar) { LL_GPIO_ResetOutputPin(TSSI_G_CONTROL_GPIO_Port, TSSI_G_CONTROL_Pin); if (MillisecondsSinceBoot() % 286 < 143) { LL_GPIO_SetOutputPin(TSSI_R_CONTROL_GPIO_Port, TSSI_R_CONTROL_Pin); diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index 586dd056e..e3efbf94b 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -26,7 +26,7 @@ * @remark Intentionally not a globally accessible variable */ -ECU_StateData stateLump = {.ecu_state = GR_GLV_ON, .acu_software_latch = 1, .powerlevel = 3}; +ECU_StateData stateLump = {.ecu_state = GR_GLV_ON, .acu_software_latch = 1, .glv_voltage_20V = 20.0f, .powerlevel = 3}; static uint32_t millis_since_boot; void ECU_State_Tick(void) @@ -39,27 +39,6 @@ void ECU_State_Tick(void) last_ECU_status_msg_millis = millis_since_boot; } - // light control - // false or imd_sense > 0.5 -> false -> no light - // false or imd_sense < 0.5 -> true -> light - // true or imd_sense > 0.5 -> true -> light stays on - // stateLump.bms_light |= !(stateLump.ams_sense > 0.5f); - // stateLump.imd_light |= !(stateLump.imd_sense > 0.5f); - // lgoht control reset - - // true and no failiure -> flase - // true and failiure -> true - // false and failure -> false - // flase and no failure -> false - // stateLump.bms_light &= (bmsFailure(&stateLump)); - // stateLump.imd_light &= (imdFailure(&stateLump)); - - stateLump.bms_light = (stateLump.ams_sense <= 0.4f) || (stateLump.bms_light && bmsFailure(&stateLump)); - stateLump.imd_light = (stateLump.imd_sense <= 0.4f) || (stateLump.imd_light && imdFailure(&stateLump)); - - stateLump.tssi_fault = stateLump.bms_light || stateLump.imd_light; - - // bmsFailure(&stateLump) || imdFailure(&stateLump); if (stateLump.ts_active_button_press_interrupt) { stateLump.ts_active_button_press_interrupt = false; diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index efef6b4a0..260a52309 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -58,9 +58,43 @@ bool CriticalError(volatile const ECU_StateData *stateData) return problem; } +SDC_Level bmsLevel(volatile const ECU_StateData *stateData) { + // TODO: DYNAMIC LOGIC HERE + if (stateData->bms_sense < 0.2f) { + return SDC_ONGOING_FAILURE; + } else if (stateData->bms_sense > 1.6f) { + return SDC_LATCHED_FAILURE; + } + + return SDC_OK; +} + +SDC_Level imdLevel(volatile const ECU_StateData *stateData) { + // TODO: DYNAMIC LOGIC HERE + if (stateData->imd_sense < 0.2f) { + return SDC_ONGOING_FAILURE; + } else if (stateData->imd_sense > 1.6f) { + return SDC_LATCHED_FAILURE; + } + + return SDC_OK; +} + +SDC_Level bspdLevel(volatile const ECU_StateData *stateData) { + if (stateData->bspd_sense < 0.6f) { + return SDC_ONGOING_FAILURE; + } else if (stateData->bspd_sense > 1.35f) { + return SDC_LATCHED_FAILURE; + } + + return SDC_OK; +} + + bool bmsFailure(volatile const ECU_StateData *stateData) { - return stateData->ams_sense < 0.5f || stateData->ams_sense > 1.6f; // 0.5 to 1.6 is valid + SDC_Level level = bmsLevel(stateData); + return level == SDC_ONGOING_FAILURE || level == SDC_LATCHED_FAILURE; } bool imdFailure(volatile const ECU_StateData *stateData) @@ -71,16 +105,14 @@ bool imdFailure(volatile const ECU_StateData *stateData) return false; } - return stateData->imd_sense < 0.5f || stateData->imd_sense > 1.6f; // 0.5 to 1.6 is valid + SDC_Level level = imdLevel(stateData); + return level == SDC_ONGOING_FAILURE || level == SDC_LATCHED_FAILURE; } bool bspdFailure(volatile const ECU_StateData *stateData) { -#ifdef PLAN_C - return false; -#endif - - return stateData->bspd_sense < 0.6f || stateData->bspd_sense > 1.35f; // possible values are 0.3, 1.2, 1.6 + SDC_Level level = bspdLevel(stateData); + return level == SDC_ONGOING_FAILURE || level == SDC_LATCHED_FAILURE; } bool APPS_BSE_Violation(volatile const ECU_StateData *stateData) diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 8e9fc3bea..422752064 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -209,7 +209,7 @@ void write_adc_values_to_state_data(void) // TODO: determine conversion factors for all of these (uint to float) stateLump.bspd_sense = ADC_outputs[ADC_BUFFER_SENSE_BSPD] / 4095.0 * 3.3; stateLump.imd_sense = ADC_outputs[ADC_BUFFER_SENSE_IMD] / 4095.0 * 3.3; - stateLump.ams_sense = ADC_outputs[ADC_BUFFER_SENSE_AMS] / 4095.0 * 3.3; + stateLump.bms_sense = ADC_outputs[ADC_BUFFER_SENSE_AMS] / 4095.0 * 3.3; } void ADC_Configure(void) @@ -540,7 +540,7 @@ int main(void) // ADC_Logomatic(); } } - /* USER CODE END 3 */ +/* USER CODE END 3 */ } /**