diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index d8f03d0b15..c2520ecd19 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -434,6 +434,14 @@ void Engine::OnTriggerStateProperState(efitick_t nowNt) { void Engine::OnTriggerSynchronizationLost() { // Needed for early instant-RPM detection rpmCalculator.setStopSpinning(); + + triggerCentral.triggerState.resetTriggerState(); + + for (size_t i = 0; i < efi::size(triggerCentral.vvtState); i++) { + for (size_t j = 0; j < efi::size(triggerCentral.vvtState[0]); j++) { + triggerCentral.vvtState[i][j].resetTriggerState(); + } + } } void Engine::OnTriggerInvalidIndex(int currentIndex) { diff --git a/firmware/controllers/engine_cycle/main_trigger_callback.cpp b/firmware/controllers/engine_cycle/main_trigger_callback.cpp index 73b86d6261..3d033a9533 100644 --- a/firmware/controllers/engine_cycle/main_trigger_callback.cpp +++ b/firmware/controllers/engine_cycle/main_trigger_callback.cpp @@ -330,8 +330,18 @@ static void handleFuel(const bool limitedFuel, uint32_t trgEventIndex, int rpm, uint32_t *cyccnt = (uint32_t*) &DWT->CYCCNT; #endif -static bool noFiringUntilVvtSync(vvt_mode_e mode) { - return mode == VVT_MIATA_NB2 || mode == VVT_MAP_V_TWIN_ANOTHER; +static bool noFiringUntilVvtSync(vvt_mode_e vvtMode) { + auto operationMode = engine->getOperationMode(); + + // V-Twin MAP phase sense needs to always wait for sync + if (vvtMode == VVT_MAP_V_TWIN_ANOTHER) { + return false; + } + + // Symmetrical crank modes require cam sync before firing + // non-symmetrical cranks can use faster spin-up mode (firing in wasted/batch before VVT sync) + // Examples include Nissan MR/VQ, Miata NB, etc + return operationMode == FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR || operationMode == FOUR_STROKE_THREE_TIMES_CRANK_SENSOR; } /** @@ -341,11 +351,11 @@ static bool noFiringUntilVvtSync(vvt_mode_e mode) { void mainTriggerCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp) { ScopePerf perf(PE::MainTriggerCallback); - if (noFiringUntilVvtSync(engineConfiguration->vvtMode[0]) && engine->triggerCentral.vvtSyncTimeNt == 0) { - // this is a bit spaghetti code for sure - // do not spark & do not fuel until we have VVT sync. - // NB2 is a special case due to symmetrical crank wheel and we need to make sure no spark happens out of sync - // VTwin is another special case where we really need to know phase before firing + if (noFiringUntilVvtSync(engineConfiguration->vvtMode[0]) && engine->triggerCentral.vvtSyncTimeNt[0][0] == 0) { + // Any engine that requires cam-assistance for a full crank sync (symmetrical crank) can't schedule until we have cam sync + // examples: + // NB2, Nissan VQ/MR: symmetrical crank wheel and we need to make sure no spark happens out of sync + // VTwin Harley: uneven firing order, so we need "cam" MAP sync to make sure no spark happens out of sync return; } diff --git a/firmware/controllers/trigger/decoders/trigger_mazda.cpp b/firmware/controllers/trigger/decoders/trigger_mazda.cpp index b1fe36f352..e44ec0eac0 100644 --- a/firmware/controllers/trigger/decoders/trigger_mazda.cpp +++ b/firmware/controllers/trigger/decoders/trigger_mazda.cpp @@ -73,7 +73,7 @@ void initializeMazdaMiataNb2Crank(TriggerWaveform *s) { // Nominal gap 70/110 = 0.636 s->setTriggerSynchronizationGap2(0.35f, 0.98f); // Nominal gap 110/70 = 1.571 - s->setSecondTriggerSynchronizationGap2(1.05f, 1.8f); + s->setSecondTriggerSynchronizationGap2(1.02f, 1.8f); // todo: NB2 fronts are inverted comparing to NB1, life is not perfect :( s->addEventAngle(180.0f - NB_CRANK_MAGIC - 4, T_PRIMARY, TV_FALL); diff --git a/firmware/controllers/trigger/trigger_central.cpp b/firmware/controllers/trigger/trigger_central.cpp index 2281ec9030..669277302f 100644 --- a/firmware/controllers/trigger/trigger_central.cpp +++ b/firmware/controllers/trigger/trigger_central.cpp @@ -317,7 +317,8 @@ void hwHandleVvtCamSignal(trigger_value_e front, efitick_t nowNt, int index) { case VVT_BOSCH_QUICK_START: case VVT_BARRA_3_PLUS_1: case VVT_NISSAN_VQ: - { + case VVT_NISSAN_MR: + { if (tc->vvtState[bankIndex][camIndex].currentCycle.current_index != 0) { // this is not sync tooth - exiting return; diff --git a/firmware/controllers/trigger/trigger_decoder.cpp b/firmware/controllers/trigger/trigger_decoder.cpp index bdc99c0f35..99de5b415f 100644 --- a/firmware/controllers/trigger/trigger_decoder.cpp +++ b/firmware/controllers/trigger/trigger_decoder.cpp @@ -71,7 +71,6 @@ void TriggerState::resetTriggerState() { lastDecodingErrorTime = US2NT(-10000000LL); someSortOfTriggerError = false; - memset(toothDurations, 0, sizeof(toothDurations)); curSignal = SHAFT_PRIMARY_FALLING; prevSignal = SHAFT_PRIMARY_FALLING; startOfCycleNt = 0; @@ -218,6 +217,16 @@ int TriggerState::getTotalRevolutionCounter() const { return totalRevolutionCounter; } +void TriggerStateWithRunningStatistics::resetTriggerState() { + TriggerState::resetTriggerState(); + + memset(timeOfLastEvent, 0, sizeof(timeOfLastEvent)); + memset(spinningEvents, 0, sizeof(spinningEvents)); + spinningEventIndex = 0; + prevInstantRpmValue = 0; + m_instantRpm = 0; +} + void TriggerStateWithRunningStatistics::movePreSynchTimestamps() { // here we take timestamps of events which happened prior to synchronization and place them // at appropriate locations diff --git a/firmware/controllers/trigger/trigger_decoder.h b/firmware/controllers/trigger/trigger_decoder.h index 178e54e1c9..5e5a6a9287 100644 --- a/firmware/controllers/trigger/trigger_decoder.h +++ b/firmware/controllers/trigger/trigger_decoder.h @@ -139,7 +139,7 @@ public: uint32_t totalTriggerErrorCounter; uint32_t orderingErrorCounter; - void resetTriggerState(); + virtual void resetTriggerState(); void setShaftSynchronized(bool value); bool getShaftSynchronized(); @@ -175,6 +175,7 @@ private: class TriggerStateWithRunningStatistics : public TriggerState { public: TriggerStateWithRunningStatistics(); + void resetTriggerState() override; float getInstantRpm() const { return m_instantRpm;