From bc6eb28818a7e73ac92da824938ad9f1ca479914 Mon Sep 17 00:00:00 2001 From: rusEfi Date: Wed, 12 Nov 2014 08:03:14 -0600 Subject: [PATCH] auto-sync --- firmware/controllers/algo/ec2.h | 2 +- firmware/controllers/algo/event_registry.h | 9 +++- firmware/controllers/algo/signal_executor.c | 4 +- firmware/controllers/math/engine_math.cpp | 31 ++++++------ firmware/controllers/math/engine_math.h | 2 + .../trigger/main_trigger_callback.cpp | 48 +++++++++++++++++-- firmware/rusefi.cpp | 2 +- 7 files changed, 73 insertions(+), 25 deletions(-) diff --git a/firmware/controllers/algo/ec2.h b/firmware/controllers/algo/ec2.h index f428820617..822aecf88b 100644 --- a/firmware/controllers/algo/ec2.h +++ b/firmware/controllers/algo/ec2.h @@ -25,7 +25,7 @@ public: void addFuelEvents(trigger_shape_s *s, injection_mode_e mode DECLATE_ENGINE_PARAMETER); void registerInjectionEvent(trigger_shape_s *s, - io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER); + io_pin_e pin, float angle, bool_t isSimultanious DECLATE_ENGINE_PARAMETER); uint8_t hasEvents[PWM_PHASE_MAX_COUNT]; diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index d07a5d4264..585c26c85a 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -31,7 +31,12 @@ typedef struct { typedef struct { event_trigger_position_s position; OutputSignal *actuator; -} ActuatorEvent; + /** + * This is a performance optimization - it's more efficient to handle all + * injectors together if that's the case + */ + bool_t isSimultanious; +} InjectionEvent; typedef struct IgnitionEvent_struct IgnitionEvent; @@ -66,7 +71,7 @@ Type * ArrayList< Type, Dimention>::getNextActuatorEvent(void) { return &events[size++]; } -typedef ArrayList ActuatorEventList; +typedef ArrayList ActuatorEventList; typedef ArrayList IgnitionEventList; diff --git a/firmware/controllers/algo/signal_executor.c b/firmware/controllers/algo/signal_executor.c index b8f9c4e36f..ce83f0d41e 100644 --- a/firmware/controllers/algo/signal_executor.c +++ b/firmware/controllers/algo/signal_executor.c @@ -62,12 +62,12 @@ void turnPinHigh(io_pin_e pin) { // sleep for the needed duration #if EFI_PROD_CODE || EFI_SIMULATOR - if (pin == SPARKOUT_1_OUTPUT || pin == SPARKOUT_3_OUTPUT) { +// if (pin == SPARKOUT_1_OUTPUT || pin == SPARKOUT_3_OUTPUT) { // time_t now = hTimeNow(); // float an = getCrankshaftAngle(now); // scheduleMsg(&logger, "spark up%d %d", pin, now); // scheduleMsg(&logger, "spark angle %d %f", (int)an, an); - } +// } #endif #if EFI_WAVE_CHART diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 96c0ce4bb7..98a14684de 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -174,7 +174,7 @@ void initializeIgnitionActions(float advance, float dwellAngle, } void FuelSchedule::registerInjectionEvent(trigger_shape_s *s, - io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER) { + io_pin_e pin, float angle, bool_t isSimultanious DECLATE_ENGINE_PARAMETER) { ActuatorEventList *list = &events; if (!isPinAssigned(pin)) { @@ -182,9 +182,11 @@ void FuelSchedule::registerInjectionEvent(trigger_shape_s *s, warning(OBD_PCM_Processor_Fault, "no_pin_inj #%d", (int) pin - (int) INJECTOR_1_OUTPUT + 1); } - ActuatorEvent *ev = list->getNextActuatorEvent(); + InjectionEvent *ev = list->getNextActuatorEvent(); OutputSignal *actuator = injectonSignals.add(pin); + ev->isSimultanious = isSimultanious; + efiAssertVoid(s->getSize() > 0, "uninitialized trigger_shape_s"); if (ev == NULL) { @@ -216,33 +218,34 @@ void FuelSchedule::addFuelEvents(trigger_shape_s *s, switch (mode) { case IM_SEQUENTIAL: for (int i = 0; i < engineConfiguration->cylindersCount; i++) { - io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + getCylinderId(engineConfiguration->firingOrder, i) - 1); - float angle = baseAngle + i * 720.0 / engineConfiguration->cylindersCount; - registerInjectionEvent(s, pin, angle PASS_ENGINE_PARAMETER); + io_pin_e pin = INJECTOR_PIN_BY_INDEX(getCylinderId(engineConfiguration->firingOrder, i) - 1); + float angle = baseAngle + 1.0 * i * 720 / engineConfiguration->cylindersCount; + registerInjectionEvent(s, pin, angle, false PASS_ENGINE_PARAMETER); } break; case IM_SIMULTANEOUS: for (int i = 0; i < engineConfiguration->cylindersCount; i++) { - float angle = baseAngle + i * 720.0 / engineConfiguration->cylindersCount; + float angle = baseAngle + 1.0 * i * 720 / engineConfiguration->cylindersCount; - for (int j = 0; j < engineConfiguration->cylindersCount; j++) { - io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + j); - registerInjectionEvent(s, pin, angle PASS_ENGINE_PARAMETER); - } + /** + * We do not need injector pin here because we will control all injectors + * simultaniously + */ + registerInjectionEvent(s, IO_INVALID, angle, true PASS_ENGINE_PARAMETER); } break; case IM_BATCH: for (int i = 0; i < engineConfiguration->cylindersCount; i++) { int index = i % (engineConfiguration->cylindersCount / 2); - io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + index); - float angle = baseAngle + i * 720.0 / engineConfiguration->cylindersCount; - registerInjectionEvent(s, pin, angle PASS_ENGINE_PARAMETER); + io_pin_e pin = INJECTOR_PIN_BY_INDEX(index); + float angle = baseAngle + 1.0 * i * 720 / engineConfiguration->cylindersCount; + registerInjectionEvent(s, pin, angle, false PASS_ENGINE_PARAMETER); /** * also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires */ pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + index + (engineConfiguration->cylindersCount / 2)); - registerInjectionEvent(s, pin, angle PASS_ENGINE_PARAMETER); + registerInjectionEvent(s, pin, angle, false PASS_ENGINE_PARAMETER); } break; default: diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index ea6f33947d..f3bdb94dd8 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -17,6 +17,8 @@ #include "table_helper.h" #include "engine.h" +#define INJECTOR_PIN_BY_INDEX(index) (io_pin_e) ((int) INJECTOR_1_OUTPUT + (index)) + void findTriggerPosition(trigger_shape_s * s, event_trigger_position_s *position, float angleOffset DECLATE_ENGINE_PARAMETER); diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index a055a1f4df..e6e6926c9b 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -78,7 +78,19 @@ static cyclic_buffer ignitionErrorDetection; static Logging logger; -static ALWAYS_INLINE void handleFuelInjectionEvent(ActuatorEvent *event, int rpm DECLATE_ENGINE_PARAMETER) { +static void startSimultaniousInjection(Engine *engine) { + for (int i = 0; i < engine->engineConfiguration->cylindersCount; i++) { + turnPinHigh(INJECTOR_PIN_BY_INDEX(i)); + } +} + +static void endSimultaniousInjection(Engine *engine) { + for (int i = 0; i < engine->engineConfiguration->cylindersCount; i++) { + turnPinLow(INJECTOR_PIN_BY_INDEX(i)); + } +} + +static ALWAYS_INLINE void handleFuelInjectionEvent(InjectionEvent *event, int rpm DECLATE_ENGINE_PARAMETER) { /** * todo: we do not really need to calculate fuel for each individual cylinder */ @@ -95,12 +107,37 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(ActuatorEvent *event, int rpm if (engine->isCylinderCleanupMode) return; - float delay = getOneDegreeTimeMs(rpm) * event->position.angleOffset; + float delayMs = getOneDegreeTimeMs(rpm) * event->position.angleOffset; // if (isCranking()) // scheduleMsg(&logger, "crankingFuel=%f for CLT=%fC", fuelMs, getCoolantTemperature()); - scheduleOutput(event->actuator, delay, fuelMs); + if (event->isSimultanious) { + if (fuelMs < 0) { + firmwareError("duration cannot be negative: %d", fuelMs); + return; + } + if (cisnan(fuelMs)) { + firmwareError("NaN in scheduleOutput", fuelMs); + return; + } + /** + * this is pretty much copy-paste of 'scheduleOutput' + * 'scheduleOutput' is currently only used for injection, so maybe it should be + * changed into 'scheduleInjection' and unified? todo: think about it. + */ + OutputSignal *signal = event->actuator; + efiAssertVoid(signal!=NULL, "signal is NULL"); + int index = getRevolutionCounter() % 2; + scheduling_s * sUp = &signal->signalTimerUp[index]; + scheduling_s * sDown = &signal->signalTimerDown[index]; + + scheduleTask("out up", sUp, (int) MS2US(delayMs), (schfunc_t) &startSimultaniousInjection, engine); + scheduleTask("out down", sDown, (int) MS2US(delayMs + fuelMs), (schfunc_t) &endSimultaniousInjection, engine); + + } else { + scheduleOutput(event->actuator, delayMs, fuelMs); + } } static ALWAYS_INLINE void handleFuel(uint32_t eventIndex, int rpm DECLATE_ENGINE_PARAMETER) { @@ -127,14 +164,15 @@ static ALWAYS_INLINE void handleFuel(uint32_t eventIndex, int rpm DECLATE_ENGINE return; for (int i = 0; i < source->size; i++) { - ActuatorEvent *event = &source->events[i]; + InjectionEvent *event = &source->events[i]; if (event->position.eventIndex != eventIndex) continue; handleFuelInjectionEvent(event, rpm PASS_ENGINE_PARAMETER); } } -static ALWAYS_INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent, int rpm DECLATE_ENGINE_PARAMETER) { +static ALWAYS_INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent, + int rpm DECLATE_ENGINE_PARAMETER) { engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2; float dwellMs = getSparkDwellMsT(rpm PASS_ENGINE_PARAMETER); diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index 89d9cd48be..e67f594508 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -252,5 +252,5 @@ void firmwareError(const char *fmt, ...) { } int getRusEfiVersion(void) { - return 20141111; + return 20141112; }