GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 27.3% 12 / 0 / 44
Functions: 30.4% 7 / 1 / 24
Branches: -% 0 / 0 / 0
Decisions: -% 0 / - / 0

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