GCC Code Coverage Report


Directory: ./
File: firmware/controllers/algo/engine.h
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 25.0% 10 0 40
Functions: 31.8% 7 0 22
Branches: -% 0 0 0
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 /**
2 * @file engine.h
3 *
4 * @date May 21, 2014
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 */
7
8 #pragma once
9
10 #include "global_shared.h"
11 #include "engine_module.h"
12 #include "engine_state.h"
13 #include "rpm_calculator.h"
14 #include "event_registry.h"
15 #include "table_helper.h"
16 #include "listener_array.h"
17 #include "accel_enrichment.h"
18 #include "trigger_central.h"
19 #include "local_version_holder.h"
20 #include "buttonshift.h"
21 #include "gear_controller.h"
22 #include "dynoview.h"
23 #include "high_pressure_fuel_pump.h"
24 #include "limp_manager.h"
25 #include "pin_repository.h"
26 #include "ac_control.h"
27 #include "knock_logic.h"
28 #include "idle_state_generated.h"
29 #include "sent_state_generated.h"
30 #include "closed_loop_idle.h"
31 #include "dc_motors_generated.h"
32 #include "idle_thread.h"
33 #include "injector_model.h"
34 #include "launch_control.h"
35 #include "shift_torque_reduction_controller.h"
36 #include "nitrous_controller.h"
37 #include "antilag_system.h"
38 #include "start_stop.h"
39 #include "trigger_scheduler.h"
40 #include "fuel_pump.h"
41 #include "main_relay.h"
42 #include "ac_control.h"
43 #include "type_list.h"
44 #include "boost_control.h"
45 #include "ignition_controller.h"
46 #include "alternator_controller.h"
47 #include "harley_acr.h"
48 #include "dfco.h"
49 #include "fuel_computer.h"
50 #include "advance_map.h"
51 #include "ignition_state.h"
52 #include "sensor_checker.h"
53 #include "fuel_schedule.h"
54 #include "prime_injection.h"
55 #include "throttle_model.h"
56 #include "gc_generic.h"
57 #include "lambda_monitor.h"
58 #include "efi_output.h"
59 #include "vvt.h"
60 #include "closed_loop_fuel.h"
61 #include "long_term_fuel_trim.h"
62 #include "electronic_throttle_generated.h"
63 #include "engine_cylinder.hpp"
64
65 #include <functional>
66
67 #ifndef EFI_BOOTLOADER
68 #include "engine_modules_generated.h"
69 #endif
70
71 static_assert(MAX_CYLINDER_COUNT > 0);
72
73 #ifndef EFI_UNIT_TEST
74 #error EFI_UNIT_TEST must be defined!
75 #endif
76
77 #ifndef EFI_SIMULATOR
78 #error EFI_SIMULATOR must be defined!
79 #endif
80
81 #ifndef EFI_PROD_CODE
82 #error EFI_PROD_CODE must be defined!
83 #endif
84
85 struct AirmassModelBase;
86
87 #define MAF_DECODING_CACHE_SIZE 256
88
89 #define MAF_DECODING_CACHE_MULT (MAF_DECODING_CACHE_SIZE / 5.0)
90
91 /**
92 * I am not sure if this needs to be configurable.
93 *
94 * Also technically the whole feature might be implemented as cranking fuel coefficient curve by TPS.
95 */
96 // todo: not great location for these
97 #define CLEANUP_MODE_TPS 90
98 #define STEPPER_PARKING_TPS CLEANUP_MODE_TPS
99
100 class IEtbController;
101
102 class Engine final : public TriggerStateListener {
103 public:
104 Engine();
105
106 StartStopState startStopState{};
107
108
109 TunerStudioOutputChannels outputChannels{};
110
111 /**
112 * Sometimes for instance during shutdown we need to completely supress CAN TX
113 */
114 bool allowCanTx = true;
115
116 // used by HW CI
117 bool isPwmEnabled = true;
118
119 /**
120 * ELM327 cannot handle both RX and TX at the same time, we have to stay quite once first ISO/TP packet was detected
121 * this is a pretty temporary hack only while we are trying ELM327, long term ISO/TP and rusEFI broadcast should find a way to coexists
122 */
123 bool pauseCANdueToSerial = false;
124
125 #if EFI_ELECTRONIC_THROTTLE_BODY
126 IEtbController *etbControllers[ETB_COUNT] = {nullptr};
127 #endif // EFI_ELECTRONIC_THROTTLE_BODY
128
129
130 #if EFI_DYNO_VIEW
131 DynoView dynoInstance{};
132 #endif
133
134 #if EFI_IDLE_CONTROL
135 LongTermIdleTrim m_ltit;
136 #endif // EFI_IDLE_CONTROL
137
138 #if EFI_ENGINE_CONTROL
139 FuelComputer fuelComputer{};
140 #endif // EFI_ENGINE_CONTROL
141
142 type_list<
143 Mockable<InjectorModelPrimary>,
144 Mockable<InjectorModelSecondary>,
145 #if EFI_IDLE_CONTROL
146 Mockable<IdleController>,
147 #endif // EFI_IDLE_CONTROL
148
149 TriggerScheduler,
150 #if EFI_HPFP && EFI_ENGINE_CONTROL
151 Mockable<HpfpController>,
152 #endif // EFI_HPFP && EFI_ENGINE_CONTROL
153 #if EFI_ENGINE_CONTROL
154 Mockable<ThrottleModel>,
155 #endif // EFI_ENGINE_CONTROL
156 #if EFI_ALTERNATOR_CONTROL
157 AlternatorController,
158 #endif /* EFI_ALTERNATOR_CONTROL */
159 MainRelayController,
160 Mockable<IgnitionController>,
161 Mockable<AcController>,
162 PrimeController,
163 DfcoController,
164 #if EFI_HD_ACR
165 HarleyAcr,
166 #endif // EFI_HD_ACR
167 Mockable<WallFuelController>,
168 KnockController,
169 SensorChecker,
170 #if EFI_ENGINE_CONTROL
171 Mockable<LimpManager>,
172 #endif // EFI_ENGINE_CONTROL
173 #if EFI_VVT_PID
174 VvtController1,
175 VvtController2,
176 VvtController3,
177 VvtController4,
178 #endif // EFI_VVT_PID
179 #if EFI_BOOST_CONTROL
180 BoostController,
181 #endif // EFI_BOOST_CONTROL
182 TpsAccelEnrichment,
183 #if EFI_LAUNCH_CONTROL
184 NitrousController,
185 #endif // EFI_LAUNCH_CONTROL
186 #if EFI_LTFT_CONTROL
187 LongTermFuelTrim,
188 #endif
189 ShortTermFuelTrim,
190
191 #include "modules_list_generated.h"
192
193 EngineModule // dummy placeholder so the previous entries can all have commas
194 > engineModules{};
195
196 /**
197 * Slightly shorter helper function to keep the code looking clean.
198 */
199 template<typename get_t>
200 571910 constexpr auto & module() {
201 571910 return engineModules.get<get_t>();
202 }
203
204 template<typename get_t>
205 constexpr auto const & module() const {
206 return engineModules.get<get_t>();
207 }
208
209 #if EFI_TCU
210 GearControllerBase *gearController = nullptr;
211 #endif
212
213 // todo: boolean sensors should leverage sensor framework #6342
214 SwitchedState clutchUpSwitchedState{&engineState.clutchUpState};
215 SwitchedState brakePedalSwitchedState{&engineState.brakePedalState};
216 SwitchedState acButtonSwitchedState{&engineModules.get<AcController>().unmock().acButtonState};
217 SimpleSwitchedState luaDigitalInputState[LUA_DIGITAL_INPUT_COUNT]{};
218
219 #if EFI_LAUNCH_CONTROL
220 LaunchControlBase launchController{};
221 ShiftTorqueReductionController shiftTorqueReductionController{};
222 SoftSparkLimiter softSparkLimiter{false};
223 // technically not directly related to EFI_LAUNCH_CONTROL since useful for TCU
224 SoftSparkLimiter hardSparkLimiter{true};
225 #endif // EFI_LAUNCH_CONTROL
226
227 #if EFI_ANTILAG_SYSTEM
228 AntilagSystemBase antilagController{};
229 #endif // EFI_ANTILAG_SYSTEM
230
231 #if EFI_ANTILAG_SYSTEM
232 // SoftSparkLimiter ALSsoftSparkLimiter{false};
233 #endif /* EFI_ANTILAG_SYSTEM */
234
235 #if EFI_SHAFT_POSITION_INPUT
236 LambdaMonitor lambdaMonitor{};
237 #endif // EFI_ENGINE_CONTROL
238
239 IgnitionState ignitionState{};
240 void resetLua();
241
242 #if EFI_SHAFT_POSITION_INPUT
243 void OnTriggerStateProperState(efitick_t nowNt, size_t triggerStateIndex) override;
244 void OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError) override;
245 void OnTriggerSynchronizationLost() override;
246 TriggerStateListener* nextListener() override;
247 TriggerStateListener* secondListener = nullptr;
248 #endif
249
250 void setConfig();
251
252 #if EFI_AUX_VALVES
253 AuxActor auxValves[AUX_DIGITAL_VALVE_COUNT][2]{};
254 #endif // EFI_AUX_VALVES
255
256 #if EFI_UNIT_TEST
257 bool needTdcCallback = true;
258 private:
259 int bailedOnDwellCount = 0;
260 public:
261 9 int getBailedOnDwellCount() const { return bailedOnDwellCount; }
262 5907 void incrementBailedOnDwellCount() { bailedOnDwellCount++; }
263 #endif /* EFI_UNIT_TEST */
264
265 int getGlobalConfigurationVersion() const;
266
267 // a pointer with interface type would make this code nicer but would carry extra runtime
268 // cost to resolve pointer, we use instances as a micro optimization
269 #if EFI_SIGNAL_EXECUTOR_ONE_TIMER
270 // while theoretically PROD could be using EFI_SIGNAL_EXECUTOR_SLEEP, as of 2024 all PROD uses SingleTimerExecutor
271 SingleTimerExecutor scheduler{};
272 #endif
273 #if EFI_SIGNAL_EXECUTOR_SLEEP
274 // at the moment this one is used exclusively by x86 simulator it should theoretically be possible to make it available in embedded if needed
275 SleepExecutor scheduler{};
276 #endif
277 #if EFI_UNIT_TEST
278 TestExecutor scheduler{};
279
280 std::function<void(IgnitionEvent*, bool)> onIgnitionEvent;
281 std::function<void(const IgnitionEvent&, efitick_t, angle_t, efitick_t)> onScheduleTurnSparkPinHighStartCharging
282 8678 = [](const IgnitionEvent&, efitick_t, angle_t, efitick_t) -> void {};
283 std::function<void(const IgnitionEvent&, efitick_t)> onScheduleOverFireSparkAndPrepareNextSchedule
284 1251 = [](const IgnitionEvent&, efitick_t) -> void {};
285 #endif // EFI_UNIT_TEST
286
287 #if EFI_ENGINE_CONTROL
288 FuelSchedule injectionEvents{};
289 IgnitionEventList ignitionEvents{};
290 scheduling_s tdcScheduler[2]{};
291 OneCylinder cylinders[MAX_CYLINDER_COUNT]{};
292 #endif /* EFI_ENGINE_CONTROL */
293
294 #if EFI_ELECTRONIC_THROTTLE_BODY
295 // todo: move to electronic_throttle something?
296 bool etbAutoTune = false;
297 bool etbIgnoreJamProtection = false;
298 #endif // EFI_ELECTRONIC_THROTTLE_BODY
299
300 #if EFI_UNIT_TEST
301 bool tdcMarkEnabled = true;
302 #endif // EFI_UNIT_TEST
303
304 bool slowCallBackWasInvoked = false;
305
306 RpmCalculator rpmCalculator{};
307
308 Timer configBurnTimer{};
309 Timer engineTypeChangeTimer{};
310
311 /**
312 * This counter is incremented every time user adjusts ECU parameters online (either via rusEfi console or other
313 * tuning software)
314 */
315 int globalConfigurationVersion = 0;
316
317 #if EFI_SHAFT_POSITION_INPUT
318 TriggerCentral triggerCentral{};
319 #endif // EFI_SHAFT_POSITION_INPUT
320
321 /**
322 * See FAST_CALLBACK_PERIOD_MS
323 */
324 void periodicFastCallback();
325 /**
326 * See SLOW_CALLBACK_PERIOD_MS
327 */
328 void periodicSlowCallback();
329 void onEngineStopped();
330 void updateSlowSensors();
331 void updateSwitchInputs();
332 void updateTriggerConfiguration();
333
334 bool isRunningPwmTest = false;
335
336 /**
337 * are we running any kind of functional test? this affect
338 * some areas
339 */
340 bool isFunctionalTestMode = false;
341
342 void resetEngineSnifferIfInTestMode();
343
344 EngineState engineState{};
345
346 dc_motors_s dc_motors{};
347 #if EFI_SENT_SUPPORT
348 sent_state_s sent_state{};
349 #endif
350
351 efitimeus_t timeToStopIdleTest{};
352
353 SensorsState sensors{};
354
355 void preCalculate();
356
357 void efiWatchdog();
358 void onEngineHasStopped();
359
360 /**
361 * Needed by EFI_MAIN_RELAY_CONTROL to shut down the engine correctly.
362 * This method cancels shutdown if the ignition voltage is detected.
363 */
364 void checkShutdown();
365
366 /**
367 * Allows to finish some long-term shutdown procedures (stepper motor parking etc.)
368 Called when the ignition switch is turned off (vBatt is too low).
369 Returns true if some operations are in progress on background.
370 */
371 bool isInShutdownMode() const;
372
373 /**
374 * The stepper does not work if the main relay is turned off (it requires +12V).
375 * Needed by the stepper motor code to detect if it works.
376 */
377 bool isMainRelayEnabled() const;
378
379 void onSparkFireKnockSense(uint8_t cylinderIndex, efitick_t nowNt);
380
381 #if EFI_UNIT_TEST
382 AirmassModelBase* mockAirmassModel{};
383 #endif
384
385 private:
386 void reset();
387
388 void injectEngineReferences();
389 };
390
391 trigger_type_e getVvtTriggerType(vvt_mode_e vvtMode);
392
393 void applyNonPersistentConfiguration();
394 void prepareOutputSignals();
395
396 void scheduleReboot();
397 bool isLockedFromUser();
398 void unlockEcu(int password);
399
400 // These externs aren't needed for unit tests - everything is injected instead
401 #if !EFI_UNIT_TEST
402 extern Engine ___engine;
403 static constexpr Engine* engine_ptr = &___engine;
404
405 struct EngineAccessor {
406 constexpr Engine* operator->() { return engine_ptr; }
407 constexpr Engine const* operator->() const { return engine_ptr; }
408 constexpr operator Engine*() { return engine_ptr; }
409 constexpr operator Engine const*() const { return engine_ptr; }
410 constexpr operator bool() const { return true; }
411 };
412
413 [[maybe_unused]] static EngineAccessor engine;
414
415 #else // EFI_UNIT_TEST
416 extern Engine* engine;
417 #endif // EFI_UNIT_TEST
418