/** * @brief Shaft position callback used by RPM calculation logic. * * This callback is invoked on interrupt thread. */ static void shaftPositionCallback(ShaftEvents ckpSignalType, int index) { itoa10(&shaft_signal_msg_index[1], index); if (ckpSignalType == SHAFT_PRIMARY_UP) { addWaveChartEvent("crank", "up", shaft_signal_msg_index); } else if (ckpSignalType == SHAFT_PRIMARY_DOWN) { addWaveChartEvent("crank", "down", shaft_signal_msg_index); } else if (ckpSignalType == SHAFT_SECONDARY_UP) { addWaveChartEvent("crank2", "up", shaft_signal_msg_index); } else if (ckpSignalType == SHAFT_SECONDARY_DOWN) { addWaveChartEvent("crank2", "down", shaft_signal_msg_index); } if (index != 0) { #if EFI_PROD_CODE || EFI_SIMULATOR if (engineConfiguration->analogChartMode == AC_TRIGGER) acAddData(getCrankshaftAngle(chTimeNow()), 1000 * ckpSignalType + index); #endif return; } rpmState.revolutionCounter++; time_t now = chTimeNow(); int hadRpmRecently = isRunning(); if (hadRpmRecently) { if (isNoisySignal(&rpmState, now)) { // unexpected state. Noise? rpmState.rpm = NOISY_RPM; } else { int diff = now - rpmState.lastRpmEventTime; // 60000 because per minute // * 2 because each revolution of crankshaft consists of two camshaft revolutions // / 4 because each cylinder sends a signal // need to measure time from the previous non-skipped event int rpm = (int)(60000 * TICKS_IN_MS / engineConfiguration->rpmMultiplier / diff); rpmState.rpm = rpm > UNREALISTIC_RPM ? NOISY_RPM : rpm; } } rpmState.lastRpmEventTime = now; #if EFI_PROD_CODE || EFI_SIMULATOR if (engineConfiguration->analogChartMode == AC_TRIGGER) acAddData(getCrankshaftAngle(now), index); #endif }
/** * @brief Shaft position callback used by RPM calculation logic. * * This callback should always be the first of trigger callbacks because other callbacks depend of values * updated here. * This callback is invoked on interrupt thread. */ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t index DECLARE_ENGINE_PARAMETER_S) { RpmCalculator *rpmState = &engine->rpmCalculator; uint64_t nowNt = getTimeNowNt(); #if EFI_PROD_CODE efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "lowstck#2z"); #endif if (index != 0) { #if EFI_ANALOG_CHART || defined(__DOXYGEN__) if (boardConfiguration->analogChartMode == AC_TRIGGER) acAddData(getCrankshaftAngleNt(nowNt PASS_ENGINE_PARAMETER), 1000 * ckpSignalType + index); #endif return; } bool hadRpmRecently = rpmState->isRunning(PASS_ENGINE_PARAMETER_F); if (hadRpmRecently) { uint64_t diffNt = nowNt - rpmState->lastRpmEventTimeNt; /** * Four stroke cycle is two crankshaft revolutions * * We always do '* 2' because the event signal is already adjusted to 'per engine cycle' * and each revolution of crankshaft consists of two engine cycles revolutions * */ if (diffNt == 0) { rpmState->setRpmValue(NOISY_RPM); } else { int mult = engineConfiguration->engineCycle / 360; int rpm = (int) (60 * US2NT(US_PER_SECOND_LL) * mult / diffNt); rpmState->setRpmValue(rpm > UNREALISTIC_RPM ? NOISY_RPM : rpm); } } rpmState->onNewEngineCycle(); rpmState->lastRpmEventTimeNt = nowNt; #if EFI_ANALOG_CHART || defined(__DOXYGEN__) if (boardConfiguration->analogChartMode == AC_TRIGGER) acAddData(getCrankshaftAngleNt(nowNt PASS_ENGINE_PARAMETER), index); #endif }