Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | #include "pch.h" | |||
2 | ||||
3 | #include "limp_manager.h" | |||
4 | #include "fuel_math.h" | |||
5 | #include "main_trigger_callback.h" | |||
6 | ||||
7 | #if EFI_ENGINE_CONTROL | |||
8 | ||||
9 | #define CLEANUP_MODE_TPS 90 | |||
10 | ||||
11 | #if EFI_SHAFT_POSITION_INPUT | |||
12 | 1165 | static bool noFiringUntilVvtSync() { | ||
13 | 1165 | auto operationMode = getEngineRotationState()->getOperationMode(); | ||
14 | ||||
15 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 1120 times.
|
2/2✓ Decision 'true' taken 45 times.
✓ Decision 'false' taken 1120 times.
|
1165 | if (engineConfiguration->isPhaseSyncRequiredForIgnition) { |
16 | // in rare cases engines do not like random sequential mode | |||
17 | 45 | return true; | ||
18 | } | |||
19 | 1120 | if (isGdiEngine()) { | ||
20 | #if EFI_PROD_CODE | |||
21 | criticalError("For GDI please configure CAM and require sync for ignition"); | |||
22 | #endif | |||
23 | } | |||
24 | ||||
25 |
2/2✓ Branch 0 taken 1041 times.
✓ Branch 1 taken 79 times.
|
2/2✓ Decision 'true' taken 1041 times.
✓ Decision 'false' taken 79 times.
|
1120 | if (engineConfiguration->ignitionMode == IM_ONE_COIL) { |
26 | // distributor routes to the correct cylinder, no need to worry about sync | |||
27 | 1041 | return false; | ||
28 | } | |||
29 | ||||
30 | // Symmetrical crank modes require cam sync before firing | |||
31 | // non-symmetrical cranks can use faster spin-up mode (firing in wasted/batch before VVT sync) | |||
32 | // Examples include Nissan MR/VQ, Miata NB, etc | |||
33 | return | |||
34 |
1/2✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
|
69 | operationMode == FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR || | |
35 |
3/4✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 69 times.
|
148 | operationMode == FOUR_STROKE_THREE_TIMES_CRANK_SENSOR || | |
36 | 79 | operationMode == FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR; | ||
37 | } | |||
38 | #endif // EFI_SHAFT_POSITION_INPUT | |||
39 | ||||
40 | 1122 | void LimpManager::onFastCallback() { | ||
41 | 1122 | updateState(Sensor::getOrZero(SensorType::Rpm), getTimeNowNt()); | ||
42 | 1122 | } | ||
43 | ||||
44 | 2285 | void LimpManager::updateRevLimit(float rpm) { | ||
45 | // User-configured hard RPM limit, either constant or CLT-lookup | |||
46 | 4570 | m_revLimit = engineConfiguration->useCltBasedRpmLimit | ||
47 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2279 times.
|
2285 | ? interpolate2d(Sensor::getOrZero(SensorType::Clt), config->cltRevLimitRpmBins, config->cltRevLimitRpm) | |
48 | 2279 | : (float)engineConfiguration->rpmHardLimit; | ||
49 | ||||
50 | // Require configurable rpm drop before resuming | |||
51 | 2285 | resumeRpm = m_revLimit - engineConfiguration->rpmHardLimitHyst; | ||
52 | ||||
53 | 2285 | m_timingRetard = interpolateClamped(resumeRpm, 0, m_revLimit, engineConfiguration->rpmSoftLimitTimingRetard, rpm); | ||
54 | ||||
55 | 2285 | percent_t fuelAdded = interpolateClamped(resumeRpm, 0, m_revLimit, engineConfiguration->rpmSoftLimitFuelAdded, rpm); | ||
56 | 2285 | m_fuelCorrection = 1.0f + fuelAdded / 100; | ||
57 | 2285 | } | ||
58 | ||||
59 | 1165 | void LimpManager::updateState(float rpm, efitick_t nowNt) { | ||
60 | 1165 | Clearable allowFuel = engineConfiguration->isInjectionEnabled; | ||
61 | 1165 | Clearable allowSpark = engineConfiguration->isIgnitionEnabled; | ||
62 | ||||
63 | #if EFI_SHAFT_POSITION_INPUT && !EFI_UNIT_TEST | |||
64 | if (!m_ignitionOn | |||
65 | && !engine->triggerCentral.directSelfStimulation // useful to try things on real ECU even without ignition voltage | |||
66 | ) { | |||
67 | allowFuel.clear(ClearReason::IgnitionOff); | |||
68 | allowSpark.clear(ClearReason::IgnitionOff); | |||
69 | } | |||
70 | #endif | |||
71 | ||||
72 |
5/7✓ Branch 1 taken 1165 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1159 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (isGdiEngine() && engineConfiguration->externalRusEfiGdiModule) { |
73 | ✗ | if (externalGdiCanBusComms.getElapsedSeconds() > 1) { | ||
74 | ✗ | allowFuel.clear(ClearReason::GdiComms); | ||
75 | } | |||
76 | } | |||
77 | ||||
78 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (engine->engineState.lua.luaIgnCut) { |
79 | ✗ | allowSpark.clear(ClearReason::Lua); | ||
80 | } | |||
81 | ||||
82 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (engine->engineState.lua.luaFuelCut) { |
83 | ✗ | allowFuel.clear(ClearReason::Lua); | ||
84 | } | |||
85 | ||||
86 |
1/1✓ Branch 1 taken 1165 times.
|
1165 | updateRevLimit(rpm); | |
87 |
3/3✓ Branch 1 taken 1165 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 1158 times.
|
2/2✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 1158 times.
|
1165 | if (m_revLimitHysteresis.test(rpm, m_revLimit, resumeRpm)) { |
88 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 7 times.
✗ Decision 'false' not taken.
|
7 | if (engineConfiguration->cutFuelOnHardLimit) { |
89 | 7 | allowFuel.clear(ClearReason::HardLimit); | ||
90 | } | |||
91 | ||||
92 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 7 times.
✗ Decision 'false' not taken.
|
7 | if (engineConfiguration->cutSparkOnHardLimit) { |
93 | 7 | allowSpark.clear(ClearReason::HardLimit); | ||
94 | } | |||
95 | } | |||
96 | ||||
97 | #if EFI_SHAFT_POSITION_INPUT | |||
98 |
2/3✓ Branch 1 taken 1165 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (engine->lambdaMonitor.isCut()) { |
99 | ✗ | allowFuel.clear(ClearReason::LambdaProtection); | ||
100 | } | |||
101 | ||||
102 |
1/1✓ Branch 1 taken 1165 times.
|
2/2✓ Decision 'true' taken 36 times.
✓ Decision 'false' taken 1129 times.
|
1165 | if (noFiringUntilVvtSync() |
103 |
6/6✓ Branch 0 taken 55 times.
✓ Branch 1 taken 1110 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 36 times.
✓ Branch 6 taken 1129 times.
|
1165 | && !engine->triggerCentral.triggerState.hasSynchronizedPhase()) { | |
104 | // Any engine that requires cam-assistance for a full crank sync (symmetrical crank) can't schedule until we have cam sync | |||
105 | // examples: | |||
106 | // NB2, Nissan VQ/MR: symmetrical crank wheel and we need to make sure no spark happens out of sync | |||
107 | // VTwin Harley: uneven firing order, so we need "cam" MAP sync to make sure no spark happens out of sync | |||
108 | 36 | allowFuel.clear(ClearReason::EnginePhase); | ||
109 | 36 | allowSpark.clear(ClearReason::EnginePhase); | ||
110 | } | |||
111 | ||||
112 | // Force fuel limiting on the fault rev limit | |||
113 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (rpm > m_faultRevLimit) { |
114 | ✗ | allowFuel.clear(m_rpmLimitReason); | ||
115 | } | |||
116 | ||||
117 | // Limit fuel only on boost pressure (limiting spark bends valves) | |||
118 | 1165 | float mapCut = engineConfiguration->boostCutPressure; | ||
119 |
2/2✓ Branch 0 taken 1164 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 1164 times.
✓ Decision 'false' taken 1 time.
|
1165 | if (mapCut != 0) { |
120 | // require drop of 'boostCutPressureHyst' kPa to resume fuel | |||
121 |
4/4✓ Branch 2 taken 1164 times.
✓ Branch 5 taken 1164 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 1160 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 1160 times.
|
1164 | if (m_boostCutHysteresis.checkIfLimitIsExceeded(Sensor::getOrZero(SensorType::Map), mapCut, engineConfiguration->boostCutPressureHyst)) { |
122 | 4 | allowFuel.clear(ClearReason::BoostCut); | ||
123 | } | |||
124 | } | |||
125 | ||||
126 |
3/3✓ Branch 1 taken 1165 times.
✓ Branch 3 taken 76 times.
✓ Branch 4 taken 1089 times.
|
2/2✓ Decision 'true' taken 76 times.
✓ Decision 'false' taken 1089 times.
|
1165 | if (engine->rpmCalculator.isRunning()) { |
127 |
1/1✓ Branch 1 taken 76 times.
|
76 | bool hasOilpSensor = Sensor::hasSensor(SensorType::OilPressure); | |
128 |
1/1✓ Branch 2 taken 76 times.
|
76 | auto oilp = Sensor::get(SensorType::OilPressure); | |
129 | 76 | uint16_t minOilPressure = engineConfiguration->minOilPressureAfterStart; | ||
130 | ||||
131 | // Only check if the setting is enabled and you have an oil pressure sensor | |||
132 |
3/4✓ Branch 0 taken 9 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
2/2✓ Decision 'true' taken 9 times.
✓ Decision 'false' taken 67 times.
|
76 | if (minOilPressure > 0 && hasOilpSensor) { |
133 | // Has it been long enough we should have pressure? | |||
134 |
1/1✓ Branch 1 taken 9 times.
|
9 | bool isTimedOut = engine->rpmCalculator.getSecondsSinceEngineStart(nowNt) > 5.0f; | |
135 | ||||
136 | // Only check before timed out | |||
137 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 4 times.
|
9 | if (!isTimedOut) { |
138 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
1/2✓ Decision 'true' taken 5 times.
✗ Decision 'false' not taken.
|
5 | if (oilp) { |
139 | // We had oil pressure! Set the flag. | |||
140 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 4 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 4 times.
|
5 | if (oilp.Value > minOilPressure) { |
141 | 1 | m_hadOilPressureAfterStart = true; | ||
142 | } | |||
143 | } | |||
144 | } | |||
145 | ||||
146 | // If time is up, the sensor works, and no pressure, kill the engine. | |||
147 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 7 times.
|
9 | if (isTimedOut && !m_hadOilPressureAfterStart) { |
148 | 2 | allowFuel.clear(ClearReason::OilPressure); | ||
149 | } | |||
150 | } | |||
151 | ||||
152 |
6/6✓ Branch 1 taken 19 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 71 times.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 71 times.
|
76 | if (oilp && engineConfiguration->enableOilPressureProtect) { |
153 |
1/1✓ Branch 1 taken 5 times.
|
5 | float minPressure = interpolate2d(rpm, config->minimumOilPressureBins, config->minimumOilPressureValues); | |
154 | 5 | bool isPressureSufficient = oilp.Value > minPressure; | ||
155 | ||||
156 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 2 times.
|
5 | if (isPressureSufficient) { |
157 |
1/1✓ Branch 1 taken 3 times.
|
3 | m_lowOilPressureTimer.reset(nowNt); | |
158 | } | |||
159 | ||||
160 |
3/3✓ Branch 2 taken 5 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 4 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 4 times.
|
5 | if (m_lowOilPressureTimer.hasElapsedSec(engineConfiguration->minimumOilPressureTimeout)) { |
161 | 1 | allowFuel.clear(ClearReason::OilPressure); | ||
162 | } | |||
163 | } | |||
164 | ||||
165 | // check the maximum oil pressure | |||
166 |
1/1✓ Branch 1 taken 76 times.
|
76 | float maxOilPressure = interpolate2d(rpm, config->maximumOilPressureBins, config->maximumOilPressureValues); | |
167 |
3/4✓ Branch 0 taken 5 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 71 times.
|
76 | if (maxOilPressure > 0 && hasOilpSensor) { |
168 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 2 times.
|
5 | if (oilp.Value < maxOilPressure) { |
169 |
1/1✓ Branch 1 taken 3 times.
|
3 | m_highOilPressureTimer.reset(nowNt); | |
170 | } | |||
171 |
3/3✓ Branch 2 taken 5 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 4 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 4 times.
|
5 | if (m_highOilPressureTimer.hasElapsedSec(engineConfiguration->maxOilPressureTimeout)) { |
172 | 1 | allowFuel.clear(ClearReason::OilPressure); | ||
173 | } | |||
174 | } | |||
175 | ||||
176 | } else { | |||
177 | // reset state in case of stalled engine | |||
178 | 1089 | m_hadOilPressureAfterStart = false; | ||
179 |
1/1✓ Branch 1 taken 1089 times.
|
1089 | m_lowOilPressureTimer.reset(nowNt); | |
180 | } | |||
181 | ||||
182 | // If we're in engine stop mode, inhibit fuel | |||
183 |
2/3✓ Branch 1 taken 1165 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (shutdownController.isEngineStop(nowNt)) { |
184 | /** | |||
185 | * todo: we need explicit clarification on why do we cut fuel but do not cut spark here! | |||
186 | */ | |||
187 | ✗ | allowFuel.clear(ClearReason::StopRequested); | ||
188 | } | |||
189 | ||||
190 | { | |||
191 | // todo: we need to add some tests of this? | |||
192 | // If duty cycle is high, impose a fuel cut rev limiter. | |||
193 | // This is safer than attempting to limp along with injectors or a pump that are out of flow. | |||
194 | // Two conditions will trigger a cut: | |||
195 | // - An instantaneous excursion above maxInjectorDutyInstant | |||
196 | // - A sustained excursion above maxInjectorDutySustained for a duration of >= maxInjectorDutySustainedTimeout | |||
197 | // Only reset once below 20% duty to force the driver to lift off the pedal | |||
198 | ||||
199 |
1/1✓ Branch 1 taken 1165 times.
|
1165 | auto injDutyCycle = getInjectorDutyCycle(rpm); | |
200 | 1165 | bool isOverInstantDutyCycle = injDutyCycle > engineConfiguration->maxInjectorDutyInstant; | ||
201 | 1165 | bool isOverSustainedDutyCycle = injDutyCycle > engineConfiguration->maxInjectorDutySustained; | ||
202 | 1165 | bool isUnderLowDuty = injDutyCycle < 20; | ||
203 | ||||
204 |
1/2✓ Branch 0 taken 1165 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 1165 times.
✗ Decision 'false' not taken.
|
1165 | if (!isOverSustainedDutyCycle) { |
205 | // Duty cycle is OK, reset timer. | |||
206 |
1/1✓ Branch 1 taken 1165 times.
|
1165 | m_injectorDutySustainedTimer.reset(nowNt); | |
207 | } | |||
208 | ||||
209 | // True if isOverSustainedDutyCycle has been true for longer than the timeout | |||
210 |
1/1✓ Branch 2 taken 1165 times.
|
1165 | bool sustainedLimitTimedOut = m_injectorDutySustainedTimer.hasElapsedSec(engineConfiguration->maxInjectorDutySustainedTimeout); | |
211 | ||||
212 |
2/4✓ Branch 0 taken 1165 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1165 times.
|
1165 | bool someLimitTripped = isOverInstantDutyCycle || sustainedLimitTimedOut; | |
213 | ||||
214 |
2/3✓ Branch 1 taken 1165 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (m_injectorDutyCutHysteresis.test(someLimitTripped, isUnderLowDuty)) { |
215 | ✗ | allowFuel.clear(ClearReason::InjectorDutyCycle); | ||
216 | ✗ | warning(ObdCode::CUSTOM_TOO_LONG_FUEL_INJECTION, "Injector duty cycle cut %.1f", injDutyCycle); | ||
217 | } | |||
218 | } | |||
219 | ||||
220 | { | |||
221 | // GDI Fuel cut | |||
222 | 1165 | bool isGDIDriverInjectorTimeTooLong = engine->engineState.injectionDuration > engineConfiguration->mc33_t_hold_tot; | ||
223 | ||||
224 |
7/7✓ Branch 1 taken 1165 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1159 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 1164 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 1164 times.
|
1165 | if (isGdiEngine() && isGDIDriverInjectorTimeTooLong) { |
225 | 1 | allowFuel.clear(ClearReason::GdiLimits); | ||
226 |
1/1✓ Branch 1 taken 1 time.
|
1 | warning(ObdCode::CUSTOM_TOO_LONG_FUEL_INJECTION, "Injection duration excess PT2001 limits time: %.4f", engine->engineState.injectionDuration); | |
227 | } | |||
228 | } | |||
229 | ||||
230 | // If the pedal is pushed while not running, cut fuel to clear a flood condition. | |||
231 |
1/1✓ Branch 1 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (!engine->rpmCalculator.isRunning() && |
232 |
4/6✓ Branch 0 taken 1089 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 1089 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1165 times.
|
2254 | engineConfiguration->isCylinderCleanupEnabled && | |
233 |
2/3✓ Branch 1 taken 1089 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1089 times.
|
1089 | Sensor::getOrZero(SensorType::DriverThrottleIntent) > CLEANUP_MODE_TPS) { | |
234 | ✗ | allowFuel.clear(ClearReason::FloodClear); | ||
235 | } | |||
236 | #endif // EFI_SHAFT_POSITION_INPUT | |||
237 | ||||
238 |
1/1✓ Branch 1 taken 1165 times.
|
1/2✓ Decision 'true' taken 1165 times.
✗ Decision 'false' not taken.
|
1165 | if (!engine->isMainRelayEnabled()) { |
239 | /* | |||
240 | todo AndreiKA this change breaks 22 unit tests? | |||
241 | allowFuel.clear(); | |||
242 | allowSpark.clear(); | |||
243 | */ | |||
244 | } | |||
245 | ||||
246 | #if EFI_LAUNCH_CONTROL | |||
247 | // Fuel cut if launch control engaged | |||
248 |
2/3✓ Branch 1 taken 1165 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1165 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1165 times.
|
1165 | if (engine->launchController.isLaunchFuelRpmRetardCondition()) { |
249 | ✗ | allowFuel.clear(ClearReason::LaunchCut); | ||
250 | } | |||
251 | ||||
252 | // Spark cut if launch control engaged | |||
253 |
3/3✓ Branch 1 taken 1165 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 1157 times.
|
2/2✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 1157 times.
|
1165 | if (engine->launchController.isLaunchSparkRpmRetardCondition()) { |
254 | 8 | allowSpark.clear(ClearReason::LaunchCut); | ||
255 | } | |||
256 | #endif // EFI_LAUNCH_CONTROL | |||
257 | ||||
258 | 1165 | m_transientAllowInjection = allowFuel; | ||
259 | 1165 | m_transientAllowIgnition = allowSpark; | ||
260 | ||||
261 |
6/6✓ Branch 1 taken 1071 times.
✓ Branch 2 taken 94 times.
✓ Branch 4 taken 69 times.
✓ Branch 5 taken 1002 times.
✓ Branch 6 taken 163 times.
✓ Branch 7 taken 1002 times.
|
2/2✓ Decision 'true' taken 163 times.
✓ Decision 'false' taken 1002 times.
|
1165 | if (!m_transientAllowInjection || !m_transientAllowIgnition) { |
262 | // Tracks the last time any cut happened | |||
263 |
1/1✓ Branch 1 taken 163 times.
|
163 | m_lastCutTime.reset(nowNt); | |
264 | } | |||
265 | 1165 | } | ||
266 | ||||
267 | 1 | void LimpManager::onIgnitionStateChanged(bool ignitionOn) { | ||
268 | 1 | m_ignitionOn = ignitionOn; | ||
269 | 1 | } | ||
270 | ||||
271 | 1 | void LimpManager::reportEtbProblem() { | ||
272 | 1 | m_allowEtb.clear(ClearReason::EtbProblem); | ||
273 | 1 | setFaultRevLimit(/*rpm*/1500, ClearReason::EtbFaultRevLimit); | ||
274 | 1 | } | ||
275 | ||||
276 | 2 | void LimpManager::fatalError() { | ||
277 | 2 | m_allowEtb.clear(ClearReason::Fatal); | ||
278 | 2 | m_allowIgnition.clear(ClearReason::Fatal); | ||
279 | 2 | m_allowInjection.clear(ClearReason::Fatal); | ||
280 | 2 | m_allowTriggerInput.clear(ClearReason::Fatal); | ||
281 | ||||
282 | 2 | setFaultRevLimit(/*rpm*/0, ClearReason::FatalErrorRevLimit); | ||
283 | 2 | } | ||
284 | ||||
285 | 3 | void LimpManager::setFaultRevLimit(int limit, ClearReason rpmLimitReason) { | ||
286 | // Only allow decreasing the limit | |||
287 | // aka uses the limit of the worst fault to yet occur | |||
288 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 3 times.
✗ Decision 'false' not taken.
|
3 | if (limit < m_faultRevLimit) { |
289 | 3 | m_faultRevLimit = limit; | ||
290 | 3 | m_rpmLimitReason = rpmLimitReason; | ||
291 | } | |||
292 | 3 | } | ||
293 | ||||
294 | #if EFI_ELECTRONIC_THROTTLE_BODY | |||
295 | 417 | bool LimpManager::allowElectronicThrottle() const { | ||
296 |
3/4✓ Branch 1 taken 2 times.
✓ Branch 2 taken 415 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
417 | return m_allowEtb || engine->etbIgnoreJamProtection; | |
297 | } | |||
298 | #endif // EFI_ELECTRONIC_THROTTLE_BODY | |||
299 | ||||
300 | 67209 | bool LimpManager::allowTriggerInput() const { | ||
301 | 67209 | return m_allowTriggerInput; | ||
302 | } | |||
303 | ||||
304 | 31232 | LimpState LimpManager::allowInjection() const { | ||
305 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 31231 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 31231 times.
|
31232 | if (!m_allowInjection) { |
306 | 1 | return {false, m_allowInjection.clearReason}; | ||
307 | } | |||
308 |
2/2✓ Branch 1 taken 2361 times.
✓ Branch 2 taken 28870 times.
|
2/2✓ Decision 'true' taken 2361 times.
✓ Decision 'false' taken 28870 times.
|
31231 | if (!m_transientAllowInjection) { |
309 | 2361 | return {false, m_transientAllowInjection.clearReason}; | ||
310 | } | |||
311 | 28870 | return {true, ClearReason::None}; | ||
312 | } | |||
313 | ||||
314 | 30532 | LimpState LimpManager::allowIgnition() const { | ||
315 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 30531 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 30531 times.
|
30532 | if (!m_allowIgnition) { |
316 | 1 | return {false, m_allowIgnition.clearReason}; | ||
317 | } | |||
318 |
2/2✓ Branch 1 taken 342 times.
✓ Branch 2 taken 30189 times.
|
2/2✓ Decision 'true' taken 342 times.
✓ Decision 'false' taken 30189 times.
|
30531 | if (!m_transientAllowIgnition) { |
319 | 342 | return {false, m_transientAllowIgnition.clearReason}; | ||
320 | } | |||
321 | 30189 | return {true, ClearReason::None}; | ||
322 | } | |||
323 | ||||
324 | 1092 | angle_t LimpManager::getLimitingTimingRetard() const { | ||
325 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1092 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1092 times.
|
1092 | if (!engineConfiguration->cutSparkOnHardLimit) |
326 | ✗ | return 0; | ||
327 | 1092 | return m_timingRetard; | ||
328 | } | |||
329 | ||||
330 | 989 | float LimpManager::getLimitingFuelCorrection() const { | ||
331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 989 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 989 times.
|
989 | if (!engineConfiguration->cutFuelOnHardLimit) |
332 | ✗ | return 1.0f; // no correction | ||
333 | 989 | return m_fuelCorrection; | ||
334 | } | |||
335 | ||||
336 | 1 | float LimpManager::getTimeSinceAnyCut() const { | ||
337 | 1 | return m_lastCutTime.getElapsedSeconds(); | ||
338 | } | |||
339 | #endif // EFI_ENGINE_CONTROL | |||
340 |