diff --git a/firmware/controllers/math/efitime.h b/firmware/controllers/math/efitime.h index 386bb84607..11aabafe94 100644 --- a/firmware/controllers/math/efitime.h +++ b/firmware/controllers/math/efitime.h @@ -39,6 +39,9 @@ extern "C" * * By using 64 bit, we can achieve a very precise timestamp which does not overflow. * The primary implementation counts the number of CPU cycles from MCU reset. + * + * WARNING: you should use getTimeNowNt where possible for performance reasons. + * The heaviest part is '__aeabi_ildivmod' - non-native 64 bit division */ uint64_t getTimeNowUs(void); diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 1e06f52b95..d526173097 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -225,6 +225,7 @@ void showMainHistogram(void) { #endif } +// todo: eliminate this 'extern' extern Engine engine; /** diff --git a/firmware/controllers/trigger/rpm_calculator.cpp b/firmware/controllers/trigger/rpm_calculator.cpp index 7dd19ed130..9c446db39b 100644 --- a/firmware/controllers/trigger/rpm_calculator.cpp +++ b/firmware/controllers/trigger/rpm_calculator.cpp @@ -102,17 +102,17 @@ bool isCranking(void) { * This callback is invoked on interrupt thread. */ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t index, RpmCalculator *rpmState) { + uint64_t nowUs = getTimeNowUs(); if (index != 0) { #if EFI_ANALOG_CHART || defined(__DOXYGEN__) if (engineConfiguration->analogChartMode == AC_TRIGGER) - acAddData(getCrankshaftAngle(getTimeNowUs()), 1000 * ckpSignalType + index); + acAddData(getCrankshaftAngle(nowUs), 1000 * ckpSignalType + index); #endif return; } rpmState->revolutionCounter++; - uint64_t nowUs = getTimeNowUs(); bool hadRpmRecently = rpmState->isRunning(); diff --git a/firmware/hw_layer/microsecond_timer.c b/firmware/hw_layer/microsecond_timer.c index 460277d47b..c51e3bdc65 100644 --- a/firmware/hw_layer/microsecond_timer.c +++ b/firmware/hw_layer/microsecond_timer.c @@ -22,7 +22,7 @@ #define GPTDEVICE GPTD5 -static volatile uint64_t lastSetTimerTime; +static volatile uint64_t lastSetTimerTimeNt; static int lastSetTimerValue; static volatile bool isTimerPending = FALSE; @@ -45,7 +45,7 @@ void setHardwareUsTimer(int32_t timeUs) { gptStopTimerI(&GPTDEVICE); gptStartOneShotI(&GPTDEVICE, timeUs); - lastSetTimerTime = getTimeNowUs(); + lastSetTimerTimeNt = getTimeNowNt(); lastSetTimerValue = timeUs; isTimerPending = TRUE; timerRestartCounter++; @@ -85,7 +85,7 @@ static msg_t mwThread(int param) { while (TRUE) { chThdSleepMilliseconds(1000); // once a second is enough - if (getTimeNowUs() >= lastSetTimerTime + 2 * US_PER_SECOND) { + if (getTimeNowNt() >= lastSetTimerTimeNt + 2 * CORE_CLOCK) { strcpy(buff, "no_event"); itoa10(&buff[8], lastSetTimerValue); firmwareError(buff); @@ -94,7 +94,7 @@ static msg_t mwThread(int param) { msg = isTimerPending ? "No_cb too long" : "Timer not awhile"; // 2 seconds of inactivity would not look right - efiAssert(getTimeNowUs() < lastSetTimerTime + 2 * US_PER_SECOND, msg, -1); + efiAssert(getTimeNowNt() < lastSetTimerTimeNt + 2 * CORE_CLOCK, msg, -1); } #if defined __GNUC__ return -1; @@ -111,7 +111,7 @@ void initMicrosecondTimer(void) { gptStart(&GPTDEVICE, &gpt5cfg); - lastSetTimerTime = getTimeNowUs(); + lastSetTimerTimeNt = getTimeNowNt(); #if EFI_EMULATE_POSITION_SENSORS chThdCreateStatic(mwThreadStack, sizeof(mwThreadStack), NORMALPRIO, (tfunc_t) mwThread, NULL); #endif /* EFI_ENGINE_EMULATOR */ diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index c120f61b76..f7c11eaf57 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -339,11 +339,16 @@ void testGY6_139QMB(void) { extern EventQueue schedulingQueue; +// this is a very dirty and sad hack. todo: eliminate +extern Engine engine; + static void testRpmCalculator(void) { printf("*************************************************** testRpmCalculator\r\n"); EngineTestHelper eth(FORD_INLINE_6_1995); + efiAssertVoid(eth.engine.engineConfiguration!=NULL, "null config in engine"); + initThermistors(ð.engine); engine_configuration_s *ec = ð.persistentConfig.engineConfiguration; @@ -354,6 +359,9 @@ static void testRpmCalculator(void) { ec->globalFuelCorrection = 3; eth.initTriggerShapeAndRpmCalculator(); + // this is a very dirty and sad hack. todo: eliminate + engine.engineConfiguration = eth.engine.engineConfiguration; + configuration_s configuration = { ec, ec2 }; timeNow = 0; assertEquals(0, eth.rpmState.rpm());