diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index 086bd42546..44a2fcf0a1 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -91,7 +91,7 @@ public: /** * Desired timing advance */ - angle_t advance = NAN; + angle_t sparkAngle = NAN; floatms_t sparkDwell; /** * this timestamp allows us to measure actual dwell time diff --git a/firmware/controllers/trigger/spark_logic.cpp b/firmware/controllers/trigger/spark_logic.cpp index e0d0eb4ce4..6d73353a91 100644 --- a/firmware/controllers/trigger/spark_logic.cpp +++ b/firmware/controllers/trigger/spark_logic.cpp @@ -75,7 +75,7 @@ static void fireSparkBySettingPinLow(IgnitionEvent *event, IgnitionOutputPin *ou } \ } -static void prepareCylinderIgnitionSchedule(angle_t dwellAngle, floatms_t sparkDwell, IgnitionEvent *event DECLARE_ENGINE_PARAMETER_SUFFIX) { +static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_t sparkDwell, IgnitionEvent *event DECLARE_ENGINE_PARAMETER_SUFFIX) { // todo: clean up this implementation? does not look too nice as is. // let's save planned duration so that we can later compare it with reality @@ -84,11 +84,12 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngle, floatms_t sparkD // change of sign here from 'before TDC' to 'after TDC' angle_t ignitionPositionWithinEngineCycle = ENGINE(ignitionPositionWithinEngineCycle[event->cylinderIndex]); assertAngleRange(ignitionPositionWithinEngineCycle, "aPWEC", CUSTOM_ERR_6566); - cfg_float_t_1f timing_offset_cylinder = CONFIG(timing_offset_cylinder[event->cylinderIndex]); - const angle_t localAdvance = -ENGINE(engineState.timingAdvance) + ignitionPositionWithinEngineCycle + timing_offset_cylinder; - efiAssertVoid(CUSTOM_ERR_6689, !cisnan(localAdvance), "findAngle#9"); + // this correction is usually zero (not used) + cfg_float_t_1f perCylinderCorrection = CONFIG(timing_offset_cylinder[event->cylinderIndex]); + const angle_t sparkAngle = -ENGINE(engineState.timingAdvance) + ignitionPositionWithinEngineCycle + perCylinderCorrection; + efiAssertVoid(CUSTOM_ERR_6689, !cisnan(sparkAngle), "findAngle#9"); - efiAssertVoid(CUSTOM_ERR_6589, !cisnan(localAdvance), "localAdvance#1"); + efiAssertVoid(CUSTOM_ERR_6589, !cisnan(sparkAngle), "sparkAngle#1"); const int index = ENGINE(ignitionPin[event->cylinderIndex]); const int coilIndex = ID2INDEX(getCylinderId(index PASS_ENGINE_PARAMETER_SUFFIX)); IgnitionOutputPin *output = &enginePins.coils[coilIndex]; @@ -107,12 +108,12 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngle, floatms_t sparkD event->outputs[0] = output; event->outputs[1] = secondOutput; - event->advance = localAdvance; + event->sparkAngle = sparkAngle; - angle_t a = localAdvance - dwellAngle; - efiAssertVoid(CUSTOM_ERR_6590, !cisnan(a), "findAngle#5"); - assertAngleRange(a, "findAngle#a6", CUSTOM_ERR_6550); - TRIGGER_SHAPE(findTriggerPosition(&event->dwellPosition, a PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); + angle_t dwellStartAngle = sparkAngle - dwellAngleDuration; + efiAssertVoid(CUSTOM_ERR_6590, !cisnan(dwellStartAngle), "findAngle#5"); + assertAngleRange(dwellStartAngle, "findAngle#a6", CUSTOM_ERR_6550); + TRIGGER_SHAPE(findTriggerPosition(&event->dwellPosition, dwellStartAngle PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); #if FUEL_MATH_EXTREME_LOGGING printf("addIgnitionEvent %s ind=%d\n", output->name, event->dwellPosition.triggerEventIndex); @@ -156,13 +157,13 @@ if (engineConfiguration->debugMode == DBG_DWELL_METRIC) { #endif /* EFI_UNIT_TEST */ // now that we've just fired a coil let's prepare the new schedule for the next engine revolution - angle_t dwellAngle = ENGINE(engineState.dwellAngle); + angle_t dwellAngleDuration = ENGINE(engineState.dwellAngle); floatms_t sparkDwell = ENGINE(engineState.sparkDwell); - if (cisnan(dwellAngle) || cisnan(sparkDwell)) { + if (cisnan(dwellAngleDuration) || cisnan(sparkDwell)) { // we are here if engine has just stopped return; } - prepareCylinderIgnitionSchedule(dwellAngle, sparkDwell, event PASS_ENGINE_PARAMETER_SUFFIX); + prepareCylinderIgnitionSchedule(dwellAngleDuration, sparkDwell, event PASS_ENGINE_PARAMETER_SUFFIX); } static void startDwellByTurningSparkPinHigh(IgnitionEvent *event, IgnitionOutputPin *output) { @@ -223,8 +224,8 @@ static bool assertNotInIgnitionList(AngleBasedEvent *head, AngleBasedEvent *elem * @return true if event corresponds to current tooth and was time-based scheduler * false if event was put into queue for scheduling at a later tooth */ -static bool scheduleOrQueue(AngleBasedEvent *event, uint32_t trgEventIndex, angle_t advance, schfunc_t callback, void *param DECLARE_ENGINE_PARAMETER_SUFFIX) { - TRIGGER_SHAPE(findTriggerPosition(&event->position, advance PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); +static bool scheduleOrQueue(AngleBasedEvent *event, uint32_t trgEventIndex, angle_t angle, schfunc_t callback, void *param DECLARE_ENGINE_PARAMETER_SUFFIX) { + TRIGGER_SHAPE(findTriggerPosition(&event->position, angle PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); /** * todo: extract a "scheduleForAngle" method with best implementation into a separate utility method @@ -270,13 +271,13 @@ static bool scheduleOrQueue(AngleBasedEvent *event, uint32_t trgEventIndex, angl static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, IgnitionEvent *iEvent, int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) { - angle_t advance = iEvent->advance; + angle_t sparkAngle = iEvent->sparkAngle; const floatms_t dwellMs = ENGINE(engineState.sparkDwell); if (cisnan(dwellMs) || dwellMs <= 0) { warning(CUSTOM_DWELL, "invalid dwell to handle: %.2f at %d", dwellMs, rpm); return; } - if (cisnan(advance)) { + if (cisnan(sparkAngle)) { warning(CUSTOM_ERR_6688, "NaN advance"); return; } @@ -323,11 +324,11 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI * TODO: improve precision */ - efiAssertVoid(CUSTOM_ERR_6591, !cisnan(advance), "findAngle#4"); - assertAngleRange(advance, "findAngle#a5", CUSTOM_ERR_6549); + efiAssertVoid(CUSTOM_ERR_6591, !cisnan(sparkAngle), "findAngle#4"); + assertAngleRange(sparkAngle, "findAngle#a5", CUSTOM_ERR_6549); - bool scheduled = scheduleOrQueue(&iEvent->sparkEvent, trgEventIndex, advance, (schfunc_t)fireSparkAndPrepareNextSchedule, iEvent PASS_ENGINE_PARAMETER_SUFFIX); + bool scheduled = scheduleOrQueue(&iEvent->sparkEvent, trgEventIndex, sparkAngle, (schfunc_t)fireSparkAndPrepareNextSchedule, iEvent PASS_ENGINE_PARAMETER_SUFFIX); if (scheduled) { #if SPARK_EXTREME_LOGGING diff --git a/unit_tests/tests/test_ignition_scheduling.cpp b/unit_tests/tests/test_ignition_scheduling.cpp index 500c8297de..f2a9535f4f 100644 --- a/unit_tests/tests/test_ignition_scheduling.cpp +++ b/unit_tests/tests/test_ignition_scheduling.cpp @@ -26,14 +26,14 @@ TEST(ignition, twoCoils) { engine->engineState.timingAdvance = 0; initializeIgnitionActions(PASS_ENGINE_PARAMETER_SIGNATURE); - ASSERT_EQ(engine->ignitionEvents.elements[0].advance, 0); + ASSERT_EQ(engine->ignitionEvents.elements[0].sparkAngle, 0); ASSERT_EQ((void*)engine->ignitionEvents.elements[0].outputs[0], (void*)&enginePins.coils[0]); - ASSERT_EQ(engine->ignitionEvents.elements[1].advance, 720 / 12); + ASSERT_EQ(engine->ignitionEvents.elements[1].sparkAngle, 720 / 12); ASSERT_EQ((void*)engine->ignitionEvents.elements[1].outputs[0], (void*)&enginePins.coils[6]); - ASSERT_EQ(engine->ignitionEvents.elements[3].advance, 3 * 720 / 12); + ASSERT_EQ(engine->ignitionEvents.elements[3].sparkAngle, 3 * 720 / 12); ASSERT_EQ((void*)engine->ignitionEvents.elements[3].outputs[0], (void*)&enginePins.coils[6]);