diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index d3bca297cf..ce29c06ac4 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -175,6 +175,8 @@ void EngineState::periodicFastCallback() { timingAdvance[i] = correctedIgnitionAdvance + getCombinedCylinderIgnitionTrim(i, rpm, ignitionLoad); } + shouldUpdateInjectionTiming = getInjectorDutyCycle(rpm) < 90; + // TODO: calculate me from a table! trailingSparkAngle = engineConfiguration->trailingSparkAngle; diff --git a/firmware/controllers/algo/engine_state.h b/firmware/controllers/algo/engine_state.h index 6efd352617..d472a267cb 100644 --- a/firmware/controllers/algo/engine_state.h +++ b/firmware/controllers/algo/engine_state.h @@ -81,6 +81,7 @@ public: multispark_state multispark; + bool shouldUpdateInjectionTiming = true; }; EngineState * getEngineState(); diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index 7158e85805..e91ce56f15 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -276,10 +276,6 @@ float getInjectionModeDurationMultiplier() { } } -/** - * This is more like MOSFET duty cycle since durations include injector lag - * @see getCoilDutyCycle - */ percent_t getInjectorDutyCycle(int rpm) { floatms_t totalInjectiorAmountPerCycle = engine->engineState.injectionDuration * getNumberOfInjections(engineConfiguration->injectionMode); floatms_t engineCycleDuration = getEngineCycleDuration(rpm); diff --git a/firmware/controllers/engine_cycle/fuel_schedule.cpp b/firmware/controllers/engine_cycle/fuel_schedule.cpp index 3a10e6b49d..ddd8a6e72e 100644 --- a/firmware/controllers/engine_cycle/fuel_schedule.cpp +++ b/firmware/controllers/engine_cycle/fuel_schedule.cpp @@ -105,7 +105,12 @@ bool InjectionEvent::updateInjectionAngle(int cylinderIndex) { auto result = computeInjectionAngle(cylinderIndex); if (result) { - injectionStartAngle = result.Value; + // If injector duty cycle is high, lock injection SOI so that we + // don't miss injections at or above 100% duty + if (getEngineState()->shouldUpdateInjectionTiming) { + injectionStartAngle = result.Value; + } + return true; } else { return false;