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_BMW_N63TU:
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
146#include "board_overrides.h"
147
148std::optional<setup_custom_board_overrides_type> custom_board_periodicSlowCallback;
149std::optional<setup_custom_board_overrides_type> custom_board_periodicFastCallback;
150
152 // placeholder to force upgrade
153}
154
156 // placeholder to force upgrade
157}
158
161
162#if EFI_SHAFT_POSITION_INPUT
163 // Re-read config in case it's changed
165 for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
167 }
168
170 enginePins.o2heater.setValue(getEngineState()->heaterControlEnabled);
172#endif // EFI_SHAFT_POSITION_INPUT
173
174 efiWatchdog();
177
178 module<TpsAccelEnrichment>()->onNewValue(Sensor::getOrZero(SensorType::Tps1));
179
181
182 updateGppwm();
183
184 engine->engineModules.apply_all([](auto & m) { m.onSlowCallback(); });
185
186#if (BOARD_TLE8888_COUNT > 0)
188#endif
189
190#if EFI_DYNO_VIEW
192#endif
193
194 // TODO: move to sensor_checker.cpp?
196 // undervoltage crancking!
197 if (getEngineState()->undervoltageCrankingTimer.getElapsedSeconds() > 1) {
198 warningTsReport(ObdCode::OBD_System_Voltage_Low, "Cranking on low battery!");
199 }
200 } else {
202 }
203
205
206#if EFI_PROD_CODE
207 void baroLps25Update();
209#endif // EFI_PROD_CODE
212}
213
214/**
215 * We are executing these heavy (logarithm) methods from outside the trigger callbacks for performance reasons.
216 * See also periodicFastCallback
217 */
220
221#if EFI_PROD_CODE
222 // todo: extract method? do better? see https://github.com/rusefi/rusefi/issues/7511 for details
223 engine->module<InjectorModelSecondary>()->updateState();
224 engine->module<InjectorModelPrimary>()->updateState();
225#endif // EFI_PROD_CODE
226
227#if EFI_SHAFT_POSITION_INPUT
230#endif // EFI_SHAFT_POSITION_INPUT
231}
232
234#if EFI_GPIO_HARDWARE
237 }
238#endif // EFI_GPIO_HARDWARE
239 // todo: boolean sensors should leverage sensor framework #6342
241}
242
243static bool getClutchUpState() {
244#if EFI_GPIO_HARDWARE
247 }
248#endif // EFI_GPIO_HARDWARE
249 // todo: boolean sensors should leverage sensor framework #6342
251}
252
254#if EFI_GPIO_HARDWARE
257 }
258#endif // EFI_GPIO_HARDWARE
259 // todo: boolean sensors should leverage sensor framework #6342
261}
262
263
265 // this value is not used yet
269#if EFI_GPIO_HARDWARE
270 {
271 bool currentState;
272 if (hasAcToggle()) {
273 currentState = getAcToggle();
274#ifdef EFI_KLINE
275 } else if (engineConfiguration->hondaK) {
276extern bool kAcRequestState;
277 currentState = kAcRequestState;
278#endif // EFI_KLINE
279 } else {
280 currentState = engine->engineState.lua.acRequestState;
281 }
282 AcController & acController = engine->module<AcController>().unmock();
283 if (engine->acButtonSwitchedState.update(currentState)) {
284 acController.timeSinceStateChange.reset();
285 }
286 }
287
289
290#endif // EFI_GPIO_HARDWARE
291}
292
294 resetLua();
295}
296
300
302 /**
303 * it's important for wrapAngle() that engineCycle field never has zero
304 */
306 resetLua();
307}
308
310 // todo: https://github.com/rusefi/rusefi/issues/4308
311 engineState.lua = {};
315 engineState.lua.luaIgnCut = false;
316 engineState.lua.luaFuelCut = false;
319#if EFI_BOOST_CONTROL
320 module<BoostController>().unmock().resetLua();
321#endif // EFI_BOOST_CONTROL
324#if EFI_IDLE_CONTROL
325 module<IdleController>().unmock().luaAdd = 0;
326#endif // EFI_IDLE_CONTROL
327}
328
329/**
330 * Here we have a bunch of stuff which should invoked after configuration change
331 * so that we can prepare some helper structures
332 */
334#if EFI_TUNER_STUDIO
335 // we take 2 bytes of crc32, no idea if it's right to call it crc16 or not
336 // we have a hack here - we rely on the fact that engineMake is the first of three relevant fields
338
340#endif /* EFI_TUNER_STUDIO */
341}
342
343#if EFI_SHAFT_POSITION_INPUT
349
353
355 // Needed for early instant-RPM detection
357
360
361 for (size_t i = 0; i < efi::size(triggerCentral.vvtState); i++) {
362 for (size_t j = 0; j < efi::size(triggerCentral.vvtState[0]); j++) {
364 }
365 }
366}
367
368void Engine::OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError) {
369 // TODO: this logic probably shouldn't be part of engine.cpp
370
371 // We only care about trigger shape once we have synchronized trigger. Anything could happen
372 // during first revolution and it's fine
373 if (wasSynchronized) {
375
376 // 'triggerStateListener is not null' means we are running a real engine and now just preparing trigger shape
377 // that's a bit of a hack, a sweet OOP solution would be a real callback or at least 'needDecodingErrorLogic' method?
378 if (isDecodingError) {
379#if EFI_PROD_CODE
381 efiPrintf("error: synchronizationPoint @ index %lu expected %d/%d got %d/%d",
387 }
388#endif /* EFI_PROD_CODE */
389 }
390
391 engine->triggerCentral.triggerErrorDetection.add(isDecodingError);
392 }
393
394}
395#endif
396
398#if EFI_SHAFT_POSITION_INPUT
400 for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
402 }
403#endif // EFI_SHAFT_POSITION_INPUT
404}
405
407#if !EFI_UNIT_TEST
408// huh should this be happy? static_assert(config != nullptr);
409#endif
410 efi::clear(config);
411
413}
414
415/**
416 * This code asserts that we do not have unexpected gaps in time flow with the exception of internal flash burn.
417 */
418static void assertTimeIsLinear() {
419#if ! EFI_UNIT_TEST
420 static efitimems_t mostRecentMs = 0;
421 efitimems_t msNow = getTimeNowMs();
423 if (mostRecentMs != 0) {
424 efitimems_t gapInMs = msNow - mostRecentMs;
425 // todo: lower gapInMs threshold?
426 if (gapInMs > 200) {
427 firmwareError(ObdCode::RUNTIME_CRITICAL_WATCH_DOG_SECONDS, "gap in time: mostRecentMs %lumS, now=%lumS, gap=%lumS",
428 mostRecentMs, msNow, gapInMs);
429 }
430 }
431 }
432 mostRecentMs = msNow;
433#endif
434}
435
438 if (isRunningPwmTest) {
439 return;
440 }
441
442#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
443 if (module<PrimeController>()->isPriming() || triggerCentral.engineMovedRecently()) {
444 // do not invoke check in priming or if engine moved recently, no need to assert safe pin state.
445 return;
446 }
447
450 // todo: make this a firmwareError assuming functional tests would run
451 warning(ObdCode::CUSTOM_ERR_2ND_WATCHDOG, "Some pins were turned off by 2nd pass watchdog");
452 }
453 return;
454 }
455
456 /**
457 * todo: better watch dog implementation should be implemented - see
458 * http://sourceforge.net/p/rusefi/tickets/96/
459 */
462#endif // EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
463}
464
466#if EFI_ENGINE_CONTROL
467 ignitionEvents.isReady = false;
468#endif // EFI_ENGINE_CONTROL
469
470#if EFI_PROD_CODE || EFI_SIMULATOR
471 efiPrintf("Engine has stopped spinning.");
472#endif
473
474 // this invocation should be the last layer of defence in terms of making sure injectors/coils are not active
476}
477
479#if EFI_MAIN_RELAY_CONTROL
480 // if we are already in the "ignition_on" mode, then do nothing
481/* this logic is not alive
482 if (ignitionOnTimeNt > 0) {
483 return;
484 }
485todo: move to shutdown_controller.cpp
486*/
487
488 // here we are in the shutdown (the ignition is off) or initial mode (after the firmware fresh start)
489/* this needs work or tests
490 const efitick_t engineStopWaitTimeoutUs = 500000LL; // 0.5 sec
491 // in shutdown mode, we need a small cooldown time between the ignition off and on
492todo: move to shutdown_controller.cpp
493 if (stopEngineRequestTimeNt == 0 || (getTimeNowNt() - stopEngineRequestTimeNt) > US2NT(engineStopWaitTimeoutUs)) {
494 // if the ignition key is turned on again,
495 // we cancel the shutdown mode, but only if all shutdown procedures are complete
496 const float vBattThresholdOn = 8.0f;
497 // we fallback into zero instead of VBAT_FALLBACK_VALUE because it's not safe to false-trigger the "ignition on" event,
498 // and we want to turn on the main relay only when 100% sure.
499 if ((Sensor::getOrZero(SensorType::BatteryVoltage) > vBattThresholdOn) && !isInShutdownMode()) {
500 ignitionOnTimeNt = getTimeNowNt();
501 efiPrintf("Ignition voltage detected!");
502 if (stopEngineRequestTimeNt != 0) {
503 efiPrintf("Cancel the engine shutdown!");
504 stopEngineRequestTimeNt = 0;
505 }
506 }
507 }
508*/
509#endif /* EFI_MAIN_RELAY_CONTROL */
510}
511
513 // TODO: this logic is currently broken
514#if 0 && EFI_MAIN_RELAY_CONTROL && EFI_PROD_CODE
515 // if we are in "ignition_on" mode and not in shutdown mode
516 if (stopEngineRequestTimeNt == 0 && ignitionOnTimeNt > 0) {
517 const float vBattThresholdOff = 5.0f;
518 // start the shutdown process if the ignition voltage dropped low
519 if (Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE) <= vBattThresholdOff) {
521 }
522 }
523
524 // we are not in the shutdown mode?
525 if (stopEngineRequestTimeNt == 0) {
526 return false;
527 }
528
529 const efitick_t turnOffWaitTimeoutNt = NT_PER_SECOND;
530 // We don't want any transients to step in, so we wait at least 1 second whatever happens.
531 // Also it's good to give the stepper motor some time to start moving to the initial position (or parking)
532 if ((getTimeNowNt() - stopEngineRequestTimeNt) < turnOffWaitTimeoutNt)
533 return true;
534
535 const efitick_t engineSpinningWaitTimeoutNt = 5 * NT_PER_SECOND;
536 // The engine is still spinning! Give it some time to stop (but wait no more than 5 secs)
537 if (isSpinning && (getTimeNowNt() - stopEngineRequestTimeNt) < engineSpinningWaitTimeoutNt)
538 return true;
539
540 // The idle motor valve is still moving! Give it some time to park (but wait no more than 10 secs)
541 // Usually it can move to the initial 'cranking' position or zero 'parking' position.
542 const efitick_t idleMotorWaitTimeoutNt = 10 * NT_PER_SECOND;
543 if (isIdleMotorBusy() && (getTimeNowNt() - stopEngineRequestTimeNt) < idleMotorWaitTimeoutNt)
544 return true;
545#endif /* EFI_MAIN_RELAY_CONTROL */
546 return false;
547}
548
552
553/**
554 * The idea of this method is to execute all heavy calculations in a lower-priority thread,
555 * so that trigger event handler/IO scheduler tasks are faster.
556 */
570
572 engineModules.apply_all([](auto& m) { m.onEngineStop(); });
573}
574
578
582
586
588 return &engine->scheduler;
589}
590
591#if EFI_SHAFT_POSITION_INPUT
595#endif // EFI_SHAFT_POSITION_INPUT
596
597#if EFI_ENGINE_CONTROL
599 return &engine->module<LimpManager>().unmock();
600}
601
605
609#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.
static bool call_board_override(std::optional< FuncType > board_override, Args &&... args)
Timer timeSinceStateChange
Definition ac_control.h:16
TriggerCentral triggerCentral
Definition engine.h:326
void resetLua()
Definition engine.cpp:309
void updateSlowSensors()
Definition engine.cpp:218
int getGlobalConfigurationVersion() const
Definition engine.cpp:297
bool isFunctionalTestMode
Definition engine.h:348
FuelSchedule injectionEvents
Definition engine.h:296
IgnitionEventList ignitionEvents
Definition engine.h:297
void onEngineHasStopped()
Definition engine.cpp:465
IgnitionState ignitionState
Definition engine.h:247
void periodicFastCallback()
Definition engine.cpp:557
void onEngineStopped()
Definition engine.cpp:571
void checkShutdown()
Definition engine.cpp:478
void preCalculate()
Definition engine.cpp:333
bool slowCallBackWasInvoked
Definition engine.h:312
SingleTimerExecutor scheduler
Definition engine.h:279
bool isInShutdownMode() const
Definition engine.cpp:512
void efiWatchdog()
Definition engine.cpp:436
EngineState engineState
Definition engine.h:352
void periodicSlowCallback()
Definition engine.cpp:159
SwitchedState brakePedalSwitchedState
Definition engine.h:219
RpmCalculator rpmCalculator
Definition engine.h:314
void resetEngineSnifferIfInTestMode()
Definition engine.cpp:53
TriggerStateListener * nextListener() override
Definition engine.cpp:350
SwitchedState clutchUpSwitchedState
Definition engine.h:218
Engine()
Definition engine.cpp:293
int globalConfigurationVersion
Definition engine.h:323
SwitchedState acButtonSwitchedState
Definition engine.h:220
void setConfig()
Definition engine.cpp:406
void OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError) override
Definition engine.cpp:368
void injectEngineReferences()
Definition engine.cpp:397
TriggerStateListener * secondListener
Definition engine.h:255
TunerStudioOutputChannels outputChannels
Definition engine.h:113
void updateTriggerConfiguration()
Definition engine.cpp:133
void OnTriggerStateProperState(efitick_t nowNt, size_t triggerStateIndex) override
Definition engine.cpp:344
void updateSwitchInputs()
Definition engine.cpp:264
constexpr auto & module()
Definition engine.h:204
void reset()
Definition engine.cpp:301
void OnTriggerSynchronizationLost() override
Definition engine.cpp:354
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:198
Timer configBurnTimer
Definition engine.h:316
bool isRunningPwmTest
Definition engine.h:342
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
void setValue(const char *msg, int logicValue, bool isForce=false)
Definition efi_gpio.cpp:605
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:87
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
void boardPeriodicFastCallback()
Definition engine.cpp:155
int waveChartUsedSize
std::optional< setup_custom_board_overrides_type > custom_board_periodicSlowCallback
Definition engine.cpp:148
bool getBrakePedalState()
Definition engine.cpp:253
LimpManager * getLimpManager()
Definition engine.cpp:598
Scheduler * getScheduler()
Definition engine.cpp:587
static void assertTimeIsLinear()
Definition engine.cpp:418
TriggerCentral * getTriggerCentral()
Definition engine.cpp:592
PUBLIC_API_WEAK trigger_type_e getCustomVvtTriggerType(vvt_mode_e vvtMode)
Definition engine.cpp:63
static bool getClutchUpState()
Definition engine.cpp:243
injection_mode_e getCurrentInjectionMode()
Definition engine.cpp:549
FuelSchedule * getFuelSchedule()
Definition engine.cpp:602
trigger_type_e getVvtTriggerType(vvt_mode_e vvtMode)
Definition engine.cpp:72
EngineRotationState * getEngineRotationState()
Definition engine.cpp:575
EngineState * getEngineState()
Definition engine.cpp:579
bool getClutchDownState()
Definition engine.cpp:233
void boardPeriodicSlowCallback()
Definition engine.cpp:151
std::optional< setup_custom_board_overrides_type > custom_board_periodicFastCallback
Definition engine.cpp:149
IgnitionEventList * getIgnitionEvents()
Definition engine.cpp:606
TunerStudioOutputChannels * getTunerStudioOutputChannels()
Definition engine.cpp:583
WaveChart waveChart
static EngineAccessor engine
Definition engine.h:415
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, 1604, 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