From 2a7d2604373ce2545665d98186a45b1862313f6c Mon Sep 17 00:00:00 2001 From: rusEfi Date: Wed, 30 Nov 2016 20:02:41 -0500 Subject: [PATCH] auto-sync --- firmware/controllers/algo/engine.h | 2 +- firmware/controllers/math/engine_math.cpp | 148 +++++++++--------- .../trigger/main_trigger_callback.cpp | 20 ++- firmware/rusefi.cpp | 2 +- unit_tests/test_trigger_decoder.cpp | 24 ++- 5 files changed, 97 insertions(+), 99 deletions(-) diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 20d356724a..b2de923b4f 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -42,6 +42,7 @@ public: * this method schedules all fuel events for an engine cycle */ void addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S); + void addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE_ENGINE_PARAMETER_S); uint32_t usedAtEngineCycle; @@ -58,7 +59,6 @@ public: int eventsCount; private: void clear(); - void registerInjectionEvent(InjectorOutputPin *output, InjectorOutputPin *secondOutput, float angle, angle_t injectionDuration, bool isSimultanious DECLARE_ENGINE_PARAMETER_S); }; /** diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 52591630c7..c8e5d0c235 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -93,40 +93,6 @@ void setSingleCoilDwell(engine_configuration_s *engineConfiguration) { #if EFI_ENGINE_CONTROL || defined(__DOXYGEN__) -void FuelSchedule::registerInjectionEvent(InjectorOutputPin *output, InjectorOutputPin *secondOutput, float angle, angle_t injectionDuration, - bool isSimultanious DECLARE_ENGINE_PARAMETER_S) { - - - if (!isSimultanious && !isPinAssigned(output)) { - // todo: extract method for this index math - warning(CUSTOM_OBD_20, "no_pin_inj #%s", output->name); - } - - InjectionEvent *ev = injectionEvents.add(); - if (ev == NULL) { - // error already reported - return; - } - fixAngle(angle); - ev->isOverlapping = angle < 720 && (angle + injectionDuration) > 720; - - ev->outputs[0] = output; - - ev->isSimultanious = isSimultanious; - - efiAssertVoid(TRIGGER_SHAPE(getSize()) > 0, "uninitialized TriggerShape"); - - findTriggerPosition(&ev->injectionStart, angle PASS_ENGINE_PARAMETER); -#if EFI_UNIT_TEST - printf("registerInjectionEvent angle=%f index=%d\r\n", angle, ev->injectionStart.eventIndex); -#endif - - if (!hasEvents[ev->injectionStart.eventIndex]) { - hasEvents[ev->injectionStart.eventIndex] = true; - eventsCount++; - } -} - FuelSchedule::FuelSchedule() { clear(); } @@ -137,12 +103,7 @@ void FuelSchedule::clear() { usedAtEngineCycle = 0; } -void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) { - clear(); // this method is relatively heavy -// sourceList->reset(); - - injectionEvents.reset(); - +void FuelSchedule::addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) { efiAssertVoid(engine!=NULL, "engine is NULL"); if (cisnan(engine->rpmCalculator.oneDegreeUs)) { @@ -161,46 +122,77 @@ void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_ angle_t injectionDuration = MS2US(ENGINE(fuelMs)) / ENGINE(rpmCalculator.oneDegreeUs); angle_t baseAngle = ENGINE(engineState.injectionOffset) - injectionDuration; - switch (mode) { - case IM_SEQUENTIAL: - for (int i = 0; i < CONFIG(specs.cylindersCount); i++) { - int index = getCylinderId(engineConfiguration->specs.firingOrder, i) - 1; - float angle = baseAngle - + ENGINE(engineCycle) * i / CONFIG(specs.cylindersCount); - registerInjectionEvent(&enginePins.injectors[index], NULL, angle, injectionDuration, false PASS_ENGINE_PARAMETER); - } - break; - case IM_SIMULTANEOUS: - for (int i = 0; i < CONFIG(specs.cylindersCount); i++) { - float angle = baseAngle - + ENGINE(engineCycle) * i / CONFIG(specs.cylindersCount); + int index; - /** - * We do not need injector pin here because we will control all injectors - * simultaneously - */ - registerInjectionEvent(&enginePins.injectors[0], NULL, angle, injectionDuration, true PASS_ENGINE_PARAMETER); - } - break; - case IM_BATCH: - for (int i = 0; i < CONFIG(specs.cylindersCount); i++) { - int index = i % (engineConfiguration->specs.cylindersCount / 2); - float angle = baseAngle - + i * ENGINE(engineCycle) / CONFIG(specs.cylindersCount); - registerInjectionEvent(&enginePins.injectors[index], NULL, angle, injectionDuration, false PASS_ENGINE_PARAMETER); - - if (CONFIG(twoWireBatchInjection)) { - - /** - * also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires - */ - index = index + (CONFIG(specs.cylindersCount) / 2); - registerInjectionEvent(&enginePins.injectors[index], NULL, angle, injectionDuration, false PASS_ENGINE_PARAMETER); - } - } - break; - default: + if (mode == IM_SIMULTANEOUS) { + index = 0; + } else if (mode == IM_SEQUENTIAL) { + index = getCylinderId(engineConfiguration->specs.firingOrder, i) - 1; + } else if (mode == IM_BATCH) { + // does not look exactly right, not too consistent with IM_SEQUENTIAL + index = i % (engineConfiguration->specs.cylindersCount / 2); + } else { warning(CUSTOM_OBD_21, "Unexpected injection mode %d", mode); + index = 0; + } + + bool isSimultanious = mode == IM_SIMULTANEOUS; + + float angle = baseAngle + + i * ENGINE(engineCycle) / CONFIG(specs.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 + */ + int secondIndex = index + (CONFIG(specs.cylindersCount) / 2); + secondOutput = &enginePins.injectors[secondIndex]; + } else { + secondOutput = NULL; + } + + InjectorOutputPin *output = &enginePins.injectors[index]; + + if (!isSimultanious && !isPinAssigned(output)) { + // todo: extract method for this index math + warning(CUSTOM_OBD_20, "no_pin_inj #%s", output->name); + } + + InjectionEvent *ev = injectionEvents.add(); + if (ev == NULL) { + // error already reported + return; + } + fixAngle(angle); + ev->isOverlapping = angle < 720 && (angle + injectionDuration) > 720; + + ev->outputs[0] = output; + ev->outputs[1] = secondOutput; + + ev->isSimultanious = isSimultanious; + + efiAssertVoid(TRIGGER_SHAPE(getSize()) > 0, "uninitialized TriggerShape"); + + findTriggerPosition(&ev->injectionStart, angle PASS_ENGINE_PARAMETER); +#if EFI_UNIT_TEST + printf("registerInjectionEvent angle=%f index=%d\r\n", angle, ev->injectionStart.eventIndex); +#endif + + if (!hasEvents[ev->injectionStart.eventIndex]) { + hasEvents[ev->injectionStart.eventIndex] = true; + eventsCount++; + } +} + +void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) { + clear(); // this method is relatively heavy +// sourceList->reset(); + + injectionEvents.reset(); + + for (int i = 0; i < CONFIG(specs.cylindersCount); i++) { + addFuelEventsForCylinder(i, mode PASS_ENGINE_PARAMETER); } } diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 4fc4c71dde..1d31d18694 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -121,8 +121,11 @@ static void tempTurnPinHigh(InjectorOutputPin *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); + for (int i = 0;ioutputs[i]; + if (output != NULL) + tempTurnPinHigh(output); + } } static void tempTurnPinLow(InjectorOutputPin *output) { @@ -166,8 +169,11 @@ static void tempTurnPinLow(InjectorOutputPin *output) { void seTurnPinLow(OutputSignalPair *pair) { pair->isScheduled = false; - InjectorOutputPin *output = pair->outputs[0]; - tempTurnPinLow(output); + for (int i = 0;ioutputs[i]; + if (output != NULL) + tempTurnPinLow(output); + } } static void seScheduleByTime(const char *prefix, scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, OutputSignalPair *pair) { @@ -185,7 +191,7 @@ static void seScheduleByTime(const char *prefix, scheduling_s *scheduling, efiti scheduleByTime(true, prefix, scheduling, time, callback, pair); } -static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t nowUs, floatus_t delayUs, floatus_t durationUs, InjectorOutputPin *output DECLARE_ENGINE_PARAMETER_S) { +static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t nowUs, floatus_t delayUs, floatus_t durationUs, InjectionEvent *event DECLARE_ENGINE_PARAMETER_S) { if (durationUs < 0) { warning(CUSTOM_OBD_3, "duration cannot be negative: %d", durationUs); return; @@ -194,6 +200,7 @@ static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t now warning(CUSTOM_NAN_DURACTION, "NaN in scheduleFuelInjection", durationUs); return; } + InjectorOutputPin *output = event->outputs[0]; #if EFI_PRINTF_FUEL_DETAILS || defined(__DOXYGEN__) printf("fuelout %s duration %d total=%d\t\n", output->name, (int)durationUs, (int)MS2US(getCrankshaftRevolutionTimeMs(rpm))); @@ -209,6 +216,7 @@ static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t now return; // this OutputSignalPair is still needed for an extremely long injection scheduled previously } pair->outputs[0] = output; + pair->outputs[1] = event->outputs[1]; scheduling_s * sUp = &pair->signalTimerUp; scheduling_s * sDown = &pair->signalTimerDown; @@ -316,7 +324,7 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionE prevOutputName = outputName; } - scheduleFuelInjection(rpm, signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event->outputs[0] PASS_ENGINE_PARAMETER); + scheduleFuelInjection(rpm, signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event PASS_ENGINE_PARAMETER); } } diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index 5abb95e0f4..60645adec4 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -281,7 +281,7 @@ void firmwareError(obd_code_e code, const char *errorMsg, ...) { } } -static char UNUSED_RAM_SIZE[1300]; +static char UNUSED_RAM_SIZE[1100]; static char UNUSED_CCM_SIZE[8500] CCM_OPTIONAL; diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index 92115b69f7..a31f6ee2be 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -383,11 +383,10 @@ void testRpmCalculator(void) { timeNow += 5000; eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_FALLING PASS_ENGINE_PARAMETER); assertEqualsM("index #3", 3, eth.engine.triggerCentral.triggerState.getCurrentIndex()); - assertEqualsM("queue size 3", 6, schedulingQueue.size()); + assertEqualsM("queue size 3", 4, schedulingQueue.size()); assertEqualsM("ev 3", st + 13333 - 1515, schedulingQueue.getForUnitText(0)->momentX); - assertEqualsM("ev 4", st + 13333 - 1515, schedulingQueue.getForUnitText(1)->momentX); - assertEqualsM2("ev 5", st + 14277, schedulingQueue.getForUnitText(2)->momentX, 2); - assertEqualsM("3/3", st + 14777, schedulingQueue.getForUnitText(3)->momentX); + assertEqualsM2("ev 5", st + 14277, schedulingQueue.getForUnitText(1)->momentX, 2); + assertEqualsM("3/3", st + 14777, schedulingQueue.getForUnitText(2)->momentX); schedulingQueue.clear(); assertEquals(5, engine->triggerShape.triggerIndexByAngle[240]); @@ -401,26 +400,26 @@ void testRpmCalculator(void) { timeNow += 5000; // 5ms eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER); - assertEqualsM("queue size 4.2", 6, schedulingQueue.size()); + assertEqualsM("queue size 4.2", 4, schedulingQueue.size()); timeNow += 5000; // 5ms eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER); - assertEqualsM("queue size 4.3", 6, schedulingQueue.size()); + assertEqualsM("queue size 4.3", 4, schedulingQueue.size()); assertEqualsM("dwell", 4.5, eth.engine.engineState.dwellAngle); assertEqualsM("fuel #3", 4.5450, eth.engine.fuelMs); assertEquals(1500, eth.engine.rpmCalculator.rpmValue); assertInjectorUpEvent("ev 0/2", 0, -4849, 2); - assertInjectorUpEvent("ev 1/2", 1, -4849, 5); + assertEqualsM("index #4", 6, eth.engine.triggerCentral.triggerState.getCurrentIndex()); - assertEqualsM("queue size 4", 6, schedulingQueue.size()); + assertEqualsM("queue size 4", 4, schedulingQueue.size()); schedulingQueue.clear(); timeNow += 5000; eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_FALLING PASS_ENGINE_PARAMETER); - assertEqualsM("queue size 5", 4, schedulingQueue.size()); + assertEqualsM("queue size 5", 2, schedulingQueue.size()); // todo: assert queue elements schedulingQueue.clear(); @@ -438,12 +437,11 @@ void testRpmCalculator(void) { timeNow += 5000; // 5ms eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER); - assertEqualsM("queue size 8", 6, schedulingQueue.size()); + assertEqualsM("queue size 8", 4, schedulingQueue.size()); // todo: assert queue elements completely assertEqualsM("8/0", st + 53333 - 1515, schedulingQueue.getForUnitText(0)->momentX); - assertEqualsM("8/1", st + 53333 - 1515, schedulingQueue.getForUnitText(1)->momentX); - assertEqualsM2("8/2", st + 54277, schedulingQueue.getForUnitText(2)->momentX, 0); - assertEqualsM2("8/3", st + 54777, schedulingQueue.getForUnitText(3)->momentX, 0); + assertEqualsM2("8/1", st + 54277, schedulingQueue.getForUnitText(1)->momentX, 0); + assertEqualsM2("8/2", st + 54777, schedulingQueue.getForUnitText(2)->momentX, 0); schedulingQueue.clear(); timeNow += 5000;