diff --git a/firmware/controllers/algo/event_registry.cpp b/firmware/controllers/algo/event_registry.cpp index 354486f74d..7db0bb94b2 100644 --- a/firmware/controllers/algo/event_registry.cpp +++ b/firmware/controllers/algo/event_registry.cpp @@ -27,7 +27,6 @@ InjectionEvent::InjectionEvent() { isSimultanious = false; isOverlapping = false; - injectorIndex = 0; output = NULL; } diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index 25b8b01549..5000c0a32c 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -38,7 +38,6 @@ public: */ bool isSimultanious; InjectorOutputPin *output; - int injectorIndex; bool isOverlapping; event_trigger_position_s injectionStart; diff --git a/firmware/controllers/algo/signal_executor.cpp b/firmware/controllers/algo/signal_executor.cpp index bc3a9a8536..31f8ee8e7b 100644 --- a/firmware/controllers/algo/signal_executor.cpp +++ b/firmware/controllers/algo/signal_executor.cpp @@ -43,7 +43,7 @@ extern WaveChart waveChart; OutputSignalPair::OutputSignalPair() { isScheduled = false; - output = NULL; + memset(outputs, 0, sizeof(outputs)); } void initSignalExecutor(void) { diff --git a/firmware/controllers/algo/signal_executor.h b/firmware/controllers/algo/signal_executor.h index 7f513cd6f2..b70fb91f93 100644 --- a/firmware/controllers/algo/signal_executor.h +++ b/firmware/controllers/algo/signal_executor.h @@ -24,6 +24,8 @@ #include "signal_executor_sleep.h" #endif /* EFI_SIGNAL_EXECUTOR_SLEEP */ +#define MAX_WIRES_COUNT 2 + class OutputSignalPair { public: OutputSignalPair(); @@ -38,7 +40,7 @@ public: * TODO: make watchdog decrement relevant counter */ bool isScheduled; - InjectorOutputPin *output; + InjectorOutputPin *outputs[MAX_WIRES_COUNT]; }; /** diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 4a05292bce..9e7dc9631e 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -111,7 +111,6 @@ void FuelSchedule::registerInjectionEvent(int injectorIndex, float angle, angle_ fixAngle(angle); ev->isOverlapping = angle < 720 && (angle + injectionDuration) > 720; - ev->injectorIndex = injectorIndex; ev->output = output; ev->isSimultanious = isSimultanious; diff --git a/firmware/controllers/system/efiGpio.cpp b/firmware/controllers/system/efiGpio.cpp index da0740b756..34ff9d1440 100644 --- a/firmware/controllers/system/efiGpio.cpp +++ b/firmware/controllers/system/efiGpio.cpp @@ -29,6 +29,7 @@ NamedOutputPin::NamedOutputPin(const char *name) : OutputPin() { InjectorOutputPin::InjectorOutputPin() : NamedOutputPin() { reset(); + injectorIndex = -1; } static const char *sparkNames[IGNITION_PIN_COUNT] = { "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", @@ -46,6 +47,7 @@ EnginePins::EnginePins() { enginePins.coils[i].name = sparkNames[i]; } for (int i = 0; i < INJECTION_PIN_COUNT;i++) { + enginePins.injectors[i].injectorIndex = i; enginePins.injectors[i].name = injectorNames[i]; } } diff --git a/firmware/controllers/system/efiGpio.h b/firmware/controllers/system/efiGpio.h index bf31c625c2..538890d461 100644 --- a/firmware/controllers/system/efiGpio.h +++ b/firmware/controllers/system/efiGpio.h @@ -56,6 +56,7 @@ public: InjectorOutputPin(); void reset(); efitimeus_t overlappingScheduleOffTime; + int injectorIndex; bool cancelNextTurningInjectorOff; int overlappingCounter; }; diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index b465170198..254bda02c8 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -87,9 +87,7 @@ static void endSimultaniousInjection(Engine *engine) { } } -// todo: make these macro? kind of a penny optimization if compiler is not smart to inline -void seTurnPinHigh(OutputSignalPair *pair) { - InjectorOutputPin *output = pair->output; +static void tempTurnPinHigh(InjectorOutputPin *output) { output->overlappingCounter++; #if FUEL_MATH_EXTREME_LOGGING || defined(__DOXYGEN__) @@ -121,9 +119,13 @@ void seTurnPinHigh(OutputSignalPair *pair) { turnPinHigh(output); } -void seTurnPinLow(OutputSignalPair *pair) { - pair->isScheduled = false; - InjectorOutputPin *output = pair->output; +// todo: make these macro? kind of a penny optimization if compiler is not smart to inline +void seTurnPinHigh(OutputSignalPair *pair) { + InjectorOutputPin *output = pair->outputs[0]; + tempTurnPinHigh(output); +} + +static void tempTurnPinLow(InjectorOutputPin *output) { #if FUEL_MATH_EXTREME_LOGGING || defined(__DOXYGEN__) printf("seTurnPinLow %s %d %d\r\n", output->name, output->overlappingCounter, (int)getTimeNowUs()); #endif /* FUEL_MATH_EXTREME_LOGGING */ @@ -162,8 +164,14 @@ void seTurnPinLow(OutputSignalPair *pair) { turnPinLow(output); } +void seTurnPinLow(OutputSignalPair *pair) { + pair->isScheduled = false; + InjectorOutputPin *output = pair->outputs[0]; + tempTurnPinLow(output); +} + static void seScheduleByTime(const char *prefix, scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, OutputSignalPair *pair) { - InjectorOutputPin *param = pair->output; + InjectorOutputPin *param = pair->outputs[0]; #if FUEL_MATH_EXTREME_LOGGING || defined(__DOXYGEN__) // scheduleMsg(&sharedLogger, "schX %s %x %d", prefix, scheduling, time); // scheduleMsg(&sharedLogger, "schX %s", param->name); @@ -200,7 +208,7 @@ static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t now #endif /* EFI_UNIT_TEST || EFI_SIMULATOR */ return; // this OutputSignalPair is still needed for an extremely long injection scheduled previously } - pair->output = output; + pair->outputs[0] = output; scheduling_s * sUp = &pair->signalTimerUp; scheduling_s * sDown = &pair->signalTimerDown; @@ -229,7 +237,7 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionE * wetting coefficient works the same way for any injection mode, or is something * x2 or /2? */ - const floatms_t injectionDuration = ENGINE(wallFuel).adjust(event->injectorIndex, ENGINE(fuelMs) PASS_ENGINE_PARAMETER); + const floatms_t injectionDuration = ENGINE(wallFuel).adjust(event->output->injectorIndex, ENGINE(fuelMs) PASS_ENGINE_PARAMETER); #if EFI_PRINTF_FUEL_DETAILS || defined(__DOXYGEN__) printf("fuel fuelMs=%f adjusted=%f\t\n", ENGINE(fuelMs), injectionDuration); #endif /*EFI_PRINTF_FUEL_DETAILS */ @@ -332,7 +340,7 @@ static void scheduleOutput2(OutputSignalPair *pair, efitimeus_t nowUs, float del pair->isScheduled = true; scheduling_s *sDown = &pair->signalTimerDown; - pair->output = output; + pair->outputs[0] = output; seScheduleByTime("out up2", sUp, turnOnTime, (schfunc_t) &seTurnPinHigh, pair); efitimeus_t turnOffTime = nowUs + (int) (delayUs + durationUs); @@ -352,7 +360,7 @@ static void handleFuelScheduleOverlap(InjectionEventList *injectionEvents DECLAR if (!engine->engineConfiguration2->wasOverlapping[injEventIndex] && event->isOverlapping) { // we are here if new fuel schedule is crossing engine cycle boundary with this event - InjectorOutputPin *output = &enginePins.injectors[event->injectorIndex]; + InjectorOutputPin *output = event->output; // todo: recalc fuel? account for wetting? floatms_t injectionDuration = ENGINE(fuelMs); diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index c6a4b08a15..ce8cdf8ac7 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -588,7 +588,7 @@ void assertEvent(const char *msg, int index, void *callback, efitime_t start, ef assertEqualsM4(msg, "up/down", (void*)ev->callback == (void*) callback, 1); assertEqualsM(msg, momentX, ev->momentX - start); OutputSignalPair *pair = (OutputSignalPair *)ev->param; - assertEqualsLM(msg, param, (long)pair->output); + assertEqualsLM(msg, param, (long)pair->outputs[0]); } void assertInjectorUpEvent(const char *msg, int eventIndex, efitime_t momentX, long injectorIndex) { @@ -600,7 +600,7 @@ void assertInjectorDownEvent(const char *msg, int eventIndex, efitime_t momentX, } static void assertInjectionEvent(const char *msg, InjectionEvent *ev, int injectorIndex, int eventIndex, angle_t angleOffset, bool isOverlapping) { - assertEqualsM4(msg, "inj index", injectorIndex, ev->injectorIndex); + assertEqualsM4(msg, "inj index", injectorIndex, ev->output->injectorIndex); assertEqualsM4(msg, " event index", eventIndex, ev->injectionStart.eventIndex); assertEqualsM4(msg, " event offset", angleOffset, ev->injectionStart.angleOffset); assertTrueM("is overlapping", isOverlapping == ev->isOverlapping);