| 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 | 584243 | constexpr auto & module() { | ||
| 201 | 584243 | 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 | 6683 | 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 | 9456 | = [](const IgnitionEvent&, efitick_t, angle_t, efitick_t) -> void {}; | ||
| 283 | std::function<void(const IgnitionEvent&, efitick_t)> onScheduleOverFireSparkAndPrepareNextSchedule | |||
| 284 | 2029 | = [](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 |