diff --git a/firmware/controllers/algo/obd_error_codes.h b/firmware/controllers/algo/obd_error_codes.h index 8e8e34229d..5094c787ef 100644 --- a/firmware/controllers/algo/obd_error_codes.h +++ b/firmware/controllers/algo/obd_error_codes.h @@ -242,18 +242,18 @@ typedef enum { //P0199 Engine Oil Temperature Sensor Intermittent //DTC Codes - P0200-P0299 - Fuel and Air Metering (Injector Circuit) //P0200 Injector Circuit Malfunction - //P0201 Injector Circuit Malfunction - Cylinder 1 - //P0202 Injector Circuit Malfunction - Cylinder 2 - //P0203 Injector Circuit Malfunction - Cylinder 3 - //P0204 Injector Circuit Malfunction - Cylinder 4 - //P0205 Injector Circuit Malfunction - Cylinder 5 - //P0206 Injector Circuit Malfunction - Cylinder 6 - //P0207 Injector Circuit Malfunction - Cylinder 7 - //P0208 Injector Circuit Malfunction - Cylinder 8 - //P0209 Injector Circuit Malfunction - Cylinder 9 - //P0210 Injector Circuit Malfunction - Cylinder 10 - //P0211 Injector Circuit Malfunction - Cylinder 11 - //P0212 Injector Circuit Malfunction - Cylinder 12 + OBD_Injector_Circuit_1 = 201, + OBD_Injector_Circuit_2 = 202, + OBD_Injector_Circuit_3 = 203, + OBD_Injector_Circuit_4 = 204, + OBD_Injector_Circuit_5 = 205, + OBD_Injector_Circuit_6 = 206, + OBD_Injector_Circuit_7 = 207, + OBD_Injector_Circuit_8 = 208, + OBD_Injector_Circuit_9 = 209, + OBD_Injector_Circuit_10 = 210, + OBD_Injector_Circuit_11 = 211, + OBD_Injector_Circuit_12 = 212, //P0213 Cold Start Injector 1 Malfunction //P0214 Cold Start Injector 2 Malfunction //P0215 Engine Shutoff Solenoid Malfunction @@ -401,18 +401,18 @@ typedef enum { //P0348 Camshaft Position Sensor A Circuit High Input (Bank 2) //P0349 Camshaft Position Sensor A Circuit Intermittent (Bank 2) //P0350 Ignition Coil Primary/Secondary Circuit Malfunction - //P0351 Ignition Coil A Primary/Secondary Circuit Malfunction - //P0352 Ignition Coil B Primary/Secondary Circuit Malfunction - //P0353 Ignition Coil C Primary/Secondary Circuit Malfunction - //P0354 Ignition Coil D Primary/Secondary Circuit Malfunction - //P0355 Ignition Coil E Primary/Secondary Circuit Malfunction - //P0356 Ignition Coil F Primary/Secondary Circuit Malfunction - //P0357 Ignition Coil G Primary/Secondary Circuit Malfunction - //P0358 Ignition Coil H Primary/Secondary Circuit Malfunction - //P0359 Ignition Coil I Primary/Secondary Circuit Malfunction - //P0360 Ignition Coil J Primary/Secondary Circuit Malfunction - //P0361 Ignition Coil K Primary/Secondary Circuit Malfunction - //P0362 Ignition Coil L Primary/Secondary Circuit Malfunction + OBD_Ignition_Circuit_1 = 351, + OBD_Ignition_Circuit_2 = 352, + OBD_Ignition_Circuit_3 = 353, + OBD_Ignition_Circuit_4 = 354, + OBD_Ignition_Circuit_5 = 355, + OBD_Ignition_Circuit_6 = 356, + OBD_Ignition_Circuit_7 = 357, + OBD_Ignition_Circuit_8 = 358, + OBD_Ignition_Circuit_9 = 359, + OBD_Ignition_Circuit_10 = 360, + OBD_Ignition_Circuit_11 = 361, + OBD_Ignition_Circuit_12 = 362, //P0363 Misfire Detected - Fueling Disabled //P0364 Reserved //P0365 Camshaft Position Sensor "B" Circuit (Bank 1) diff --git a/firmware/controllers/bench_test.cpp b/firmware/controllers/bench_test.cpp index df9972da51..d4c7689701 100644 --- a/firmware/controllers/bench_test.cpp +++ b/firmware/controllers/bench_test.cpp @@ -37,7 +37,6 @@ #include "malfunction_central.h" #include "trigger_emulator_algo.h" #include "microsecond_timer.h" -#include "gpio_ext.h" #if EFI_WIDEBAND_FIRMWARE_UPDATE #include "rusefi_wideband.h" @@ -69,7 +68,7 @@ static char pin_error[64]; static void benchOff(OutputPin* output) { #if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0) - brain_pin_diag_e diag = gpiochips_getDiag(output->brainPin); + brain_pin_diag_e diag = output->getDiag(); if (diag == PIN_INVALID) { efiPrintf("No Diag on this pin"); } else { diff --git a/firmware/controllers/sensors/sensor_checker.cpp b/firmware/controllers/sensors/sensor_checker.cpp index 0ae52619c2..b32ac0df9c 100644 --- a/firmware/controllers/sensors/sensor_checker.cpp +++ b/firmware/controllers/sensors/sensor_checker.cpp @@ -121,6 +121,28 @@ static void check(SensorType type) { } } +static obd_code_e getCodeForInjector(int idx, brain_pin_diag_e diag) { + if (idx < 0 || idx >= 12) { + return OBD_None; + } + + // TODO: do something more intelligent with `diag`? + UNUSED(diag); + + return (obd_code_e)((int)OBD_Injector_Circuit_1 + idx); +} + +static obd_code_e getCodeForIgnition(int idx, brain_pin_diag_e diag) { + if (idx < 0 || idx >= 12) { + return OBD_None; + } + + // TODO: do something more intelligent with `diag`? + UNUSED(diag); + + return (obd_code_e)((int)OBD_Ignition_Circuit_1 + idx); +} + void SensorChecker::onSlowCallback() { // Don't check when the ignition is off, or when it was just turned on (let things stabilize) // TODO: also inhibit checking if we just did a flash burn, since that blocks the ECU for a few seconds. @@ -128,6 +150,7 @@ void SensorChecker::onSlowCallback() { return; } + // Check sensors check(SensorType::Tps1Primary); check(SensorType::Tps1Secondary); check(SensorType::Tps1); @@ -145,6 +168,47 @@ void SensorChecker::onSlowCallback() { check(SensorType::Iat); check(SensorType::FuelEthanolPercent); + +// only bother checking these if we have GPIO chips actually capable of reporting an error +#if BOARD_EXT_GPIOCHIPS > 0 && EFI_PROD_CODE + // Check injectors + for (int i = 0; i < efi::size(enginePins.injectors); i++) { + InjectorOutputPin& pin = enginePins.injectors[i]; + + // Skip not-configured pins + if (!isBrainPinValid(pin.brainPin)) { + continue; + } + + auto diag = pin.getDiag(); + if (diag != PIN_OK) { + auto code = getCodeForInjector(i + 1, diag); + + char description[32]; + pinDiag2string(description, efi::size(description), diag); + warning(code, "Injector %d fault: %s", i, description); + } + } + + // Check ignition + for (int i = 0; i < efi::size(enginePins.injectors); i++) { + IgnitionOutputPin& pin = enginePins.coils[i]; + + // Skip not-configured pins + if (!isBrainPinValid(pin.brainPin)) { + continue; + } + + auto diag = pin.getDiag(); + if (diag != PIN_OK) { + auto code = getCodeForIgnition(i + 1, diag); + + char description[32]; + pinDiag2string(description, efi::size(description), diag); + warning(code, "Ignition %d fault: %s", i, description); + } + } +#endif // BOARD_EXT_GPIOCHIPS > 0 } void SensorChecker::onIgnitionStateChanged(bool ignitionOn) { diff --git a/firmware/controllers/sensors/sensor_checker.h b/firmware/controllers/sensors/sensor_checker.h index d884a26f8c..1d93502658 100644 --- a/firmware/controllers/sensors/sensor_checker.h +++ b/firmware/controllers/sensors/sensor_checker.h @@ -1,5 +1,6 @@ #pragma once +// TODO: this name is now probably wrong, since it checks injectors/ignition too struct SensorChecker : public EngineModule { public: void onSlowCallback() override; diff --git a/firmware/controllers/system/efi_gpio.cpp b/firmware/controllers/system/efi_gpio.cpp index 23ce194668..7488af0a51 100644 --- a/firmware/controllers/system/efi_gpio.cpp +++ b/firmware/controllers/system/efi_gpio.cpp @@ -475,6 +475,14 @@ void OutputPin::setDefaultPinState(const pin_output_mode_e *outputMode) { setValue(false); // initial state } +brain_pin_diag_e OutputPin::getDiag() const { +#if BOARD_EXT_GPIOCHIPS > 0 + return gpiochips_getDiag(brainPin); +#else + return PIN_OK; +#endif +} + void initOutputPins() { #if EFI_GPIO_HARDWARE diff --git a/firmware/controllers/system/efi_gpio.h b/firmware/controllers/system/efi_gpio.h index 3db75fe24d..3ceb0962a6 100644 --- a/firmware/controllers/system/efi_gpio.h +++ b/firmware/controllers/system/efi_gpio.h @@ -60,6 +60,8 @@ public: void toggle(); bool getLogicValue() const; + brain_pin_diag_e getDiag() const; + #if EFI_GPIO_HARDWARE ioportid_t port = 0; uint8_t pin = 0;