diff --git a/firmware/controllers/core/fsio_impl.cpp b/firmware/controllers/core/fsio_impl.cpp index 35e8146dbc..6b9b193ac7 100644 --- a/firmware/controllers/core/fsio_impl.cpp +++ b/firmware/controllers/core/fsio_impl.cpp @@ -141,7 +141,7 @@ FsioValue getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) { return engine->triggerCentral.getVVTPosition(); #endif case LE_METHOD_TIME_SINCE_TRIGGER_EVENT: - return engine->triggerCentral.getTimeSinceTriggerEvent(getTimeNowNt()); + return engine->triggerCentral.getTimeSinceTriggerEvent(); case LE_METHOD_TIME_SINCE_BOOT: #if EFI_MAIN_RELAY_CONTROL // in main relay control mode, we return the number of seconds since the ignition is turned on diff --git a/firmware/controllers/engine_cycle/rpm_calculator.cpp b/firmware/controllers/engine_cycle/rpm_calculator.cpp index f32670681e..5c4a6c3c37 100644 --- a/firmware/controllers/engine_cycle/rpm_calculator.cpp +++ b/firmware/controllers/engine_cycle/rpm_calculator.cpp @@ -94,6 +94,9 @@ RpmCalculator::RpmCalculator() : #endif /* EFI_PROD_CODE */ // todo: reuse assignRpmValue() method which needs PASS_ENGINE_PARAMETER_SUFFIX // which we cannot provide inside this parameter-less constructor. need a solution for this minor mess + + // we need this initial to have not_running at first invocation + lastRpmEventTimeNt = (efitick_t) DEEP_IN_THE_PAST_SECONDS * NT_PER_SECOND; } /** @@ -115,15 +118,11 @@ bool RpmCalculator::checkIfSpinning(efitick_t nowNt) const { * note that the result of this subtraction could be negative, that would happen if * we have a trigger event between the time we've invoked 'getTimeNow' and here */ - - // Anything below 60 rpm is not running - bool noRpmEventsForTooLong = lastTdcTimer.getElapsedSeconds(nowNt) > NO_RPM_EVENTS_TIMEOUT_SECS; - + bool noRpmEventsForTooLong = nowNt - lastRpmEventTimeNt >= NT_PER_SECOND * NO_RPM_EVENTS_TIMEOUT_SECS; // Anything below 60 rpm is not running /** * Also check if there were no trigger events */ - bool noTriggerEventsForTooLong = engine->triggerCentral.getTimeSinceTriggerEvent(nowNt) >= 1; - + bool noTriggerEventsForTooLong = nowNt - engine->triggerCentral.triggerState.previousShaftEventTimeNt >= NT_PER_SECOND; if (noRpmEventsForTooLong || noTriggerEventsForTooLong) { return false; } @@ -250,9 +249,8 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, if (index == 0) { bool hadRpmRecently = rpmState->checkIfSpinning(nowNt); - float periodSeconds = engine->rpmCalculator.lastTdcTimer.getElapsedSecondsAndReset(nowNt); - if (hadRpmRecently) { + efitick_t diffNt = nowNt - rpmState->lastRpmEventTimeNt; /** * Four stroke cycle is two crankshaft revolutions * @@ -260,16 +258,16 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, * and each revolution of crankshaft consists of two engine cycles revolutions * */ - if (periodSeconds == 0) { + if (diffNt == 0) { rpmState->setRpmValue(NOISY_RPM); } else { int mult = (int)getEngineCycle(engine->getOperationMode(PASS_ENGINE_PARAMETER_SIGNATURE)) / 360; - float rpm = 60 * mult / periodSeconds; + float rpm = 60.0 * NT_PER_SECOND * mult / diffNt; rpmState->setRpmValue(rpm > UNREALISTIC_RPM ? NOISY_RPM : rpm); } } - rpmState->onNewEngineCycle(); + rpmState->lastRpmEventTimeNt = nowNt; engine->isRpmHardLimit = GET_RPM() > engine->getRpmHardLimit(PASS_ENGINE_PARAMETER_SIGNATURE); } @@ -352,13 +350,16 @@ void tdcMarkCallback( * @return Current crankshaft angle, 0 to 720 for four-stroke */ float getCrankshaftAngleNt(efitick_t timeNt DECLARE_ENGINE_PARAMETER_SUFFIX) { - float timeSinceZeroAngle = engine->rpmCalculator.lastTdcTimer.getElapsedSeconds(timeNt); + efitick_t timeSinceZeroAngleNt = timeNt + - engine->rpmCalculator.lastRpmEventTimeNt; + /** + * even if we use 'getOneDegreeTimeUs' macros here, it looks like the + * compiler is not smart enough to figure out that "A / ( B / C)" could be optimized into + * "A * C / B" in order to replace a slower division with a faster multiplication. + */ int rpm = GET_RPM(); - - float oneDegreeSeconds = (60.0f / 360) / rpm; - - return rpm == 0 ? NAN : timeSinceZeroAngle / oneDegreeSeconds; + return rpm == 0 ? NAN : timeSinceZeroAngleNt / getOneDegreeTimeNt(rpm); } void initRpmCalculator(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { diff --git a/firmware/controllers/engine_cycle/rpm_calculator.h b/firmware/controllers/engine_cycle/rpm_calculator.h index 65702be588..2552788357 100644 --- a/firmware/controllers/engine_cycle/rpm_calculator.h +++ b/firmware/controllers/engine_cycle/rpm_calculator.h @@ -11,7 +11,6 @@ #include "globalaccess.h" #include "scheduler.h" #include "stored_value_sensor.h" -#include "timer.h" // we use this value in case of noise on trigger input lines #define NOISY_RPM -1 @@ -114,8 +113,7 @@ public: * NaN while engine is not spinning */ volatile floatus_t oneDegreeUs = NAN; - - Timer lastTdcTimer; + volatile efitick_t lastRpmEventTimeNt = 0; protected: // Print sensor info - current RPM state diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index 262d293b9b..625986bddd 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -34,6 +34,11 @@ void setFlatInjectorLag(float value DECLARE_CONFIG_PARAMETER_SUFFIX); */ #define getOneDegreeTimeUs(rpm) (1000000.0f * 60 / 360 / (rpm)) +/** + * @return float, time needed to rotate crankshaft by one degree, in native clicks. + */ +#define getOneDegreeTimeNt(rpm) (US2NT(1000000) * 60.0f / 360 / (rpm)) + floatms_t getCrankshaftRevolutionTimeMs(int rpm); floatms_t getEngineCycleDuration(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX); diff --git a/firmware/controllers/trigger/trigger_central.h b/firmware/controllers/trigger/trigger_central.h index 1cded0e064..20d2107a6e 100644 --- a/firmware/controllers/trigger/trigger_central.h +++ b/firmware/controllers/trigger/trigger_central.h @@ -44,8 +44,8 @@ public: void resetCounters(); void validateCamVvtCounters(); - float getTimeSinceTriggerEvent(efitick_t nowNt) const { - return m_lastEventTimer.getElapsedSeconds(nowNt); + float getTimeSinceTriggerEvent() const { + return m_lastEventTimer.getElapsedSeconds(); } TriggerNoiseFilter noiseFilter; diff --git a/unit_tests/tests/sensor/test_sensor_init.cpp b/unit_tests/tests/sensor/test_sensor_init.cpp index 01d01a56ec..dc23dd471f 100644 --- a/unit_tests/tests/sensor/test_sensor_init.cpp +++ b/unit_tests/tests/sensor/test_sensor_init.cpp @@ -82,7 +82,7 @@ TEST(SensorInit, TpsValuesTooClose) { // With no pin, it should be ok that they are the same // Should succeed, -0.51 volts apart - CONFIG(tps1_1AdcChannel) = EFI_ADC_NONE; + CONFIG(tps1_1AdcChannel) = ADC_CHANNEL_NONE; CONFIG(tpsMin) = 200; // 1.00 volt CONFIG(tpsMax) = 200; // 1.00 volts EXPECT_NO_FATAL_ERROR(initTps(PASS_CONFIG_PARAMETER_SIGNATURE));