From dcb0d7ffdb31fbb3a3d7a69dd66622f59c96adbb Mon Sep 17 00:00:00 2001 From: rusEFI LLC Date: Tue, 23 Apr 2024 15:55:12 -0400 Subject: [PATCH] only: docs --- firmware/controllers/algo/event_registry.h | 10 ++++++++++ firmware/controllers/engine_cycle/spark_logic.cpp | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index 94605086db..c634da84f6 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -36,11 +36,21 @@ private: angle_t enginePhase; }; +// this is related to wasted spark idea where engines fire each spark twice per 4 stroke 720 degree cycle of operations +// first spark is happens on intake stroke and actually ignites fuel mixture, that's the useful one +// the other spark 360 degrees later happens during exhaust stroke meaning there is nothing to ignite, that spark is known as "wasted" spark +// historically this was about sharing ignition coils between opposite cylinders and having two high voltage wire coming from one physical coil +// more recently same idea happens with two individual physical coils (meaning two outputs) since wasted spark of operation is useful +// while exact engine phase is either not known YET (cranking) or just not known (broken cam sensor) +// so, while in wasted spark we manage half of cylinder count _events_ potentially with each event having two outputs +// +// an interesting corner case is when we transition from wasted spark mode into individual/sequential mode #define MAX_OUTPUTS_FOR_IGNITION 2 class IgnitionEvent { public: IgnitionEvent(); + // IgnitionEvent to IgnitionOutputPin is either 1 to 1 or 1 to 2 relationship, see large comment at 'MAX_OUTPUTS_FOR_IGNITION' IgnitionOutputPin *outputs[MAX_OUTPUTS_FOR_IGNITION]; scheduling_s dwellStartTimer; AngleBasedEvent sparkEvent; diff --git a/firmware/controllers/engine_cycle/spark_logic.cpp b/firmware/controllers/engine_cycle/spark_logic.cpp index 9d9502ac79..a8c2b293de 100644 --- a/firmware/controllers/engine_cycle/spark_logic.cpp +++ b/firmware/controllers/engine_cycle/spark_logic.cpp @@ -38,7 +38,6 @@ static void fireSparkBySettingPinLow(IgnitionEvent *event, IgnitionOutputPin *ou * * 2) we have an un-matched low followed by legit pairs */ - output->signalFallSparkId = event->sparkCounter; if (!output->currentLogicValue && !event->wasSparkLimited) { @@ -182,6 +181,9 @@ static void overFireSparkAndPrepareNextSchedule(IgnitionEvent *event) { fireSparkAndPrepareNextSchedule(event); } +/** + * TL,DR: each IgnitionEvent is in charge of it's own scheduling forever, we plant next event while finishing handling of the current one + */ void fireSparkAndPrepareNextSchedule(IgnitionEvent *event) { #if EFI_UNIT_TEST if (engine->onIgnitionEvent) { @@ -323,6 +325,10 @@ void turnSparkPinHighStartCharging(IgnitionEvent *event) { for (int i = 0; i< MAX_OUTPUTS_FOR_IGNITION;i++) { IgnitionOutputPin *output = event->outputs[i]; if (output != NULL) { + // at the moment we have a funny xor as if outputs could have different destiny. That's probably an over exaggeration, + // realistically it should be enough to check the sequencing of only the first output but that would be less elegant + // + // maybe it would have need nicer if instead of an array of outputs we had a linked list of outputs? but that's just daydreaming. skippedDwellDueToTriggerNoised |= startDwellByTurningSparkPinHigh(event, output); } }