diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 9a6038d7bc..b54a58bbb6 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -349,7 +349,7 @@ void Engine::reset() { /** * it's important for fixAngle() that engineCycle field never has zero */ - engineCycle = getEngineCycle(FOUR_STROKE_CRANK_SENSOR); + engineState.engineCycle = getEngineCycle(FOUR_STROKE_CRANK_SENSOR); memset(&ignitionPin, 0, sizeof(ignitionPin)); resetLua(); } diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 0fcaceb6b1..0e8ed2dcda 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -318,11 +318,6 @@ public: */ int globalConfigurationVersion = 0; - /** - * always 360 or 720, never zero - */ - angle_t engineCycle; - TpsAccelEnrichment tpsAccelEnrichment; #if EFI_SHAFT_POSITION_INPUT @@ -330,9 +325,6 @@ public: #endif // EFI_SHAFT_POSITION_INPUT - // Per-injection fuel mass, including TPS accel enrich - float injectionMass[MAX_CYLINDER_COUNT] = {0}; - float stftCorrection[STFT_BANK_COUNT] = {0}; diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index ad3bc26a35..11e026a6a2 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -179,7 +179,7 @@ void EngineState::periodicFastCallback() { auto cylinderTrim = getCylinderFuelTrim(i, rpm, fuelLoad); // Apply both per-bank and per-cylinder trims - engine->injectionMass[i] = injectionMass * bankTrim * cylinderTrim; + engine->engineState.injectionMass[i] = injectionMass * bankTrim * cylinderTrim; timingAdvance[i] = advance + getCylinderIgnitionTrim(i, rpm, ignitionLoad); } diff --git a/firmware/controllers/algo/engine_state.h b/firmware/controllers/algo/engine_state.h index 50fe06c017..93bb9ecce0 100644 --- a/firmware/controllers/algo/engine_state.h +++ b/firmware/controllers/algo/engine_state.h @@ -19,6 +19,14 @@ public: void updateSlowSensors(); void updateTChargeK(int rpm, float tps); + /** + * always 360 or 720, never zero + */ + angle_t engineCycle; + + // Per-injection fuel mass, including TPS accel enrich + float injectionMass[MAX_CYLINDER_COUNT] = {0}; + FuelConsumptionState fuelConsumption; Timer crankingTimer; diff --git a/firmware/controllers/engine_cycle/high_pressure_fuel_pump.cpp b/firmware/controllers/engine_cycle/high_pressure_fuel_pump.cpp index 705cf33d0a..47f1098735 100644 --- a/firmware/controllers/engine_cycle/high_pressure_fuel_pump.cpp +++ b/firmware/controllers/engine_cycle/high_pressure_fuel_pump.cpp @@ -70,7 +70,7 @@ angle_t HpfpLobe::findNextLobe() { // As a percent of the full pump stroke float HpfpQuantity::calcFuelPercent(int rpm) { float fuel_requested_cc_per_cycle = - engine->injectionMass[0] * (1.f / fuelDensity) * engineConfiguration->specs.cylindersCount; + engine->engineState.injectionMass[0] * (1.f / fuelDensity) * engineConfiguration->specs.cylindersCount; float fuel_requested_cc_per_lobe = fuel_requested_cc_per_cycle / engineConfiguration->hpfpCamLobes; return 100.f * fuel_requested_cc_per_lobe / engineConfiguration->hpfpPumpVolume + diff --git a/firmware/controllers/engine_cycle/main_trigger_callback.cpp b/firmware/controllers/engine_cycle/main_trigger_callback.cpp index 4840935a8f..a169736b70 100644 --- a/firmware/controllers/engine_cycle/main_trigger_callback.cpp +++ b/firmware/controllers/engine_cycle/main_trigger_callback.cpp @@ -180,7 +180,7 @@ void InjectionEvent::onTriggerTooth(int rpm, efitick_t nowNt, float currentPhase } // Select fuel mass from the correct cylinder - auto injectionMassGrams = engine->injectionMass[this->cylinderNumber]; + auto injectionMassGrams = engine->engineState.injectionMass[this->cylinderNumber]; // Perform wall wetting adjustment on fuel mass, not duration, so that // it's correct during fuel pressure (injector flow) or battery voltage (deadtime) transients @@ -279,7 +279,7 @@ void InjectionEvent::onTriggerTooth(int rpm, efitick_t nowNt, float currentPhase float angleFromNow = eventAngle - currentPhase; if (angleFromNow < 0) { - angleFromNow += engine->engineCycle; + angleFromNow += engine->engineState.engineCycle; } efitick_t startTime = scheduleByAngle(&signalTimerUp, nowNt, angleFromNow, startAction); diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index fc206aa72c..fd0d1af5d9 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -434,7 +434,7 @@ ignition_mode_e getCurrentIgnitionMode() { * This heavy method is only invoked in case of a configuration change or initialization. */ void prepareOutputSignals() { - engine->engineCycle = getEngineCycle(engine->getOperationMode()); + engine->engineState.engineCycle = getEngineCycle(engine->getOperationMode()); angle_t maxTimingCorrMap = -FOUR_STROKE_CYCLE_DURATION; angle_t maxTimingMap = -FOUR_STROKE_CYCLE_DURATION; @@ -463,7 +463,7 @@ void prepareOutputSignals() { angle_t getCylinderAngle(uint8_t cylinderIndex, uint8_t cylinderNumber) { // base = position of this cylinder in the firing order. // We get a cylinder every n-th of an engine cycle where N is the number of cylinders - auto base = engine->engineCycle * cylinderIndex / engineConfiguration->specs.cylindersCount; + auto base = engine->engineState.engineCycle * cylinderIndex / engineConfiguration->specs.cylindersCount; // Plus or minus any adjustment if this is an odd-fire engine auto adjustment = engineConfiguration->timing_offset_cylinder[cylinderNumber]; diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index 405d98dcbe..8f7db59a6e 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -18,7 +18,7 @@ void setFlatInjectorLag(float value); * TODO: replace all usages of fixAngle with wrapAngle? * Should we make this a nice method instead of that off macro which changes parameter value? */ -#define fixAngle(angle, msg, code) wrapAngle2(angle, msg, code, engine->engineCycle) +#define fixAngle(angle, msg, code) wrapAngle2(angle, msg, code, engine->engineState.engineCycle) #define wrapAngle(angle, msg, code) fixAngle(angle, msg, code) // proper method avoids un-wrapped state of variables diff --git a/unit_tests/tests/ignition_injection/test_fuel_math.cpp b/unit_tests/tests/ignition_injection/test_fuel_math.cpp index 4e291bfc9f..e3b134518a 100644 --- a/unit_tests/tests/ignition_injection/test_fuel_math.cpp +++ b/unit_tests/tests/ignition_injection/test_fuel_math.cpp @@ -226,10 +226,10 @@ TEST(FuelMath, CylinderFuelTrim) { // Check that each cylinder gets the expected amount of fuel float unadjusted = 0.072142f; - EXPECT_NEAR(engine->injectionMass[0], unadjusted * 0.96, EPS4D); - EXPECT_NEAR(engine->injectionMass[1], unadjusted * 0.98, EPS4D); - EXPECT_NEAR(engine->injectionMass[2], unadjusted * 1.02, EPS4D); - EXPECT_NEAR(engine->injectionMass[3], unadjusted * 1.04, EPS4D); + EXPECT_NEAR(engine->engineState.injectionMass[0], unadjusted * 0.96, EPS4D); + EXPECT_NEAR(engine->engineState.injectionMass[1], unadjusted * 0.98, EPS4D); + EXPECT_NEAR(engine->engineState.injectionMass[2], unadjusted * 1.02, EPS4D); + EXPECT_NEAR(engine->engineState.injectionMass[3], unadjusted * 1.04, EPS4D); } struct MockIdle : public MockIdleController { diff --git a/unit_tests/tests/test_hpfp.cpp b/unit_tests/tests/test_hpfp.cpp index 35e1593b88..9a30d4ad2e 100755 --- a/unit_tests/tests/test_hpfp.cpp +++ b/unit_tests/tests/test_hpfp.cpp @@ -55,7 +55,7 @@ TEST(HPFP, InjectionReplacementFuel) { engineConfiguration->specs.cylindersCount = 4; engineConfiguration->hpfpCamLobes = 4; - engine->injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe HpfpQuantity math; @@ -67,7 +67,7 @@ TEST(HPFP, InjectionReplacementFuel) { EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 25 * 1.333333333f); // More fuel! - engine->injectionMass[0] = 0.1 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.1 /* cc/cyl */ * fuelDensity; EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 50 * 1.333333333f); // More cylinders! @@ -97,7 +97,7 @@ TEST(HPFP, InjectionReplacementFuel) { EXPECT_FLOAT_EQ(math.calcFuelPercent(2000), 50); // +0, in next cell // 25% more fuel (1.25*50=62.5 base), but half way between comp of 20 and 0 (so comp of 10) - engine->injectionMass[0] = 0.125 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.125 /* cc/cyl */ * fuelDensity; EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 72.5); // +10 comp EXPECT_FLOAT_EQ(math.calcFuelPercent(1500), 67.5); // +5, half way EXPECT_FLOAT_EQ(math.calcFuelPercent(2000), 62.5); // +0 base @@ -108,7 +108,7 @@ TEST(HPFP, PI) { engineConfiguration->specs.cylindersCount = 4; engineConfiguration->hpfpCamLobes = 4; - engine->injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe HpfpQuantity math; @@ -165,7 +165,7 @@ TEST(HPFP, Angle) { engineConfiguration->specs.cylindersCount = 4; engineConfiguration->hpfpCamLobes = 4; - engine->injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe HpfpQuantity math; @@ -194,7 +194,7 @@ TEST(HPFP, Angle) { EXPECT_FLOAT_EQ(math.calcPI(1000, 10), 0); // Validate no PI EXPECT_NEAR(math.pumpAngleFuel(1000, &model), 37.5, 0.4); // Given the profile, should be 50% higher - engine->injectionMass[0] = 0.08 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.08 /* cc/cyl */ * fuelDensity; EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 40); // Double check baseline EXPECT_FLOAT_EQ(math.calcPI(1000, 10), 0); // Validate no PI EXPECT_NEAR(math.pumpAngleFuel(1000, &model), 60, 0.4); // Given the profile, should be 50% higher @@ -267,7 +267,7 @@ TEST(HPFP, Schedule) { engineConfiguration->hpfpPeakPos = 90; // This will call the fast callback routine engine->rpmCalculator.setRpmValue(1000); - engine->injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; + engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; engineConfiguration->hpfpValvePin = Gpio::A2; // arbitrary hpfp.onFastCallback(); diff --git a/unit_tests/tests/trigger/test_trigger_decoder.cpp b/unit_tests/tests/trigger/test_trigger_decoder.cpp index 38b410be15..f998b77b1a 100644 --- a/unit_tests/tests/trigger/test_trigger_decoder.cpp +++ b/unit_tests/tests/trigger/test_trigger_decoder.cpp @@ -266,7 +266,7 @@ TEST(misc, testRpmCalculator) { IgnitionEventList *ilist = &engine->ignitionEvents; ASSERT_EQ( 0, ilist->isReady) << "size #1"; - ASSERT_EQ( 720, engine->engineCycle) << "engineCycle"; + ASSERT_EQ( 720, engine->engineState.engineCycle) << "engineCycle"; efiAssertVoid(CUSTOM_ERR_6670, engineConfiguration!=NULL, "null config in engine");