diff --git a/firmware/controllers/algo/event_registry.cpp b/firmware/controllers/algo/event_registry.cpp index 6a4727f184..7746fb9ca0 100644 --- a/firmware/controllers/algo/event_registry.cpp +++ b/firmware/controllers/algo/event_registry.cpp @@ -25,8 +25,6 @@ #include "engine_math.h" InjectionEvent::InjectionEvent() { - isSimultanious = false; - ownIndex = 0; memset(outputs, 0, sizeof(outputs)); } diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index 0561933748..b483208fc1 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -22,13 +22,17 @@ class Engine; class InjectionEvent { public: InjectionEvent(); + + // Call this every decoded trigger tooth. It will schedule any relevant events for this injector. + void onTriggerTooth(size_t toothIndex, int rpm, efitick_t nowNt); + /** * This is a performance optimization for IM_SIMULTANEOUS fuel strategy. * It's more efficient to handle all injectors together if that's the case */ - bool isSimultanious; + bool isSimultanious = false; InjectorOutputPin *outputs[MAX_WIRES_COUNT]; - int ownIndex; + int ownIndex = 0; DECLARE_ENGINE_PTR; event_trigger_position_s injectionStart; @@ -47,13 +51,16 @@ public: WallFuel wallFuel; }; - /** * This class knows about when to inject fuel */ class FuelSchedule { public: FuelSchedule(); + + // Call this every trigger tooth. It will schedule all required injector events. + void onTriggerTooth(size_t toothIndex, int rpm, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX); + /** * this method schedules all fuel events for an engine cycle */ diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 44ba571980..4fb3a605ee 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -34,6 +34,7 @@ CONTROLLERS_SRC_CPP = \ $(CONTROLLERS_DIR)/engine_cycle/spark_logic.cpp \ $(CONTROLLERS_DIR)/engine_cycle/main_trigger_callback.cpp \ $(CONTROLLERS_DIR)/engine_cycle/aux_valves.cpp \ + $(CONTROLLERS_DIR)/engine_cycle/fuel_schedule.cpp \ $(CONTROLLERS_DIR)/flash_main.cpp \ $(CONTROLLERS_DIR)/bench_test.cpp \ $(CONTROLLERS_DIR)/can/obd2.cpp \ diff --git a/firmware/controllers/engine_cycle/fuel_schedule.cpp b/firmware/controllers/engine_cycle/fuel_schedule.cpp new file mode 100644 index 0000000000..335f356d91 --- /dev/null +++ b/firmware/controllers/engine_cycle/fuel_schedule.cpp @@ -0,0 +1,163 @@ +/** + * @file fuel_schedule.cpp + * + * Handles injection scheduling + */ + +#include "global.h" +#include "engine.h" +#include "engine_math.h" +#include "event_registry.h" + +EXTERN_ENGINE; + +#if EFI_ENGINE_CONTROL + +FuelSchedule::FuelSchedule() { + clear(); + for (int cylinderIndex = 0; cylinderIndex < MAX_INJECTION_OUTPUT_COUNT; cylinderIndex++) { + InjectionEvent *ev = &elements[cylinderIndex]; + ev->ownIndex = cylinderIndex; + } +} + +void FuelSchedule::clear() { + isReady = false; +} + +void FuelSchedule::resetOverlapping() { + for (size_t i = 0; i < efi::size(enginePins.injectors); i++) { + enginePins.injectors[i].reset(); + } +} + +/** + * @returns false in case of error, true if success + */ +bool FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFFIX) { + efiAssert(CUSTOM_ERR_ASSERT, engine!=NULL, "engine is NULL", false); + + floatus_t oneDegreeUs = ENGINE(rpmCalculator.oneDegreeUs); // local copy + if (cisnan(oneDegreeUs)) { + // in order to have fuel schedule we need to have current RPM + // wonder if this line slows engine startup? + return false; + } + + /** + * injection phase is scheduled by injection end, so we need to step the angle back + * for the duration of the injection + * + * todo: since this method is not invoked within trigger event handler and + * engineState.injectionOffset is calculated from the same utility timer should we more that logic here? + */ + floatms_t fuelMs = ENGINE(injectionDuration); + efiAssert(CUSTOM_ERR_ASSERT, !cisnan(fuelMs), "NaN fuelMs", false); + angle_t injectionDuration = MS2US(fuelMs) / oneDegreeUs; + efiAssert(CUSTOM_ERR_ASSERT, !cisnan(injectionDuration), "NaN injectionDuration", false); + assertAngleRange(injectionDuration, "injectionDuration_r", CUSTOM_INJ_DURATION); + floatus_t injectionOffset = ENGINE(engineState.injectionOffset); + if (cisnan(injectionOffset)) { + // injection offset map not ready - we are not ready to schedule fuel events + return false; + } + angle_t baseAngle = injectionOffset - injectionDuration; + efiAssert(CUSTOM_ERR_ASSERT, !cisnan(baseAngle), "NaN baseAngle", false); + assertAngleRange(baseAngle, "baseAngle_r", CUSTOM_ERR_6554); + + injection_mode_e mode = engine->getCurrentInjectionMode(PASS_ENGINE_PARAMETER_SIGNATURE); + + int injectorIndex; + if (mode == IM_SIMULTANEOUS || mode == IM_SINGLE_POINT) { + // These modes only have one injector + injectorIndex = 0; + } else if (mode == IM_SEQUENTIAL || (mode == IM_BATCH && CONFIG(twoWireBatchInjection))) { + // Map order index -> cylinder index (firing order) + injectorIndex = getCylinderId(i PASS_ENGINE_PARAMETER_SUFFIX) - 1; + } else if (mode == IM_BATCH) { + // Loop over the first half of the firing order twice + injectorIndex = i % (engineConfiguration->specs.cylindersCount / 2); + } else { + firmwareError(CUSTOM_OBD_UNEXPECTED_INJECTION_MODE, "Unexpected injection mode %d", mode); + injectorIndex = 0; + } + + assertAngleRange(baseAngle, "addFbaseAngle", CUSTOM_ADD_BASE); + + int cylindersCount = CONFIG(specs.cylindersCount); + if (cylindersCount < 1) { + // May 2020 this somehow still happens with functional tests, maybe race condition? + warning(CUSTOM_OBD_ZERO_CYLINDER_COUNT, "Invalid cylinder count: %d", cylindersCount); + return false; + } + + float angle = baseAngle + + i * ENGINE(engineCycle) / cylindersCount; + + InjectorOutputPin *secondOutput; + if (mode == IM_BATCH && CONFIG(twoWireBatchInjection)) { + /** + * also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires + */ + // Compute the position of this cylinder's twin in the firing order + // Each injector gets fired as a primary (the same as sequential), but also + // fires the injector 360 degrees later in the firing order. + int secondOrder = (i + (CONFIG(specs.cylindersCount) / 2)) % CONFIG(specs.cylindersCount); + int secondIndex = getCylinderId(secondOrder PASS_ENGINE_PARAMETER_SUFFIX) - 1; + secondOutput = &enginePins.injectors[secondIndex]; + } else { + secondOutput = nullptr; + } + + InjectorOutputPin *output = &enginePins.injectors[injectorIndex]; + bool isSimultanious = mode == IM_SIMULTANEOUS; + + if (!isSimultanious && !output->isInitialized()) { + // todo: extract method for this index math + warning(CUSTOM_OBD_INJECTION_NO_PIN_ASSIGNED, "no_pin_inj #%s", output->name); + } + + InjectionEvent *ev = &elements[i]; + ev->ownIndex = i; + INJECT_ENGINE_REFERENCE(ev); + fixAngle(angle, "addFuel#1", CUSTOM_ERR_6554); + + ev->outputs[0] = output; + ev->outputs[1] = secondOutput; + + ev->isSimultanious = isSimultanious; + + if (TRIGGER_WAVEFORM(getSize()) < 1) { + warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform"); + return false; + } + + efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "findAngle#3", false); + assertAngleRange(angle, "findAngle#a33", CUSTOM_ERR_6544); + ev->injectionStart.setAngle(angle PASS_ENGINE_PARAMETER_SUFFIX); +#if EFI_UNIT_TEST + printf("registerInjectionEvent angle=%.2f trgIndex=%d inj %d\r\n", angle, ev->injectionStart.triggerEventIndex, injectorIndex); +#endif + return true; +} + +void FuelSchedule::addFuelEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + clear(); + + for (int cylinderIndex = 0; cylinderIndex < CONFIG(specs.cylindersCount); cylinderIndex++) { + InjectionEvent *ev = &elements[cylinderIndex]; + ev->ownIndex = cylinderIndex; // todo: is this assignment needed here? we now initialize in constructor + bool result = addFuelEventsForCylinder(cylinderIndex PASS_ENGINE_PARAMETER_SUFFIX); + if (!result) + return; + } + isReady = true; +} + +void FuelSchedule::onTriggerTooth(size_t toothIndex, int rpm, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { + for (int i = 0; i < CONFIG(specs.cylindersCount); i++) { + elements[i].onTriggerTooth(toothIndex, rpm, nowNt); + } +} + +#endif diff --git a/firmware/controllers/engine_cycle/main_trigger_callback.cpp b/firmware/controllers/engine_cycle/main_trigger_callback.cpp index ba97235b4a..08f624300c 100644 --- a/firmware/controllers/engine_cycle/main_trigger_callback.cpp +++ b/firmware/controllers/engine_cycle/main_trigger_callback.cpp @@ -187,9 +187,13 @@ void turnInjectionPinLow(InjectionEvent *event) { ENGINE(injectionEvents.addFuelEventsForCylinder(event->ownIndex PASS_ENGINE_PARAMETER_SUFFIX)); } -// todo: rename to 'scheduleInjectorOpenAndClose'? -void handleFuelInjectionEvent(int injEventIndex, InjectionEvent *event, - int rpm, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { +void InjectionEvent::onTriggerTooth(size_t trgEventIndex, int rpm, efitick_t nowNt) { + uint32_t eventIndex = injectionStart.triggerEventIndex; +// right after trigger change we are still using old & invalid fuel schedule. good news is we do not change trigger on the fly in real life +// efiAssertVoid(CUSTOM_ERR_ASSERT_VOID, eventIndex < ENGINE(triggerShape.getLength()), "handleFuel/event sch index"); + if (eventIndex != trgEventIndex) { + return; + } /** * todo: this is a bit tricky with batched injection. is it? Does the same @@ -197,11 +201,11 @@ void handleFuelInjectionEvent(int injEventIndex, InjectionEvent *event, * x2 or /2? */ - const floatms_t injectionDuration = event->wallFuel.adjust(ENGINE(injectionDuration) PASS_ENGINE_PARAMETER_SUFFIX); + const floatms_t injectionDuration = wallFuel.adjust(ENGINE(injectionDuration) PASS_ENGINE_PARAMETER_SUFFIX); #if EFI_PRINTF_FUEL_DETAILS if (printFuelDebug) { printf("fuel index=%d injectionDuration=%.2fms adjusted=%.2fms\n", - injEventIndex, + eventIndex, ENGINE(injectionDuration), injectionDuration); } @@ -245,7 +249,7 @@ void handleFuelInjectionEvent(int injEventIndex, InjectionEvent *event, // we are ignoring low RPM in order not to handle "engine was stopped to engine now running" transition if (rpm > 2 * engineConfiguration->cranking.rpm) { - const char *outputName = event->outputs[0]->name; + const char *outputName = outputs[0]->name; if (prevOutputName == outputName && engineConfiguration->injectionMode != IM_SIMULTANEOUS && engineConfiguration->injectionMode != IM_SINGLE_POINT) { @@ -256,48 +260,48 @@ void handleFuelInjectionEvent(int injEventIndex, InjectionEvent *event, #if EFI_PRINTF_FUEL_DETAILS if (printFuelDebug) { - InjectorOutputPin *output = event->outputs[0]; + InjectorOutputPin *output = outputs[0]; printf("handleFuelInjectionEvent fuelout %s injection_duration %dus engineCycleDuration=%.1fms\t\n", output->name, (int)durationUs, (int)MS2US(getCrankshaftRevolutionTimeMs(GET_RPM_VALUE)) / 1000.0); } #endif /*EFI_PRINTF_FUEL_DETAILS */ - if (event->isScheduled) { + if (isScheduled) { #if EFI_PRINTF_FUEL_DETAILS if (printFuelDebug) { - InjectorOutputPin *output = event->outputs[0]; + InjectorOutputPin *output = outputs[0]; printf("handleFuelInjectionEvent still used %s now=%.1fms\r\n", output->name, (int)getTimeNowUs() / 1000.0); } #endif /*EFI_PRINTF_FUEL_DETAILS */ return; // this InjectionEvent is still needed for an extremely long injection scheduled previously } - event->isScheduled = true; + isScheduled = true; action_s startAction, endAction; // We use different callbacks based on whether we're running sequential mode or not - everything else is the same - if (event->isSimultanious) { + if (isSimultanious) { startAction = { &startSimultaniousInjection, engine }; - endAction = { &endSimultaniousInjection, event }; + endAction = { &endSimultaniousInjection, this }; } else { // sequential or batch - startAction = { &turnInjectionPinHigh, event }; - endAction = { &turnInjectionPinLow, event }; + startAction = { &turnInjectionPinHigh, this }; + endAction = { &turnInjectionPinLow, this }; } - efitick_t startTime = scheduleByAngle(&event->signalTimerUp, nowNt, event->injectionStart.angleOffsetFromTriggerEvent, startAction PASS_ENGINE_PARAMETER_SUFFIX); + efitick_t startTime = scheduleByAngle(&signalTimerUp, nowNt, injectionStart.angleOffsetFromTriggerEvent, startAction PASS_ENGINE_PARAMETER_SUFFIX); efitick_t turnOffTime = startTime + US2NT((int)durationUs); - engine->executor.scheduleByTimestampNt(&event->endOfInjectionEvent, turnOffTime, endAction); + engine->executor.scheduleByTimestampNt(&endOfInjectionEvent, turnOffTime, endAction); #if EFI_UNIT_TEST - printf("scheduling injection angle=%.2f/delay=%.2f injectionDuration=%.2f\r\n", event->injectionStart.angleOffsetFromTriggerEvent, NT2US(startTime - nowNt), injectionDuration); + printf("scheduling injection angle=%.2f/delay=%.2f injectionDuration=%.2f\r\n", injectionStart.angleOffsetFromTriggerEvent, NT2US(startTime - nowNt), injectionDuration); #endif #if EFI_DEFAILED_LOGGING - scheduleMsg(logger, "handleFuel pin=%s eventIndex %d duration=%.2fms %d", event->outputs[0]->name, + scheduleMsg(logger, "handleFuel pin=%s eventIndex %d duration=%.2fms %d", outputs[0]->name, injEventIndex, injectionDuration, getRevolutionCounter()); - scheduleMsg(logger, "handleFuel pin=%s delay=%.2f %d", event->outputs[0]->name, NT2US(startTime - nowNt), + scheduleMsg(logger, "handleFuel pin=%s delay=%.2f %d", outputs[0]->name, NT2US(startTime - nowNt), getRevolutionCounter()); #endif /* EFI_DEFAILED_LOGGING */ } @@ -322,7 +326,7 @@ static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIn } /** - * Ignition events are defined by addFuelEvents() according to selected + * Injection events are defined by addFuelEvents() according to selected * fueling strategy */ FuelSchedule *fs = &ENGINE(injectionEvents); @@ -342,16 +346,7 @@ static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIn ENGINE(engineLoadAccelEnrichment.onEngineCycle(PASS_ENGINE_PARAMETER_SIGNATURE)); } - for (int injEventIndex = 0; injEventIndex < CONFIG(specs.cylindersCount); injEventIndex++) { - InjectionEvent *event = &fs->elements[injEventIndex]; - uint32_t eventIndex = event->injectionStart.triggerEventIndex; -// right after trigger change we are still using old & invalid fuel schedule. good news is we do not change trigger on the fly in real life -// efiAssertVoid(CUSTOM_ERR_ASSERT_VOID, eventIndex < ENGINE(triggerShape.getLength()), "handleFuel/event sch index"); - if (eventIndex != trgEventIndex) { - continue; - } - handleFuelInjectionEvent(injEventIndex, event, rpm, nowNt PASS_ENGINE_PARAMETER_SUFFIX); - } + fs->onTriggerTooth(trgEventIndex, rpm, nowNt PASS_ENGINE_PARAMETER_SUFFIX); } #if EFI_PROD_CODE @@ -473,6 +468,8 @@ static bool isPrimeInjectionPulseSkipped(DECLARE_ENGINE_PARAMETER_SIGNATURE) { * See testStartOfCrankingPrimingPulse() */ void startPrimeInjectionPulse(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + INJECT_ENGINE_REFERENCE(&primeInjEvent); + // First, we need a protection against 'fake' ignition switch on and off (i.e. no engine started), to avoid repeated prime pulses. // So we check and update the ignition switch counter in non-volatile backup-RAM #if EFI_PROD_CODE @@ -490,10 +487,6 @@ void startPrimeInjectionPulse(DECLARE_ENGINE_PARAMETER_SIGNATURE) { ignSwitchCounter = -1; // start prime injection if this is a 'fresh start' if (ignSwitchCounter == 0) { - // fill-in the prime event struct -#if EFI_UNIT_TEST - primeInjEvent.engine = engine; -#endif /* EFI_UNIT_TEST */ primeInjEvent.ownIndex = 0; primeInjEvent.isSimultanious = true; diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 6c8a3b5648..7021cba6aa 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -103,151 +103,6 @@ void setSingleCoilDwell(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->sparkDwellValues[7] = 0; } -#if EFI_ENGINE_CONTROL - -FuelSchedule::FuelSchedule() { - clear(); - for (int cylinderIndex = 0; cylinderIndex < MAX_INJECTION_OUTPUT_COUNT; cylinderIndex++) { - InjectionEvent *ev = &elements[cylinderIndex]; - ev->ownIndex = cylinderIndex; - } -} - -void FuelSchedule::clear() { - isReady = false; -} - -void FuelSchedule::resetOverlapping() { - for (size_t i = 0; i < efi::size(enginePins.injectors); i++) { - enginePins.injectors[i].reset(); - } -} - -/** - * @returns false in case of error, true if success - */ -bool FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFFIX) { - efiAssert(CUSTOM_ERR_ASSERT, engine!=NULL, "engine is NULL", false); - - floatus_t oneDegreeUs = ENGINE(rpmCalculator.oneDegreeUs); // local copy - if (cisnan(oneDegreeUs)) { - // in order to have fuel schedule we need to have current RPM - // wonder if this line slows engine startup? - return false; - } - - /** - * injection phase is scheduled by injection end, so we need to step the angle back - * for the duration of the injection - * - * todo: since this method is not invoked within trigger event handler and - * engineState.injectionOffset is calculated from the same utility timer should we more that logic here? - */ - floatms_t fuelMs = ENGINE(injectionDuration); - efiAssert(CUSTOM_ERR_ASSERT, !cisnan(fuelMs), "NaN fuelMs", false); - angle_t injectionDuration = MS2US(fuelMs) / oneDegreeUs; - efiAssert(CUSTOM_ERR_ASSERT, !cisnan(injectionDuration), "NaN injectionDuration", false); - assertAngleRange(injectionDuration, "injectionDuration_r", CUSTOM_INJ_DURATION); - floatus_t injectionOffset = ENGINE(engineState.injectionOffset); - if (cisnan(injectionOffset)) { - // injection offset map not ready - we are not ready to schedule fuel events - return false; - } - angle_t baseAngle = injectionOffset - injectionDuration; - efiAssert(CUSTOM_ERR_ASSERT, !cisnan(baseAngle), "NaN baseAngle", false); - assertAngleRange(baseAngle, "baseAngle_r", CUSTOM_ERR_6554); - - injection_mode_e mode = engine->getCurrentInjectionMode(PASS_ENGINE_PARAMETER_SIGNATURE); - - int injectorIndex; - if (mode == IM_SIMULTANEOUS || mode == IM_SINGLE_POINT) { - // These modes only have one injector - injectorIndex = 0; - } else if (mode == IM_SEQUENTIAL || (mode == IM_BATCH && CONFIG(twoWireBatchInjection))) { - // Map order index -> cylinder index (firing order) - injectorIndex = getCylinderId(i PASS_ENGINE_PARAMETER_SUFFIX) - 1; - } else if (mode == IM_BATCH) { - // Loop over the first half of the firing order twice - injectorIndex = i % (engineConfiguration->specs.cylindersCount / 2); - } else { - firmwareError(CUSTOM_OBD_UNEXPECTED_INJECTION_MODE, "Unexpected injection mode %d", mode); - injectorIndex = 0; - } - - assertAngleRange(baseAngle, "addFbaseAngle", CUSTOM_ADD_BASE); - - int cylindersCount = CONFIG(specs.cylindersCount); - if (cylindersCount < 1) { - // May 2020 this somehow still happens with functional tests, maybe race condition? - warning(CUSTOM_OBD_ZERO_CYLINDER_COUNT, "Invalid cylinder count: %d", cylindersCount); - return false; - } - - float angle = baseAngle - + i * ENGINE(engineCycle) / cylindersCount; - - InjectorOutputPin *secondOutput; - if (mode == IM_BATCH && CONFIG(twoWireBatchInjection)) { - /** - * also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires - */ - // Compute the position of this cylinder's twin in the firing order - // Each injector gets fired as a primary (the same as sequential), but also - // fires the injector 360 degrees later in the firing order. - int secondOrder = (i + (CONFIG(specs.cylindersCount) / 2)) % CONFIG(specs.cylindersCount); - int secondIndex = getCylinderId(secondOrder PASS_ENGINE_PARAMETER_SUFFIX) - 1; - secondOutput = &enginePins.injectors[secondIndex]; - } else { - secondOutput = nullptr; - } - - InjectorOutputPin *output = &enginePins.injectors[injectorIndex]; - bool isSimultanious = mode == IM_SIMULTANEOUS; - - if (!isSimultanious && !output->isInitialized()) { - // todo: extract method for this index math - warning(CUSTOM_OBD_INJECTION_NO_PIN_ASSIGNED, "no_pin_inj #%s", output->name); - } - - InjectionEvent *ev = &elements[i]; - ev->ownIndex = i; - INJECT_ENGINE_REFERENCE(ev); - fixAngle(angle, "addFuel#1", CUSTOM_ERR_6554); - - ev->outputs[0] = output; - ev->outputs[1] = secondOutput; - - ev->isSimultanious = isSimultanious; - - if (TRIGGER_WAVEFORM(getSize()) < 1) { - warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform"); - return false; - } - - efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "findAngle#3", false); - assertAngleRange(angle, "findAngle#a33", CUSTOM_ERR_6544); - ev->injectionStart.setAngle(angle PASS_ENGINE_PARAMETER_SUFFIX); -#if EFI_UNIT_TEST - printf("registerInjectionEvent angle=%.2f trgIndex=%d inj %d\r\n", angle, ev->injectionStart.triggerEventIndex, injectorIndex); -#endif - return true; -} - -void FuelSchedule::addFuelEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - clear(); - - for (int cylinderIndex = 0; cylinderIndex < CONFIG(specs.cylindersCount); cylinderIndex++) { - InjectionEvent *ev = &elements[cylinderIndex]; - ev->ownIndex = cylinderIndex; // todo: is this assignment needed here? we now initialize in constructor - bool result = addFuelEventsForCylinder(cylinderIndex PASS_ENGINE_PARAMETER_SUFFIX); - if (!result) - return; - } - isReady = true; -} - -#endif - static floatms_t getCrankingSparkDwell(DECLARE_ENGINE_PARAMETER_SIGNATURE) { if (engineConfiguration->useConstantDwellDuringCranking) { return engineConfiguration->ignitionDwellForCrankingMs; diff --git a/unit_tests/tests/trigger/test_injection_scheduling.cpp b/unit_tests/tests/trigger/test_injection_scheduling.cpp index 071338461b..759d4ca2b7 100644 --- a/unit_tests/tests/trigger/test_injection_scheduling.cpp +++ b/unit_tests/tests/trigger/test_injection_scheduling.cpp @@ -17,6 +17,7 @@ TEST(injectionScheduling, NormalDutyCycle) { efitick_t nowNt = 1000000; InjectionEvent event; + INJECT_ENGINE_REFERENCE(&event); InjectorOutputPin pin; pin.injectorIndex = 0; event.outputs[0] = &pin; @@ -36,5 +37,5 @@ TEST(injectionScheduling, NormalDutyCycle) { engine->rpmCalculator.oneDegreeUs = 100; - handleFuelInjectionEvent(0, &event, 1000, nowNt PASS_ENGINE_PARAMETER_SUFFIX); + event.onTriggerTooth(0, 1000, nowNt); }