rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
engine.cpp
Go to the documentation of this file.
1/**
2 * @file engine.cpp
3 *
4 *
5 * This might be a http://en.wikipedia.org/wiki/God_object but that's best way I can
6 * express myself in C/C++. I am open for suggestions :)
7 *
8 * @date May 21, 2014
9 * @author Andrey Belomutskiy, (c) 2012-2020
10 */
11
12#include "pch.h"
13
14#include "trigger_central.h"
15#include "fuel_math.h"
16#include "advance_map.h"
17#include "speed_density.h"
18#include "advance_map.h"
19#include "init.h"
20
21#include "aux_valves.h"
22#include "perf_trace.h"
23#include "backup_ram.h"
24#include "idle_thread.h"
25#include "idle_hardware.h"
26#include "gppwm.h"
27#include "speedometer.h"
28#include "dynoview.h"
29#include "boost_control.h"
30#include "ac_control.h"
31#include "vr_pwm.h"
32#include "max3185x.h"
33#if EFI_MC33816
34 #include "mc33816.h"
35#endif // EFI_MC33816
36
37#include "bench_test.h"
38
39#if EFI_PROD_CODE
41#endif /* EFI_PROD_CODE */
42
43#if (BOARD_TLE8888_COUNT > 0)
44#include "gpio/tle8888.h"
45#endif
46
47#if EFI_ENGINE_SNIFFER
48#include "engine_sniffer.h"
49extern int waveChartUsedSize;
50extern WaveChart waveChart;
51#endif /* EFI_ENGINE_SNIFFER */
52
54#if EFI_ENGINE_SNIFFER
56 // TODO: what is the exact reasoning for the exact engine sniffer pause time I wonder
59 }
60#endif /* EFI_ENGINE_SNIFFER */
61}
62
64 criticalError("Broken VVT mode maybe corrupted calibration %d: %s", vvtMode, getVvt_mode_e(vvtMode));
65 return trigger_type_e::TT_HALF_MOON; // we have to return something for the sake of -Werror=return-type
66}
67
68// todo: move this method from engine.cpp already?
69/**
70 * VVT decoding delegates to universal trigger decoder. Here we map vvt_mode_e into corresponding trigger_type_e
71 */
73 switch (vvtMode) {
74 case VVT_CUSTOM_1:
75 case VVT_CUSTOM_2:
76 case VVT_INACTIVE:
77 // hold on, what? 'VVT_INACTIVE' means TT_HALF_MOON?!
79 case VVT_TOYOTA_3_TOOTH:
81 case VVT_MIATA_NB:
83 case VVT_BOSCH_QUICK_START:
85 case VVT_HONDA_K_EXHAUST:
87 case VVT_HONDA_K_INTAKE:
88 case VVT_SINGLE_TOOTH:
89 case VVT_MAP_V_TWIN:
91 case VVT_FORD_ST170:
93 case VVT_BARRA_3_PLUS_1:
95 case VVT_FORD_COYOTE:
97 case VVT_DEV:
99 case VVT_MAZDA_SKYACTIV:
101 case VVT_MAZDA_L:
103 case VVT_NISSAN_VQ:
105 case VVT_TOYOTA_4_1:
107 case VVT_MITSUBISHI_4G69:
109 case VVT_MITSUBISHI_3A92:
111 case VVT_MITSUBISHI_6G72:
113 case VVT_HONDA_CBR_600:
115 case VVT_CHRYSLER_PHASER:
117 case VVT_TOYOTA_3TOOTH_UZ:
119 case VVT_NISSAN_MR:
121 case VVT_UNUSED_17:
122 case VVT_MITSUBISHI_4G63:
124 case VVT_HR12DDR_IN:
126 case VVT_SUBARU_7TOOTH:
128 default:
129 return getCustomVvtTriggerType(vvtMode);
130 }
131}
132
134#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
135 // we have a confusing threading model so some synchronization would not hurt
136 chibios_rt::CriticalSectionLocker csl;
137
139
142 }
143#endif /* EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT */
144}
145
146PUBLIC_API_WEAK void boardPeriodicSlowCallback() { }
147
148PUBLIC_API_WEAK void boardPeriodicFastCallback() { }
149
152
153#if EFI_SHAFT_POSITION_INPUT
154 // Re-read config in case it's changed
156 for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
158 }
159
161 enginePins.o2heater.setValue(getEngineState()->heaterControlEnabled);
163#endif // EFI_SHAFT_POSITION_INPUT
164
165 efiWatchdog();
168
169 module<TpsAccelEnrichment>()->onNewValue(Sensor::getOrZero(SensorType::Tps1));
170
172
173 updateGppwm();
174
175 engine->engineModules.apply_all([](auto & m) { m.onSlowCallback(); });
176
177#if (BOARD_TLE8888_COUNT > 0)
179#endif
180
181#if EFI_DYNO_VIEW
183#endif
184
185 // TODO: move to sensor_checker.cpp?
187 // undervoltage crancking!
188 if (getEngineState()->undervoltageCrankingTimer.getElapsedSeconds() > 1) {
189 warningTsReport(ObdCode::OBD_System_Voltage_Low, "Cranking on low battery!");
190 }
191 } else {
193 }
194
196
197#if EFI_PROD_CODE
198 void baroLps25Update();
200#endif // EFI_PROD_CODE
202}
203
204/**
205 * We are executing these heavy (logarithm) methods from outside the trigger callbacks for performance reasons.
206 * See also periodicFastCallback
207 */
210
211#if EFI_PROD_CODE
212 // todo: extract method? do better? see https://github.com/rusefi/rusefi/issues/7511 for details
213 engine->module<InjectorModelSecondary>()->updateState();
214 engine->module<InjectorModelPrimary>()->updateState();
215#endif // EFI_PROD_CODE
216
217#if EFI_SHAFT_POSITION_INPUT
220#endif // EFI_SHAFT_POSITION_INPUT
221}
222
224#if EFI_GPIO_HARDWARE
227 }
228#endif // EFI_GPIO_HARDWARE
229 // todo: boolean sensors should leverage sensor framework #6342
231}
232
233static bool getClutchUpState() {
234#if EFI_GPIO_HARDWARE
237 }
238#endif // EFI_GPIO_HARDWARE
239 // todo: boolean sensors should leverage sensor framework #6342
241}
242
244#if EFI_GPIO_HARDWARE
247 }
248#endif // EFI_GPIO_HARDWARE
249 // todo: boolean sensors should leverage sensor framework #6342
251}
252
253
255 // this value is not used yet
259#if EFI_GPIO_HARDWARE
260 {
261 bool currentState;
262 if (hasAcToggle()) {
263 currentState = getAcToggle();
264#ifdef EFI_KLINE
265 } else if (engineConfiguration->hondaK) {
266extern bool kAcRequestState;
267 currentState = kAcRequestState;
268#endif // EFI_KLINE
269 } else {
270 currentState = engine->engineState.lua.acRequestState;
271 }
272 AcController & acController = engine->module<AcController>().unmock();
273 if (engine->acButtonSwitchedState.update(currentState)) {
274 acController.timeSinceStateChange.reset();
275 }
276 }
277
279
280#endif // EFI_GPIO_HARDWARE
281}
282
284 // Everything else has default initializers setup in generated file
287}
288
292
294 /**
295 * it's important for wrapAngle() that engineCycle field never has zero
296 */
298 resetLua();
299}
300
302 // todo: https://github.com/rusefi/rusefi/issues/4308
303 engineState.lua = {};
307 engineState.lua.luaIgnCut = false;
308 engineState.lua.luaFuelCut = false;
310#if EFI_BOOST_CONTROL
311 module<BoostController>().unmock().resetLua();
312#endif // EFI_BOOST_CONTROL
315#if EFI_IDLE_CONTROL
316 module<IdleController>().unmock().luaAdd = 0;
317#endif // EFI_IDLE_CONTROL
318}
319
320/**
321 * Here we have a bunch of stuff which should invoked after configuration change
322 * so that we can prepare some helper structures
323 */
325#if EFI_TUNER_STUDIO
326 // we take 2 bytes of crc32, no idea if it's right to call it crc16 or not
327 // we have a hack here - we rely on the fact that engineMake is the first of three relevant fields
329
331#endif /* EFI_TUNER_STUDIO */
332}
333
334#if EFI_SHAFT_POSITION_INPUT
340
344
346 // Needed for early instant-RPM detection
348
351
352 for (size_t i = 0; i < efi::size(triggerCentral.vvtState); i++) {
353 for (size_t j = 0; j < efi::size(triggerCentral.vvtState[0]); j++) {
355 }
356 }
357}
358
359void Engine::OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError) {
360 // TODO: this logic probably shouldn't be part of engine.cpp
361
362 // We only care about trigger shape once we have synchronized trigger. Anything could happen
363 // during first revolution and it's fine
364 if (wasSynchronized) {
366
367 // 'triggerStateListener is not null' means we are running a real engine and now just preparing trigger shape
368 // that's a bit of a hack, a sweet OOP solution would be a real callback or at least 'needDecodingErrorLogic' method?
369 if (isDecodingError) {
370#if EFI_PROD_CODE
372 efiPrintf("error: synchronizationPoint @ index %lu expected %d/%d got %d/%d",
378 }
379#endif /* EFI_PROD_CODE */
380 }
381
382 engine->triggerCentral.triggerErrorDetection.add(isDecodingError);
383 }
384
385}
386#endif
387
389#if EFI_SHAFT_POSITION_INPUT
391 for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
393 }
394#endif // EFI_SHAFT_POSITION_INPUT
395}
396
398#if !EFI_UNIT_TEST
399// huh should this be happy? static_assert(config != nullptr);
400#endif
401 efi::clear(config);
402
404}
405
406/**
407 * This code asserts that we do not have unexpected gaps in time flow with the exception of internal flash burn.
408 */
409static void assertTimeIsLinear() {
410#if ! EFI_UNIT_TEST
411 static efitimems_t mostRecentMs = 0;
412 efitimems_t msNow = getTimeNowMs();
414 if (mostRecentMs != 0) {
415 efitimems_t gapInMs = msNow - mostRecentMs;
416 // todo: lower gapInMs threshold?
417 if (gapInMs > 200) {
418 firmwareError(ObdCode::RUNTIME_CRITICAL_WATCH_DOG_SECONDS, "gap in time: mostRecentMs %lumS, now=%lumS, gap=%lumS",
419 mostRecentMs, msNow, gapInMs);
420 }
421 }
422 }
423 mostRecentMs = msNow;
424#endif
425}
426
430 return;
431
432#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
433 if (module<PrimeController>()->isPriming() || triggerCentral.engineMovedRecently()) {
434 // do not invoke check in priming or if engine moved recently, no need to assert safe pin state.
435 return;
436 }
437
440 // todo: make this a firmwareError assuming functional tests would run
441 warning(ObdCode::CUSTOM_ERR_2ND_WATCHDOG, "Some pins were turned off by 2nd pass watchdog");
442 }
443 return;
444 }
445
446 /**
447 * todo: better watch dog implementation should be implemented - see
448 * http://sourceforge.net/p/rusefi/tickets/96/
449 */
452#endif // EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
453}
454
456#if EFI_ENGINE_CONTROL
457 ignitionEvents.isReady = false;
458#endif // EFI_ENGINE_CONTROL
459
460#if EFI_PROD_CODE || EFI_SIMULATOR
461 efiPrintf("Engine has stopped spinning.");
462#endif
463
464 // this invocation should be the last layer of defence in terms of making sure injectors/coils are not active
466}
467
469#if EFI_MAIN_RELAY_CONTROL
470 // if we are already in the "ignition_on" mode, then do nothing
471/* this logic is not alive
472 if (ignitionOnTimeNt > 0) {
473 return;
474 }
475todo: move to shutdown_controller.cpp
476*/
477
478 // here we are in the shutdown (the ignition is off) or initial mode (after the firmware fresh start)
479/* this needs work or tests
480 const efitick_t engineStopWaitTimeoutUs = 500000LL; // 0.5 sec
481 // in shutdown mode, we need a small cooldown time between the ignition off and on
482todo: move to shutdown_controller.cpp
483 if (stopEngineRequestTimeNt == 0 || (getTimeNowNt() - stopEngineRequestTimeNt) > US2NT(engineStopWaitTimeoutUs)) {
484 // if the ignition key is turned on again,
485 // we cancel the shutdown mode, but only if all shutdown procedures are complete
486 const float vBattThresholdOn = 8.0f;
487 // we fallback into zero instead of VBAT_FALLBACK_VALUE because it's not safe to false-trigger the "ignition on" event,
488 // and we want to turn on the main relay only when 100% sure.
489 if ((Sensor::getOrZero(SensorType::BatteryVoltage) > vBattThresholdOn) && !isInShutdownMode()) {
490 ignitionOnTimeNt = getTimeNowNt();
491 efiPrintf("Ignition voltage detected!");
492 if (stopEngineRequestTimeNt != 0) {
493 efiPrintf("Cancel the engine shutdown!");
494 stopEngineRequestTimeNt = 0;
495 }
496 }
497 }
498*/
499#endif /* EFI_MAIN_RELAY_CONTROL */
500}
501
503 // TODO: this logic is currently broken
504#if 0 && EFI_MAIN_RELAY_CONTROL && EFI_PROD_CODE
505 // if we are in "ignition_on" mode and not in shutdown mode
506 if (stopEngineRequestTimeNt == 0 && ignitionOnTimeNt > 0) {
507 const float vBattThresholdOff = 5.0f;
508 // start the shutdown process if the ignition voltage dropped low
509 if (Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE) <= vBattThresholdOff) {
511 }
512 }
513
514 // we are not in the shutdown mode?
515 if (stopEngineRequestTimeNt == 0) {
516 return false;
517 }
518
519 const efitick_t turnOffWaitTimeoutNt = NT_PER_SECOND;
520 // We don't want any transients to step in, so we wait at least 1 second whatever happens.
521 // Also it's good to give the stepper motor some time to start moving to the initial position (or parking)
522 if ((getTimeNowNt() - stopEngineRequestTimeNt) < turnOffWaitTimeoutNt)
523 return true;
524
525 const efitick_t engineSpinningWaitTimeoutNt = 5 * NT_PER_SECOND;
526 // The engine is still spinning! Give it some time to stop (but wait no more than 5 secs)
527 if (isSpinning && (getTimeNowNt() - stopEngineRequestTimeNt) < engineSpinningWaitTimeoutNt)
528 return true;
529
530 // The idle motor valve is still moving! Give it some time to park (but wait no more than 10 secs)
531 // Usually it can move to the initial 'cranking' position or zero 'parking' position.
532 const efitick_t idleMotorWaitTimeoutNt = 10 * NT_PER_SECOND;
533 if (isIdleMotorBusy() && (getTimeNowNt() - stopEngineRequestTimeNt) < idleMotorWaitTimeoutNt)
534 return true;
535#endif /* EFI_MAIN_RELAY_CONTROL */
536 return false;
537}
538
540#if EFI_MAIN_RELAY_CONTROL
542#else
543 // if no main relay control, we assume it's always turned on
544 return true;
545#endif /* EFI_MAIN_RELAY_CONTROL */
546}
547
551
552/**
553 * The idea of this method is to execute all heavy calculations in a lower-priority thread,
554 * so that trigger event handler/IO scheduler tasks are faster.
555 */
558
560
561
563
564 speedoUpdate();
565
566 engineModules.apply_all([](auto & m) { m.onFastCallback(); });
567}
568
570 engineModules.apply_all([](auto& m) { m.onEngineStop(); });
571}
572
576
580
584
586 return &engine->scheduler;
587}
588
589#if EFI_SHAFT_POSITION_INPUT
593#endif // EFI_SHAFT_POSITION_INPUT
594
595#if EFI_ENGINE_CONTROL
597 return &engine->module<LimpManager>().unmock();
598}
599
603
607#endif // EFI_ENGINE_CONTROL
bool getAcToggle()
bool hasAcToggle()
const char * getVvt_mode_e(vvt_mode_e value)
Non-volatile backup-RAM registers support.
bool isRunningBenchTest()
Utility methods related to bench testing.
Timer timeSinceStateChange
Definition ac_control.h:16
TriggerCentral triggerCentral
Definition engine.h:318
void resetLua()
Definition engine.cpp:301
void updateSlowSensors()
Definition engine.cpp:208
int getGlobalConfigurationVersion() const
Definition engine.cpp:289
bool isFunctionalTestMode
Definition engine.h:340
FuelSchedule injectionEvents
Definition engine.h:288
IgnitionEventList ignitionEvents
Definition engine.h:289
void onEngineHasStopped()
Definition engine.cpp:455
IgnitionState ignitionState
Definition engine.h:239
void periodicFastCallback()
Definition engine.cpp:556
void onEngineStopped()
Definition engine.cpp:569
void checkShutdown()
Definition engine.cpp:468
void preCalculate()
Definition engine.cpp:324
bool slowCallBackWasInvoked
Definition engine.h:304
SingleTimerExecutor scheduler
Definition engine.h:271
bool isInShutdownMode() const
Definition engine.cpp:502
void efiWatchdog()
Definition engine.cpp:427
bool isMainRelayEnabled() const
Definition engine.cpp:539
EngineState engineState
Definition engine.h:344
void periodicSlowCallback()
Definition engine.cpp:150
SwitchedState brakePedalSwitchedState
Definition engine.h:215
RpmCalculator rpmCalculator
Definition engine.h:306
void resetEngineSnifferIfInTestMode()
Definition engine.cpp:53
TriggerStateListener * nextListener() override
Definition engine.cpp:341
SwitchedState clutchUpSwitchedState
Definition engine.h:214
Engine()
Definition engine.cpp:283
int globalConfigurationVersion
Definition engine.h:315
SwitchedState acButtonSwitchedState
Definition engine.h:216
void setConfig()
Definition engine.cpp:397
void OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError) override
Definition engine.cpp:359
void injectEngineReferences()
Definition engine.cpp:388
TriggerStateListener * secondListener
Definition engine.h:247
TunerStudioOutputChannels outputChannels
Definition engine.h:109
void updateTriggerConfiguration()
Definition engine.cpp:133
void OnTriggerStateProperState(efitick_t nowNt, size_t triggerStateIndex) override
Definition engine.cpp:335
void updateSwitchInputs()
Definition engine.cpp:254
constexpr auto & module()
Definition engine.h:200
void reset()
Definition engine.cpp:293
void OnTriggerSynchronizationLost() override
Definition engine.cpp:345
type_list< Mockable< InjectorModelPrimary >, Mockable< InjectorModelSecondary >,#if EFI_IDLE_CONTROL Mockable< IdleController >,#endif TriggerScheduler,#if EFI_HPFP &&EFI_ENGINE_CONTROL Mockable< HpfpController >,#endif #if EFI_ENGINE_CONTROL Mockable< ThrottleModel >,#endif #if EFI_ALTERNATOR_CONTROL AlternatorController,#endif MainRelayController, Mockable< IgnitionController >, Mockable< AcController >, PrimeController, DfcoController,#if EFI_HD_ACR HarleyAcr,#endif Mockable< WallFuelController >, KnockController, SensorChecker,#if EFI_ENGINE_CONTROL Mockable< LimpManager >,#endif #if EFI_VVT_PID VvtController1, VvtController2, VvtController3, VvtController4,#endif #if EFI_BOOST_CONTROL BoostController,#endif TpsAccelEnrichment,#if EFI_LAUNCH_CONTROL NitrousController,#endif #if EFI_LTFT_CONTROL LongTermFuelTrim,#endif ShortTermFuelTrim,#include "modules_list_generated.h" EngineModule > engineModules
Definition engine.h:194
Timer configBurnTimer
Definition engine.h:308
bool isRunningPwmTest
Definition engine.h:334
RegisteredOutputPin mainRelay
Definition efi_gpio.h:76
OutputPin o2heater
Definition efi_gpio.h:99
RegisteredOutputPin triggerDecoderErrorPin
Definition efi_gpio.h:121
RegisteredOutputPin starterRelayDisable
Definition efi_gpio.h:84
bool stopPins()
Definition efi_gpio.cpp:214
virtual bool isCranking() const =0
angle_t engineCycle
void periodicFastCallback()
Definition engine2.cpp:154
Timer undervoltageCrankingTimer
bool getLogicValue() const
Definition efi_gpio.cpp:667
void setValue(const char *msg, int logicValue, bool isForce=false)
Definition efi_gpio.cpp:604
void setSpinningUp(efitick_t nowNt)
bool isRunning() const
bool isCranking() const override
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
bool update(bool newState)
Definition efi_output.cpp:9
VvtTriggerDecoder vvtState[BANKS_COUNT][CAMS_PER_BANK]
InstantRpmCalculator instantRpm
PrimaryTriggerDecoder triggerState
bool engineMovedRecently(efitick_t nowNt) const
TriggerWaveform triggerShape
cyclic_buffer< int > triggerErrorDetection
VvtTriggerConfiguration vvtTriggerConfiguration[CAMS_PER_BANK]
PrimaryTriggerConfiguration primaryTriggerConfiguration
virtual void resetState()
current_cycle_state_s currentCycle
bool someSortOfTriggerError() const
size_t getExpectedEventCount(TriggerWheel channelIndex) const
rusEfi console sniffer data buffer
efitick_t pauseEngineSnifferUntilNt
void updateDynoView()
Definition dynoview.cpp:175
EnginePins enginePins
Definition efi_gpio.cpp:24
efitick_t getTimeNowNt()
Definition efitime.cpp:19
efitimems_t getTimeNowMs()
Returns the 32 bit number of milliseconds since the board initialization.
Definition efitime.cpp:34
int waveChartUsedSize
bool getBrakePedalState()
Definition engine.cpp:243
LimpManager * getLimpManager()
Definition engine.cpp:596
Scheduler * getScheduler()
Definition engine.cpp:585
static void assertTimeIsLinear()
Definition engine.cpp:409
TriggerCentral * getTriggerCentral()
Definition engine.cpp:590
PUBLIC_API_WEAK trigger_type_e getCustomVvtTriggerType(vvt_mode_e vvtMode)
Definition engine.cpp:63
static bool getClutchUpState()
Definition engine.cpp:233
injection_mode_e getCurrentInjectionMode()
Definition engine.cpp:548
PUBLIC_API_WEAK void boardPeriodicSlowCallback()
Definition engine.cpp:146
PUBLIC_API_WEAK void boardPeriodicFastCallback()
Definition engine.cpp:148
FuelSchedule * getFuelSchedule()
Definition engine.cpp:600
trigger_type_e getVvtTriggerType(vvt_mode_e vvtMode)
Definition engine.cpp:72
EngineRotationState * getEngineRotationState()
Definition engine.cpp:573
EngineState * getEngineState()
Definition engine.cpp:577
bool getClutchDownState()
Definition engine.cpp:223
IgnitionEventList * getIgnitionEvents()
Definition engine.cpp:604
TunerStudioOutputChannels * getTunerStudioOutputChannels()
Definition engine.cpp:581
WaveChart waveChart
static EngineAccessor engine
Definition engine.h:413
void prepareOutputSignals()
static constexpr persistent_config_s * config
static constexpr engine_configuration_s * engineConfiguration
rusEfi console wave sniffer
trigger_type_e
bool warning(ObdCode code, const char *fmt,...)
void firmwareError(ObdCode code, const char *fmt,...)
bool warningTsReport(ObdCode code, const char *fmt,...)
void updateGppwm()
Definition gppwm.cpp:58
Idle Air Control valve hardware.
bool isIdleMotorBusy()
Idle Valve Control thread.
void pokeAuxDigital()
void baroLps25Update()
Definition init_baro.cpp:19
bool efiReadPin(brain_pin_e pin)
Definition io_pins.cpp:89
bool kAcRequestState
Definition kline.cpp:31
UNUSED(samplingTimeSeconds)
@ RUNTIME_CRITICAL_WATCH_DOG_SECONDS
@ CUSTOM_ERR_2ND_WATCHDOG
@ OBD_System_Voltage_Low
@ EnginePeriodicSlowCallback
@ EnginePeriodicFastCallback
bool isBrainPinValid(brain_pin_e brainPin)
vvt_mode_e
@ FOUR_STROKE_CRANK_SENSOR
injection_mode_e
uint32_t efitimems_t
triggerStateIndex("triggerStateIndex", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1584, 1.0, -1.0, -1.0, "")
void doScheduleStopEngine(StopRequestedReason reason)
void tle8888startup()
void speedoUpdate()
WaveChart waveChart
size_t eventCount[PWM_PHASE_MAX_WAVE_PER_PWM]
angle_t getEngineCycle(operation_mode_e operationMode)
void updateVrThresholdPwm()
Definition vr_pwm.cpp:31