diff --git a/firmware/controllers/algo/engine_parts.h b/firmware/controllers/algo/engine_parts.h index 03904e18b7..5c6d20a154 100644 --- a/firmware/controllers/algo/engine_parts.h +++ b/firmware/controllers/algo/engine_parts.h @@ -93,6 +93,7 @@ public: float mockRpm = 0; float mockCrankingRpm = 0; float mockTimeSinceBoot = 0; + float mockTimeSinceTrigger = 0; int mockAcToggle = 0; #endif diff --git a/firmware/controllers/core/fsio_core.h b/firmware/controllers/core/fsio_core.h index 495c44e422..e5186cdd09 100644 --- a/firmware/controllers/core/fsio_core.h +++ b/firmware/controllers/core/fsio_core.h @@ -56,7 +56,7 @@ typedef enum { LE_METHOD_FSIO_DIGITAL_INPUT = 123, LE_METHOD_FSIO_SETTING = 124, LE_METHOD_PPS = 125, - LE_METHOD_TIME_SINCE_TRIGGER_EVENT = 126, + LE_METHOD_TIME_SINCE_TRIGGER_EVENT = 127, #include "fsio_enums_generated.def" diff --git a/firmware/controllers/system/efi_gpio.cpp b/firmware/controllers/system/efi_gpio.cpp index cecf490754..0e240fcf86 100644 --- a/firmware/controllers/system/efi_gpio.cpp +++ b/firmware/controllers/system/efi_gpio.cpp @@ -537,11 +537,15 @@ void OutputPin::initPin(const char *msg, brain_pin_e brainPin, const pin_output_ this->currentLogicValue = 0; +#endif // briefly leave the include guard because we need to set default state in tests + // The order of the next two calls may look strange, which is a good observation. // We call them in this order so that the pin is set to a known state BEFORE // it's enabled. Enabling the pin then setting it could result in a (brief) // mystery state being driven on the pin (potentially dangerous). setDefaultPinState(outputMode); + +#if EFI_GPIO_HARDWARE && EFI_PROD_CODE efiSetPadMode(msg, brainPin, mode); if (brain_pin_is_onchip(brainPin)) { int actualValue = palReadPad(port, pin); diff --git a/firmware/controllers/system_fsio.h b/firmware/controllers/system_fsio.h index 2deef3456b..c17f44bc96 100644 --- a/firmware/controllers/system_fsio.h +++ b/firmware/controllers/system_fsio.h @@ -18,8 +18,8 @@ // Human-readable: (fan and (coolant > cfg_fanOffTemperature)) | (coolant > cfg_fanOnTemperature) | is_clt_broken #define FAN_CONTROL_LOGIC "fan coolant cfg_fanofftemperature > and coolant cfg_fanontemperature > | is_clt_broken |" -// Human-readable: ((time_since_boot >= 0) & (time_since_boot < startup_fuel_pump_duration)) | (rpm > 0) -#define FUEL_PUMP_LOGIC "time_since_boot 0 >= time_since_boot startup_fuel_pump_duration < & rpm 0 > |" +// Human-readable: ((time_since_boot >= 0) & (time_since_boot < startup_fuel_pump_duration)) | (time_since_trigger > 0) +#define FUEL_PUMP_LOGIC "time_since_boot 0 >= time_since_boot startup_fuel_pump_duration < & time_since_trigger 1 < |" // Human-readable: vbatt < 14.5 #define ALTERNATOR_LOGIC "vbatt 14.5 <" diff --git a/firmware/controllers/system_fsio.txt b/firmware/controllers/system_fsio.txt index c412cade89..f12e75fe23 100644 --- a/firmware/controllers/system_fsio.txt +++ b/firmware/controllers/system_fsio.txt @@ -18,7 +18,7 @@ FAN_CONTROL_LOGIC=(fan and (coolant > cfg_fanOffTemperature)) | (coolant > cfg_f # todo: 'time_since_boot' means 'getTimeIgnitionSeconds' in case of EFI_MAIN_RELAY_CONTROL like Proteus # and it's negative if ignition is off? does Proteus not get fuel pump start-up priming pulse?! # -FUEL_PUMP_LOGIC=((time_since_boot >= 0) & (time_since_boot < startup_fuel_pump_duration)) | (rpm > 0) +FUEL_PUMP_LOGIC=((time_since_boot >= 0) & (time_since_boot < startup_fuel_pump_duration)) | (time_since_trigger < 1) ALTERNATOR_LOGIC=vbatt < 14.5 diff --git a/unit_tests/efifeatures.h b/unit_tests/efifeatures.h index a37e6eb3ca..d59d187ce0 100644 --- a/unit_tests/efifeatures.h +++ b/unit_tests/efifeatures.h @@ -71,3 +71,5 @@ #define EFI_JOYSTICK FALSE #define EFI_MAP_AVERAGING TRUE + +#define EFI_FUEL_PUMP TRUE diff --git a/unit_tests/tests/test_logic_expression.cpp b/unit_tests/tests/test_logic_expression.cpp index fc7050ce47..2ad4bb3fdc 100644 --- a/unit_tests/tests/test_logic_expression.cpp +++ b/unit_tests/tests/test_logic_expression.cpp @@ -27,6 +27,10 @@ FsioValue getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) { return engine->fsioState.mockCrankingRpm; case LE_METHOD_TIME_SINCE_BOOT: return engine->fsioState.mockTimeSinceBoot; + case LE_METHOD_STARTUP_FUEL_PUMP_DURATION: + return 2.0f; + case LE_METHOD_TIME_SINCE_TRIGGER_EVENT: + return engine->fsioState.mockTimeSinceTrigger; case LE_METHOD_VBATT: return 12; case LE_METHOD_AC_TOGGLE: @@ -299,3 +303,41 @@ TEST(fsio, testLogicExpressions) { testExpression2(0, "rpm cranking_rpm > ", 1, engine); } } + +TEST(fsio, fuelPump) { + // this will init fuel pump fsio logic + WITH_ENGINE_TEST_HELPER(TEST_ENGINE); + + // Mock a fuel pump pin + CONFIG(fuelPumpPin) = GPIOA_0; + // Re-init so it picks up the new config + enginePins.fuelPumpRelay.init(PASS_ENGINE_PARAMETER_SIGNATURE); + + // ECU just started, haven't seen trigger yet + engine->fsioState.mockTimeSinceBoot = 0.5f; + engine->fsioState.mockTimeSinceTrigger = 100; + runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); + // Pump should be on! + EXPECT_TRUE(efiReadPin(GPIOA_0)); + + // Long time since ecu start, haven't seen trigger yet + engine->fsioState.mockTimeSinceBoot = 60; + engine->fsioState.mockTimeSinceTrigger = 100; + runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); + // Pump should be off! + EXPECT_FALSE(efiReadPin(GPIOA_0)); + + // Long time since ecu start, just saw a trigger! + engine->fsioState.mockTimeSinceBoot = 60; + engine->fsioState.mockTimeSinceTrigger = 0.1f; + runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); + // Pump should be on! + EXPECT_TRUE(efiReadPin(GPIOA_0)); + + // ECU just started, and we just saw a trigger! + engine->fsioState.mockTimeSinceBoot = 0.5f; + engine->fsioState.mockTimeSinceTrigger = 0.1f; + runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); + // Pump should be on! + EXPECT_TRUE(efiReadPin(GPIOA_0)); +}