From e2841e689d088a905b64ea3ca954fae7a1771c19 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 9 Jan 2020 12:45:13 -0800 Subject: [PATCH] Require tooth reference time for scheduleByAngle (#1091) * injection * injectors * add edge timestamp to ShaftPositionListener * scheduleByAngle require edgeTimestamp * schedule with nt not us * oops, these were missing from this branch --- .../engine_cycle/main_trigger_callback.cpp | 2 +- .../controllers/engine_cycle/map_averaging.cpp | 6 +++--- .../controllers/engine_cycle/rpm_calculator.cpp | 15 +++++++++------ .../controllers/engine_cycle/rpm_calculator.h | 2 +- firmware/controllers/gauges/tachometer.cpp | 2 +- firmware/controllers/system/timer/scheduler.h | 1 + .../system/timer/signal_executor_sleep.cpp | 4 ++++ .../system/timer/signal_executor_sleep.h | 1 + .../system/timer/single_timer_executor.cpp | 6 +++++- .../system/timer/single_timer_executor.h | 1 + firmware/controllers/trigger/trigger_central.cpp | 2 +- firmware/controllers/trigger/trigger_central.h | 2 +- firmware/development/logic_analyzer.cpp | 5 +++-- firmware/hw_layer/hip9011.cpp | 6 +++--- unit_tests/global_execution_queue.cpp | 4 ++++ unit_tests/global_execution_queue.h | 1 + 16 files changed, 40 insertions(+), 20 deletions(-) diff --git a/firmware/controllers/engine_cycle/main_trigger_callback.cpp b/firmware/controllers/engine_cycle/main_trigger_callback.cpp index be8ad368fd..b9ba0b73b2 100644 --- a/firmware/controllers/engine_cycle/main_trigger_callback.cpp +++ b/firmware/controllers/engine_cycle/main_trigger_callback.cpp @@ -414,7 +414,7 @@ uint32_t *cyccnt = (uint32_t*) &DWT->CYCCNT; * This is the main trigger event handler. * Both injection and ignition are controlled from this method. */ -static void mainTriggerCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex DECLARE_ENGINE_PARAMETER_SUFFIX) { +static void mainTriggerCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { ScopePerf perf(PE::MainTriggerCallback); (void) ckpSignalType; diff --git a/firmware/controllers/engine_cycle/map_averaging.cpp b/firmware/controllers/engine_cycle/map_averaging.cpp index 72183c3121..365a736205 100644 --- a/firmware/controllers/engine_cycle/map_averaging.cpp +++ b/firmware/controllers/engine_cycle/map_averaging.cpp @@ -263,7 +263,7 @@ void refreshMapAveragingPreCalc(DECLARE_ENGINE_PARAMETER_SIGNATURE) { * Shaft Position callback used to schedule start and end of MAP averaging */ static void mapAveragingTriggerCallback(trigger_event_e ckpEventType, - uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { + uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { ScopePerf perf(PE::MapAveragingTriggerCallback); @@ -313,9 +313,9 @@ static void mapAveragingTriggerCallback(trigger_event_e ckpEventType, // at the moment we schedule based on time prediction based on current RPM and angle // we are loosing precision in case of changing RPM - the further away is the event the worse is precision // todo: schedule this based on closest trigger event, same as ignition works - scheduleByAngle(&startTimer[i][structIndex], samplingStart, + scheduleByAngle(&startTimer[i][structIndex], edgeTimestamp, samplingStart, startAveraging PASS_ENGINE_PARAMETER_SUFFIX); - scheduleByAngle(&endTimer[i][structIndex], samplingEnd, + scheduleByAngle(&endTimer[i][structIndex], edgeTimestamp, samplingEnd, endAveraging PASS_ENGINE_PARAMETER_SUFFIX); engine->m.mapAveragingCbTime = getTimeNowLowerNt() - engine->m.beforeMapAveragingCb; diff --git a/firmware/controllers/engine_cycle/rpm_calculator.cpp b/firmware/controllers/engine_cycle/rpm_calculator.cpp index 0082536b6d..29a616718c 100644 --- a/firmware/controllers/engine_cycle/rpm_calculator.cpp +++ b/firmware/controllers/engine_cycle/rpm_calculator.cpp @@ -227,8 +227,7 @@ void RpmCalculator::setSpinningUp(efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFI * This callback is invoked on interrupt thread. */ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, - uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { - efitick_t nowNt = getTimeNowNt(); + uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { efiAssertVoid(CUSTOM_ERR_6632, getCurrentRemainingStack() > EXPECTED_REMAINING_STACK, "lowstckRCL"); RpmCalculator *rpmState = &engine->rpmCalculator; @@ -313,7 +312,7 @@ static void onTdcCallback(Engine *engine) { * This trigger callback schedules the actual physical TDC callback in relation to trigger synchronization point. */ static void tdcMarkCallback(trigger_event_e ckpSignalType, - uint32_t index0 DECLARE_ENGINE_PARAMETER_SUFFIX) { + uint32_t index0, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { (void) ckpSignalType; bool isTriggerSynchronizationPoint = index0 == 0; if (isTriggerSynchronizationPoint && ENGINE(isEngineChartEnabled)) { @@ -322,7 +321,7 @@ static void tdcMarkCallback(trigger_event_e ckpSignalType, int rpm = GET_RPM(); // todo: use tooth event-based scheduling, not just time-based scheduling if (isValidRpm(rpm)) { - scheduleByAngle(&tdcScheduler[revIndex2], tdcPosition(), + scheduleByAngle(&tdcScheduler[revIndex2], edgeTimestamp, tdcPosition(), { onTdcCallback, engine } PASS_ENGINE_PARAMETER_SUFFIX); } } @@ -361,10 +360,14 @@ void initRpmCalculator(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { * The callback would be executed once after the duration of time which * it takes the crankshaft to rotate to the specified angle. */ -void scheduleByAngle(scheduling_s *timer, angle_t angle, +void scheduleByAngle(scheduling_s *timer, efitick_t edgeTimestamp, angle_t angle, action_s action DECLARE_ENGINE_PARAMETER_SUFFIX) { float delayUs = ENGINE(rpmCalculator.oneDegreeUs) * angle; - ENGINE(executor.scheduleForLater(timer, (int) delayUs, action)); + + efitime_t delayNt = US2NT(delayUs); + efitime_t delayedTime = edgeTimestamp + delayNt; + + ENGINE(executor.scheduleByTimestampNt(timer, delayedTime, action)); } #else diff --git a/firmware/controllers/engine_cycle/rpm_calculator.h b/firmware/controllers/engine_cycle/rpm_calculator.h index 96e6f61254..89251a89c3 100644 --- a/firmware/controllers/engine_cycle/rpm_calculator.h +++ b/firmware/controllers/engine_cycle/rpm_calculator.h @@ -165,5 +165,5 @@ float getCrankshaftAngleNt(efitick_t timeNt DECLARE_ENGINE_PARAMETER_SUFFIX); #define addEngineSnifferEvent(n, msg) {} #endif /* EFI_ENGINE_SNIFFER */ -void scheduleByAngle(scheduling_s *timer, angle_t angle, action_s action DECLARE_ENGINE_PARAMETER_SUFFIX); +void scheduleByAngle(scheduling_s *timer, efitick_t edgeTimestamp, angle_t angle, action_s action DECLARE_ENGINE_PARAMETER_SUFFIX); diff --git a/firmware/controllers/gauges/tachometer.cpp b/firmware/controllers/gauges/tachometer.cpp index f4edb49aec..17a9e4ce8c 100644 --- a/firmware/controllers/gauges/tachometer.cpp +++ b/firmware/controllers/gauges/tachometer.cpp @@ -24,7 +24,7 @@ static void turnTachPinLow(void *) { } static void tachSignalCallback(trigger_event_e ckpSignalType, - uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { + uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { UNUSED(ckpSignalType); if (index != (uint32_t)engineConfiguration->tachPulseTriggerIndex) { return; diff --git a/firmware/controllers/system/timer/scheduler.h b/firmware/controllers/system/timer/scheduler.h index a6a541744b..a1f66acc19 100644 --- a/firmware/controllers/system/timer/scheduler.h +++ b/firmware/controllers/system/timer/scheduler.h @@ -59,5 +59,6 @@ struct ExecutorInterface { * see also scheduleByAngle */ virtual void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, action_s action) = 0; + virtual void scheduleByTimestampNt(scheduling_s *scheduling, efitime_t timeUs, action_s action) = 0; virtual void scheduleForLater(scheduling_s *scheduling, int delayUs, action_s action) = 0; }; diff --git a/firmware/controllers/system/timer/signal_executor_sleep.cpp b/firmware/controllers/system/timer/signal_executor_sleep.cpp index 3e80d7c6e2..2579571006 100644 --- a/firmware/controllers/system/timer/signal_executor_sleep.cpp +++ b/firmware/controllers/system/timer/signal_executor_sleep.cpp @@ -37,6 +37,10 @@ void SleepExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t ti scheduleForLater(scheduling, timeUs - getTimeNowUs(), action); } +void SleepExecutor::scheduleByTimestampNt(scheduling_s* scheduling, efitick_t timeNt, action_s action) { + scheduleByTimestamp(scheduling, NT2US(timeNt), action); +} + static void timerCallback(scheduling_s *scheduling) { #if EFI_PRINTF_FUEL_DETAILS if (scheduling->action.getCallback() == (schfunc_t)&seTurnPinLow) { diff --git a/firmware/controllers/system/timer/signal_executor_sleep.h b/firmware/controllers/system/timer/signal_executor_sleep.h index 2a48c902fe..55bd3728d2 100644 --- a/firmware/controllers/system/timer/signal_executor_sleep.h +++ b/firmware/controllers/system/timer/signal_executor_sleep.h @@ -13,6 +13,7 @@ class SleepExecutor : public ExecutorInterface { public: void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, action_s action) override; + void scheduleByTimestampNt(scheduling_s *scheduling, efitick_t timeNt, action_s action) override; void scheduleForLater(scheduling_s *scheduling, int delayUs, action_s action) override; }; diff --git a/firmware/controllers/system/timer/single_timer_executor.cpp b/firmware/controllers/system/timer/single_timer_executor.cpp index b4553cad1e..414689938a 100644 --- a/firmware/controllers/system/timer/single_timer_executor.cpp +++ b/firmware/controllers/system/timer/single_timer_executor.cpp @@ -81,6 +81,10 @@ void SingleTimerExecutor::scheduleForLater(scheduling_s *scheduling, int delayUs * @param [in] dwell the number of ticks of output duration. */ void SingleTimerExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, action_s action) { + scheduleByTimestampNt(scheduling, US2NT(timeUs), action); +} + +void SingleTimerExecutor::scheduleByTimestampNt(scheduling_s* scheduling, efitime_t nt, action_s action) { ScopePerf perf(PE::SingleTimerExecutorScheduleByTimestamp); scheduleCounter++; @@ -89,7 +93,7 @@ void SingleTimerExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeu // this would guard the queue and disable interrupts alreadyLocked = lockAnyContext(); } - bool needToResetTimer = queue.insertTask(scheduling, US2NT(timeUs), action); + bool needToResetTimer = queue.insertTask(scheduling, nt, action); if (!reentrantFlag) { doExecute(); if (needToResetTimer) { diff --git a/firmware/controllers/system/timer/single_timer_executor.h b/firmware/controllers/system/timer/single_timer_executor.h index 2f19283785..cadffaee30 100644 --- a/firmware/controllers/system/timer/single_timer_executor.h +++ b/firmware/controllers/system/timer/single_timer_executor.h @@ -15,6 +15,7 @@ class SingleTimerExecutor : public ExecutorInterface { public: SingleTimerExecutor(); void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, action_s action) override; + void scheduleByTimestampNt(scheduling_s *scheduling, efitime_t timeNt, action_s action) override; void scheduleForLater(scheduling_s *scheduling, int delayUs, action_s action) override; void onTimerCallback(); int timerCallbackCounter; diff --git a/firmware/controllers/trigger/trigger_central.cpp b/firmware/controllers/trigger/trigger_central.cpp index 60af428d30..364f0cbf9f 100644 --- a/firmware/controllers/trigger/trigger_central.cpp +++ b/firmware/controllers/trigger/trigger_central.cpp @@ -393,7 +393,7 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta */ for (int i = 0; i < triggerListeneres.currentListenersCount; i++) { ShaftPositionListener listener = (ShaftPositionListener) (void*) triggerListeneres.callbacks[i]; - (listener)(signal, triggerIndexForListeners PASS_ENGINE_PARAMETER_SUFFIX); + (listener)(signal, triggerIndexForListeners, timestamp PASS_ENGINE_PARAMETER_SUFFIX); } } diff --git a/firmware/controllers/trigger/trigger_central.h b/firmware/controllers/trigger/trigger_central.h index 2ce33db5b0..41a2f58df5 100644 --- a/firmware/controllers/trigger/trigger_central.h +++ b/firmware/controllers/trigger/trigger_central.h @@ -13,7 +13,7 @@ #include "trigger_central_generated.h" class Engine; -typedef void (*ShaftPositionListener)(trigger_event_e signal, uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX); +typedef void (*ShaftPositionListener)(trigger_event_e signal, uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX); #define HAVE_CAM_INPUT() engineConfiguration->camInputs[0] != GPIO_UNASSIGNED diff --git a/firmware/development/logic_analyzer.cpp b/firmware/development/logic_analyzer.cpp index 636fb37be1..5b9b251779 100644 --- a/firmware/development/logic_analyzer.cpp +++ b/firmware/development/logic_analyzer.cpp @@ -128,12 +128,13 @@ WaveReader::WaveReader() { hw = nullptr; } -static void waTriggerEventListener(trigger_event_e ckpSignalType, uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { +static void waTriggerEventListener(trigger_event_e ckpSignalType, uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { (void)ckpSignalType; if (index != 0) { return; } - efitimeus_t nowUs = getTimeNowUs(); + + efitimeus_t nowUs = NT2US(edgeTimestamp); engineCycleDurationUs = nowUs - previousEngineCycleTimeUs; previousEngineCycleTimeUs = nowUs; } diff --git a/firmware/hw_layer/hip9011.cpp b/firmware/hw_layer/hip9011.cpp index 6479e109e8..6bbc3a37cd 100644 --- a/firmware/hw_layer/hip9011.cpp +++ b/firmware/hw_layer/hip9011.cpp @@ -248,7 +248,7 @@ static void endIntegration(void *) { /** * Shaft Position callback used to start or finish HIP integration */ -static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { +static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { (void)ckpEventType; // this callback is invoked on interrupt thread if (index != 0) @@ -261,12 +261,12 @@ static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index DECLARE int structIndex = getRevolutionCounter() % 2; // todo: schedule this based on closest trigger event, same as ignition works - scheduleByAngle(&startTimer[structIndex], engineConfiguration->knockDetectionWindowStart, + scheduleByAngle(&startTimer[structIndex], edgeTimestamp, engineConfiguration->knockDetectionWindowStart, &startIntegration); #if EFI_PROD_CODE hipLastExecutionCount = lastExecutionCount; #endif /* EFI_PROD_CODE */ - scheduleByAngle(&endTimer[structIndex], engineConfiguration->knockDetectionWindowEnd, + scheduleByAngle(&endTimer[structIndex], edgeTimestamp, engineConfiguration->knockDetectionWindowEnd, &endIntegration); engine->m.hipCbTime = getTimeNowLowerNt() - engine->m.beforeHipCb; } diff --git a/unit_tests/global_execution_queue.cpp b/unit_tests/global_execution_queue.cpp index 859ee3fbe2..0cd69ee228 100644 --- a/unit_tests/global_execution_queue.cpp +++ b/unit_tests/global_execution_queue.cpp @@ -39,3 +39,7 @@ void TestExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t tim } schedulingQueue.insertTask(scheduling, timeUs, action); } + +void TestExecutor::scheduleByTimestampNt(scheduling_s* scheduling, efitick_t timeNt, action_s action) { + scheduleByTimestamp(scheduling, NT2US(timeNt), action); +} diff --git a/unit_tests/global_execution_queue.h b/unit_tests/global_execution_queue.h index b89ee14bc9..b1e341d741 100644 --- a/unit_tests/global_execution_queue.h +++ b/unit_tests/global_execution_queue.h @@ -14,6 +14,7 @@ class TestExecutor : public ExecutorInterface { public: void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, action_s action) override; + void scheduleByTimestampNt(scheduling_s *scheduling, efitick_t timeNt, action_s action) override; void scheduleForLater(scheduling_s *scheduling, int delayUs, action_s action) override; void clear(); int executeAll(efitime_t now);