GCC Code Coverage Report


Directory: ./
File: firmware/controllers/trigger/decoders/trigger_structure.cpp
Date: 2025-10-03 00:57:22
Warnings: 1 unchecked decisions!
Coverage Exec Excl Total
Lines: 95.2% 477 0 501
Functions: 100.0% 30 0 30
Branches: 87.9% 181 0 206
Decisions: 92.3% 156 - 169

Line Branch Decision Exec Source
1 /**
2 * @file trigger_structure.cpp
3 *
4 * @date Jan 20, 2014
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 *
7 * This file is part of rusEfi - see http://rusefi.com
8 *
9 * rusEfi is free software; you can redistribute it and/or modify it under the terms of
10 * the GNU General Public License as published by the Free Software Foundation; either
11 * version 3 of the License, or (at your option) any later version.
12 *
13 * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with this program.
18 * If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "pch.h"
22
23 #include "trigger_chrysler.h"
24 #include "trigger_ford.h"
25 #include "trigger_gm.h"
26 #include "trigger_nissan.h"
27 #include "trigger_mazda.h"
28 #include "trigger_misc.h"
29 #include "trigger_mitsubishi.h"
30 #include "trigger_renault.h"
31 #include "trigger_subaru.h"
32 #include "trigger_suzuki.h"
33 #include "trigger_structure.h"
34 #include "trigger_toyota.h"
35 #include "trigger_renix.h"
36 #include "trigger_rover.h"
37 #include "trigger_honda.h"
38 #include "trigger_vw.h"
39 #include "trigger_universal.h"
40 #include "trigger_mercedes.h"
41 #include "engine_state.h"
42
43 261039 void wrapAngle(angle_t& angle, const char* msg, ObdCode code) {
44
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 261039 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 261039 times.
261039 if (std::isnan(angle)) {
45 firmwareError(ObdCode::CUSTOM_ERR_ANGLE, "a NaN %s", msg);
46 angle = 0;
47 }
48
49
2/4
✓ Branch 0 taken 261039 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 261039 times.
261039 assertAngleRange(angle, msg, code);
50 261039 float engineCycle = getEngineState()->engineCycle;
51
52
2/2
✓ Branch 0 taken 30709 times.
✓ Branch 1 taken 261039 times.
2/2
✓ Decision 'true' taken 30709 times.
✓ Decision 'false' taken 261039 times.
291748 while (angle < 0) {
53 30709 angle += engineCycle;
54 }
55
56
2/2
✓ Branch 0 taken 5581 times.
✓ Branch 1 taken 261039 times.
2/2
✓ Decision 'true' taken 5581 times.
✓ Decision 'false' taken 261039 times.
266620 while (angle >= engineCycle) {
57 5581 angle -= engineCycle;
58 }
59 261039 }
60
61 2044 TriggerWaveform::TriggerWaveform() {
62 2044 initialize(OM_NONE, SyncEdge::Rise);
63 2044 }
64
65 3043 void TriggerWaveform::initialize(operation_mode_e p_operationMode, SyncEdge p_syncEdge) {
66 3043 operationMode = p_operationMode;
67 3043 syncEdge = p_syncEdge;
68
69 3043 isSynchronizationNeeded = true; // that's default value
70 3043 isSecondWheelCam = false;
71 3043 needSecondTriggerInput = false;
72 3043 shapeWithoutTdc = false;
73
74 // If RiseOnly, ignore falling edges completely.
75 3043 useOnlyRisingEdges = syncEdge == SyncEdge::RiseOnly;
76
77 3043 setTriggerSynchronizationGap(2);
78
2/2
✓ Branch 0 taken 51731 times.
✓ Branch 1 taken 3043 times.
2/2
✓ Decision 'true' taken 51731 times.
✓ Decision 'false' taken 3043 times.
54774 for (int gapIndex = 1; gapIndex < GAP_TRACKING_LENGTH ; gapIndex++) {
79 // NaN means do not use this gap ratio
80 51731 setTriggerSynchronizationGap3(gapIndex, NAN, 100000);
81 }
82 3043 gapTrackingLength = 1;
83
84 3043 tdcPosition = 0;
85 3043 shapeDefinitionError = false;
86 3043 useOnlyPrimaryForSync = false;
87
88 3043 triggerShapeSynchPointIndex = 0;
89 3043 setArrayValues(expectedEventCount, 0);
90 3043 wave.reset();
91 3043 wave.waveCount = TRIGGER_INPUT_PIN_COUNT;
92 3043 wave.phaseCount = 0;
93 3043 previousAngle = 0;
94 3043 setArrayValues(isRiseEvent, 0);
95 #if EFI_UNIT_TEST
96 3043 memset(triggerSignalIndeces, 0, sizeof(triggerSignalIndeces));
97 3043 memset(&triggerSignalStates, 0, sizeof(triggerSignalStates));
98 3043 knownOperationMode = true;
99 #endif // EFI_UNIT_TEST
100 3043 }
101
102 1452265 size_t TriggerWaveform::getSize() const {
103 1452265 return wave.phaseCount;
104 }
105
106 5170 int TriggerWaveform::getTriggerWaveformSynchPointIndex() const {
107 5170 return triggerShapeSynchPointIndex;
108 }
109
110 /**
111 * physical primary trigger duration
112 * @see getEngineCycle
113 * @see getCrankDivider
114 */
115 173704 angle_t TriggerWaveform::getCycleDuration() const {
116
6/7
✓ Branch 0 taken 4374 times.
✓ Branch 1 taken 10014 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 782 times.
✓ Branch 4 taken 91943 times.
✓ Branch 5 taken 66505 times.
✗ Branch 6 not taken.
173704 switch (operationMode) {
117
1/1
✓ Decision 'true' taken 4374 times.
4374 case FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR:
118 4374 return FOUR_STROKE_CYCLE_DURATION / SYMMETRICAL_CRANK_SENSOR_DIVIDER;
119
1/1
✓ Decision 'true' taken 10014 times.
10014 case FOUR_STROKE_THREE_TIMES_CRANK_SENSOR:
120 10014 return FOUR_STROKE_CYCLE_DURATION / SYMMETRICAL_THREE_TIMES_CRANK_SENSOR_DIVIDER;
121
1/1
✓ Decision 'true' taken 86 times.
86 case FOUR_STROKE_SIX_TIMES_CRANK_SENSOR:
122 86 return FOUR_STROKE_CYCLE_DURATION / SYMMETRICAL_SIX_TIMES_CRANK_SENSOR_DIVIDER;
123
1/1
✓ Decision 'true' taken 782 times.
782 case FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR:
124 782 return FOUR_STROKE_CYCLE_DURATION / SYMMETRICAL_TWELVE_TIMES_CRANK_SENSOR_DIVIDER;
125
1/1
✓ Decision 'true' taken 91943 times.
91943 case FOUR_STROKE_CRANK_SENSOR:
126 case TWO_STROKE:
127
1/1
✓ Decision 'true' taken 91943 times.
91943 return TWO_STROKE_CYCLE_DURATION;
128
1/1
✓ Decision 'true' taken 66505 times.
66505 case OM_NONE:
129 case FOUR_STROKE_CAM_SENSOR:
130
1/1
✓ Decision 'true' taken 66505 times.
66505 return FOUR_STROKE_CYCLE_DURATION;
131 }
132 criticalError("unreachable getCycleDuration");
133 return 0;
134 }
135
136 907 bool TriggerWaveform::needsDisambiguation() const {
137
2/3
✓ Branch 1 taken 163 times.
✓ Branch 2 taken 744 times.
✗ Branch 3 not taken.
907 switch (getWheelOperationMode()) {
138
1/1
✓ Decision 'true' taken 163 times.
163 case FOUR_STROKE_CRANK_SENSOR:
139 case FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR:
140 case FOUR_STROKE_THREE_TIMES_CRANK_SENSOR:
141 case FOUR_STROKE_SIX_TIMES_CRANK_SENSOR:
142 case FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR:
143
1/1
✓ Decision 'true' taken 163 times.
163 return true;
144
1/1
✓ Decision 'true' taken 744 times.
744 case FOUR_STROKE_CAM_SENSOR:
145 case TWO_STROKE:
146 case OM_NONE:
147
1/1
✓ Decision 'true' taken 744 times.
744 return false;
148 /* let's NOT handle default in order to benefit from -Werror=switch */
149 }
150 criticalError("unreachable needsDisambiguation");
151 return true;
152 }
153
154 /**
155 * Trigger event count equals engine cycle event count if we have a cam sensor.
156 * Two trigger cycles make one engine cycle in case of a four stroke engine If we only have a cranksensor.
157 *
158 * 'engine->engineCycleEventCount' hold a pre-calculated copy of this value as a performance optimization
159 */
160
1/1
✓ Decision 'true' taken 114922 times.
114922 size_t TriggerWaveform::getLength() const {
161 /**
162 * 24 for FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR
163 * 6 for FOUR_STROKE_THREE_TIMES_CRANK_SENSOR
164 * 4 for FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR
165 * 2 for FOUR_STROKE_CRANK_SENSOR
166 * 1 otherwise
167 */
168 114922 int multiplier = getEngineCycle(operationMode) / getCycleDuration();
169 114922 return multiplier * getSize();
170 }
171
172 28302 angle_t TriggerWaveform::getAngle(int index) const {
173 /**
174 * FOUR_STROKE_CRANK_SENSOR magic:
175 * We have two crank shaft revolutions for each engine cycle
176 * See also trigger_central.cpp
177 * See also getEngineCycleEventCount()
178 */
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28302 times.
28302 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, wave.phaseCount != 0, "shapeSize=0", NAN);
180 28302 int crankCycle = index / wave.phaseCount;
181 28302 int remainder = index % wave.phaseCount;
182
183 28302 auto cycleStartAngle = getCycleDuration() * crankCycle;
184 28302 auto positionWithinCycle = getSwitchAngle(remainder);
185
186 28302 return cycleStartAngle + positionWithinCycle;
187 }
188
189 9832 void TriggerWaveform::addEventClamped(angle_t angle, TriggerValue const stateParam, TriggerWheel const channelIndex, float filterLeft, float filterRight) {
190
4/4
✓ Branch 0 taken 9619 times.
✓ Branch 1 taken 213 times.
✓ Branch 2 taken 8843 times.
✓ Branch 3 taken 776 times.
2/2
✓ Decision 'true' taken 8843 times.
✓ Decision 'false' taken 989 times.
9832 if (angle > filterLeft && angle < filterRight) {
191 #if EFI_UNIT_TEST
192 // printf("addEventClamped %f %s\r\n", angle, getTrigger_value_e(stateParam));
193 #endif /* EFI_UNIT_TEST */
194 8843 addEvent(angle / getEngineCycle(operationMode), stateParam, channelIndex);
195 }
196 9832 }
197
198 /**
199 * See also Engine#getOperationMode which accounts for additional settings which are
200 * needed to resolve precise mode for vague wheels
201 */
202 1508433 operation_mode_e TriggerWaveform::getWheelOperationMode() const {
203 1508433 return operationMode;
204 }
205
206 #if EFI_UNIT_TEST
207 extern bool printTriggerDebug;
208 #endif
209
210 28125 size_t TriggerWaveform::getExpectedEventCount(TriggerWheel channelIndex) const {
211 28125 return expectedEventCount[(int)channelIndex];
212 }
213
214 991 void TriggerWaveform::calculateExpectedEventCounts() {
215
2/2
✓ Branch 0 taken 708 times.
✓ Branch 1 taken 283 times.
2/2
✓ Decision 'true' taken 708 times.
✓ Decision 'false' taken 283 times.
991 if (!useOnlyRisingEdges) {
216
2/2
✓ Branch 1 taken 1416 times.
✓ Branch 2 taken 708 times.
2/2
✓ Decision 'true' taken 1416 times.
✓ Decision 'false' taken 708 times.
2124 for (size_t i = 0; i < efi::size(expectedEventCount); i++) {
217
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1416 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 1416 times.
1416 if (getExpectedEventCount((TriggerWheel)i) % 2 != 0) {
218 firmwareError(ObdCode::ERROR_TRIGGER_DRAMA, "Trigger: should be even number of events index=%d count=%d", i, getExpectedEventCount((TriggerWheel)i));
219 }
220 }
221 }
222
223
2/2
✓ Branch 0 taken 283 times.
✓ Branch 1 taken 708 times.
991 bool isSingleToothOnPrimaryChannel = useOnlyRisingEdges ? getExpectedEventCount(TriggerWheel::T_PRIMARY) == 1 : getExpectedEventCount(TriggerWheel::T_PRIMARY) == 2;
224 // todo: next step would be to set 'isSynchronizationNeeded' automatically based on the logic we have here
225
3/4
✓ Branch 0 taken 947 times.
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 947 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 991 times.
991 if (!shapeWithoutTdc && isSingleToothOnPrimaryChannel != !isSynchronizationNeeded) {
226 firmwareError(ObdCode::ERROR_TRIGGER_DRAMA, "shapeWithoutTdc isSynchronizationNeeded isSingleToothOnPrimaryChannel constraint violation");
227 }
228
2/2
✓ Branch 0 taken 675 times.
✓ Branch 1 taken 316 times.
2/2
✓ Decision 'true' taken 675 times.
✓ Decision 'false' taken 316 times.
991 if (isSingleToothOnPrimaryChannel) {
229 675 useOnlyPrimaryForSync = true;
230 } else {
231
4/6
✓ Branch 1 taken 299 times.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 299 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 316 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 316 times.
316 if (getExpectedEventCount(TriggerWheel::T_SECONDARY) == 0 && useOnlyPrimaryForSync) {
232 firmwareError(ObdCode::ERROR_TRIGGER_DRAMA, "why would you set useOnlyPrimaryForSync with only one trigger wheel?");
233 }
234 }
235
236 // todo: move the following logic from below here
237 // if (!useOnlyRisingEdgeForTrigger || stateParam == TriggerValue::RISE) {
238 // expectedEventCount[channelIndex]++;
239 // }
240
241 991 }
242
243 /**
244 * See header for documentation
245 */
246 982 void TriggerWaveform::addEvent720(angle_t angle, TriggerValue const state, TriggerWheel const channelIndex) {
247 982 addEvent(angle / FOUR_STROKE_CYCLE_DURATION, state, channelIndex);
248 982 }
249
250 4066 void TriggerWaveform::addEvent360(angle_t angle, TriggerValue const state, TriggerWheel const channelIndex) {
251
3/4
✓ Branch 0 taken 1210 times.
✓ Branch 1 taken 2856 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1210 times.
0/1
? Decision couldn't be analyzed.
4066 efiAssertVoid(ObdCode::CUSTOM_OMODE_UNDEF, operationMode == FOUR_STROKE_CAM_SENSOR || operationMode == FOUR_STROKE_CRANK_SENSOR, "Not a mode for 360");
252 #define CRANK_MODE_MULTIPLIER 2.0f
253 4066 addEvent(CRANK_MODE_MULTIPLIER * angle / FOUR_STROKE_CYCLE_DURATION, state, channelIndex);
254 }
255
256 400 void TriggerWaveform::addToothRiseFall(angle_t angle, angle_t width, TriggerWheel const channelIndex) {
257 400 addEvent360(angle - width, TriggerValue::RISE, channelIndex);
258 400 addEvent360(angle, TriggerValue::FALL, channelIndex);
259 400 }
260
261 306 void TriggerWaveform::addToothFallRise(angle_t angle, angle_t width, TriggerWheel const channelIndex) {
262 306 addEvent360(angle - width, TriggerValue::FALL, channelIndex);
263 306 addEvent360(angle, TriggerValue::RISE, channelIndex);
264 306 }
265
266 926 void TriggerWaveform::addEventAngle(angle_t angle, TriggerValue const state, TriggerWheel const channelIndex) {
267 926 addEvent(angle / getCycleDuration(), state, channelIndex);
268 926 }
269
270 14818 void TriggerWaveform::addEvent(angle_t angle, TriggerValue const state, TriggerWheel const channelIndex) {
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14818 times.
14818 efiAssertVoid(ObdCode::CUSTOM_OMODE_UNDEF, operationMode != OM_NONE, "operationMode not set");
272
273
2/2
✓ Branch 0 taken 2170 times.
✓ Branch 1 taken 12648 times.
2/2
✓ Decision 'true' taken 2170 times.
✓ Decision 'false' taken 12648 times.
14818 if (channelIndex == TriggerWheel::T_SECONDARY) {
274 2170 needSecondTriggerInput = true;
275 }
276
277 #if EFI_UNIT_TEST
278
2/2
✓ Branch 0 taken 11278 times.
✓ Branch 1 taken 3540 times.
2/2
✓ Decision 'true' taken 11278 times.
✓ Decision 'false' taken 3540 times.
14818 if (printTriggerDebug) {
279 11278 printf("addEvent2 %.2f i=%d front=%d\r\n", angle, channelIndex, state);
280 }
281 #endif
282
283 #if EFI_UNIT_TEST
284
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14818 times.
14818 assertIsInBounds(wave.phaseCount, triggerSignalIndeces, "trigger shape overflow");
285 14818 triggerSignalIndeces[wave.phaseCount] = channelIndex;
286 14818 triggerSignalStates[wave.phaseCount] = state;
287 #endif // EFI_UNIT_TEST
288
289
290 // todo: the whole 'useOnlyRisingEdgeForTrigger' parameter and logic should not be here
291 // todo: see calculateExpectedEventCounts
292 // related calculation should be done once trigger is initialized outside of trigger shape scope
293
4/4
✓ Branch 0 taken 11102 times.
✓ Branch 1 taken 3716 times.
✓ Branch 2 taken 5551 times.
✓ Branch 3 taken 5551 times.
2/2
✓ Decision 'true' taken 9267 times.
✓ Decision 'false' taken 5551 times.
14818 if (!useOnlyRisingEdges || state == TriggerValue::RISE) {
294 9267 expectedEventCount[(int)channelIndex]++;
295 }
296
297
2/4
✓ Branch 0 taken 14818 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14818 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 14818 times.
14818 if (angle <= 0 || angle > 1) {
298 firmwareError(ObdCode::CUSTOM_ERR_6599, "angle should be positive not above 1: index=%d angle %f", (int)channelIndex, angle);
299 return;
300 }
301
2/2
✓ Branch 0 taken 13819 times.
✓ Branch 1 taken 999 times.
2/2
✓ Decision 'true' taken 13819 times.
✓ Decision 'false' taken 999 times.
14818 if (wave.phaseCount > 0) {
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13819 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 13819 times.
13819 if (angle <= previousAngle) {
303 warning(ObdCode::CUSTOM_ERR_TRG_ANGLE_ORDER, "invalid angle order %s %s: new=%.2f/%f and prev=%.2f/%f, size=%d",
304 getTriggerWheel(channelIndex),
305 getTrigger_value_e(state),
306 angle, angle * getCycleDuration(),
307 previousAngle, previousAngle * getCycleDuration(),
308 wave.phaseCount);
309 setShapeDefinitionError(true);
310 return;
311 }
312 }
313 14818 previousAngle = angle;
314
2/2
✓ Branch 0 taken 999 times.
✓ Branch 1 taken 13819 times.
2/2
✓ Decision 'true' taken 999 times.
✓ Decision 'false' taken 13819 times.
14818 if (wave.phaseCount == 0) {
315 999 wave.phaseCount = 1;
316
2/2
✓ Branch 0 taken 1998 times.
✓ Branch 1 taken 999 times.
2/2
✓ Decision 'true' taken 1998 times.
✓ Decision 'false' taken 999 times.
2997 for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
317 1998 wave.setChannelState(i, /* switchIndex */ 0, TriggerValue::FALL);
318 }
319
320 999 isRiseEvent[0] = TriggerValue::RISE == state;
321 999 wave.setSwitchTime(0, angle);
322 999 wave.setChannelState((int)channelIndex, /* channelIndex */ 0, /* value */ state);
323 999 return;
324 }
325
326
2/3
✓ Branch 2 taken 13819 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13819 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 13819 times.
13819 if (wave.findAngleMatch(angle)) {
327 warning(ObdCode::CUSTOM_ERR_SAME_ANGLE, "same angle: not supported");
328 setShapeDefinitionError(true);
329 return;
330 }
331
332 13819 int index = wave.findInsertionAngle(angle);
333
334 /**
335 * todo: it would be nice to be able to provide trigger angles without sorting them externally
336 * The idea here is to shift existing data - including handling high vs low state of the signals
337 */
338 // todo: does this logic actually work? I think it does not! due to broken state handling
339 /*
340 for (int i = size - 1; i >= index; i--) {
341 for (int j = 0; j < PWM_PHASE_MAX_WAVE_PER_PWM; j++) {
342 wave.waves[j].pinStates[i + 1] = wave.getChannelState(j, index);
343 }
344 wave.setSwitchTime(i + 1, wave.getSwitchTime(i));
345 }
346 */
347 13819 isRiseEvent[index] = TriggerValue::RISE == state;
348
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13819 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 13819 times.
13819 if ((unsigned)index != wave.phaseCount) {
350 firmwareError(ObdCode::ERROR_TRIGGER_DRAMA, "are we ever here?");
351 }
352
353 13819 wave.phaseCount++;
354
355
2/2
✓ Branch 0 taken 27638 times.
✓ Branch 1 taken 13819 times.
2/2
✓ Decision 'true' taken 27638 times.
✓ Decision 'false' taken 13819 times.
41457 for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
356 27638 pin_state_t value = wave.getChannelState(/* channelIndex */i, index - 1);
357 27638 wave.setChannelState(i, index, value);
358 }
359 13819 wave.setSwitchTime(index, angle);
360 13819 wave.setChannelState((int)channelIndex, index, state);
361 }
362
363 28446 angle_t TriggerWaveform::getSwitchAngle(int index) const {
364 28446 return getCycleDuration() * wave.getSwitchTime(index);
365 }
366
367 71 void TriggerWaveform::setTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo) {
368 71 setTriggerSynchronizationGap3(/*gapIndex*/0, syncRatioFrom, syncRatioTo);
369 71 }
370
371 56268 void TriggerWaveform::setTriggerSynchronizationGap3(int gapIndex, float syncRatioFrom, float syncRatioTo) {
372 56268 isSynchronizationNeeded = true;
373
2/4
✓ Branch 0 taken 56268 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 56268 times.
56268 criticalAssertVoid(gapIndex >= 0 && gapIndex < GAP_TRACKING_LENGTH, "gapIndex out of range");
374 56268 synchronizationRatioFrom[gapIndex] = syncRatioFrom;
375 56268 synchronizationRatioTo[gapIndex] = syncRatioTo;
376
2/2
✓ Branch 0 taken 3665 times.
✓ Branch 1 taken 52603 times.
2/2
✓ Decision 'true' taken 3665 times.
✓ Decision 'false' taken 52603 times.
56268 if (gapIndex == 0) {
377 // we have a special case here - only sync with one gap has this feature
378 3665 this->syncRatioAvg = (int)efiRound((syncRatioFrom + syncRatioTo) * 0.5f, 1.0f);
379 }
380 56268 gapTrackingLength = maxI(1 + gapIndex, gapTrackingLength);
381
382 #if EFI_UNIT_TEST
383
2/2
✓ Branch 0 taken 47199 times.
✓ Branch 1 taken 9069 times.
2/2
✓ Decision 'true' taken 47199 times.
✓ Decision 'false' taken 9069 times.
56268 if (printTriggerDebug) {
384 47199 printf("setTriggerSynchronizationGap3 %d %.2f %.2f\r\n", gapIndex, syncRatioFrom, syncRatioTo);
385 }
386 #endif /* EFI_UNIT_TEST */
387
388 }
389
390 31501 uint16_t TriggerWaveform::findAngleIndex(TriggerFormDetails *details, angle_t targetAngle) const {
391 31501 size_t engineCycleEventCount = getLength();
392
393
2/4
✓ Branch 0 taken 31501 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 31501 times.
31501 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, engineCycleEventCount != 0 && engineCycleEventCount <= 0xFFFF,
394 "engineCycleEventCount", 0);
395
396 31501 uint32_t left = 0;
397 31501 uint32_t right = engineCycleEventCount - 1;
398
399 /**
400 * Let's find the last trigger angle which is less or equal to the desired angle
401 * todo: extract binary search as template method?
402 */
403 do {
404 192641 uint32_t middle = (left + right) / 2;
405
406
2/2
✓ Branch 0 taken 105519 times.
✓ Branch 1 taken 87122 times.
2/2
✓ Decision 'true' taken 105519 times.
✓ Decision 'false' taken 87122 times.
192641 if (details->eventAngles[middle] <= targetAngle) {
407 105519 left = middle + 1;
408 } else {
409 87122 right = middle - 1;
410 }
411
2/2
✓ Branch 0 taken 161140 times.
✓ Branch 1 taken 31501 times.
2/2
✓ Decision 'true' taken 161140 times.
✓ Decision 'false' taken 31501 times.
192641 } while (left <= right);
412 31501 left -= 1;
413
2/2
✓ Branch 0 taken 26406 times.
✓ Branch 1 taken 5095 times.
2/2
✓ Decision 'true' taken 26406 times.
✓ Decision 'false' taken 5095 times.
31501 if (useOnlyRisingEdges) {
414 26406 left &= ~1U;
415 }
416 31501 return left;
417 }
418
419 216 void TriggerWaveform::setShapeDefinitionError(bool value) {
420 216 shapeDefinitionError = value;
421 216 }
422
423 3345 void TriggerWaveform::setTriggerSynchronizationGap(float syncRatio) {
424 3345 setTriggerSynchronizationGap4(/*gapIndex*/0, syncRatio);
425 3345 }
426
427 140 void TriggerWaveform::setSecondTriggerSynchronizationGap(float syncRatio) {
428 140 setTriggerSynchronizationGap4(/*gapIndex*/1, syncRatio);
429 140 }
430
431 49 void TriggerWaveform::setSecondTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo) {
432 49 setTriggerSynchronizationGap3(/*gapIndex*/1, syncRatioFrom, syncRatioTo);
433 49 }
434
435 35 void TriggerWaveform::setThirdTriggerSynchronizationGap(float syncRatio) {
436 35 setTriggerSynchronizationGap4(/*gapIndex*/2, syncRatio);
437 35 }
438
439 2 PUBLIC_API_WEAK void customTrigger(operation_mode_e triggerOperationMode, TriggerWaveform *s, trigger_type_e type) {
440
3/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1/2
✓ Decision 'true' taken 2 times.
✗ Decision 'false' not taken.
2 if (type == trigger_type_e::TT_CUSTOM_1 || type == trigger_type_e::TT_CUSTOM_2) {
441 2 initializeSkippedToothTrigger(s, 1, 0, triggerOperationMode, SyncEdge::Rise);
442 2 return;
443 }
444 s->setShapeDefinitionError(true);
445 warning(ObdCode::CUSTOM_ERR_NO_SHAPE, "initializeTriggerWaveform() not implemented: %d", type);
446 }
447
448 /**
449 * External logger is needed because at this point our logger is not yet initialized
450 */
451 991 void TriggerWaveform::initializeTriggerWaveform(operation_mode_e triggerOperationMode, const trigger_config_s &triggerType, bool isCrankWheel) {
452
453 #if EFI_PROD_CODE
454 efiAssertVoid(ObdCode::CUSTOM_ERR_6641, hasLotsOfRemainingStack(), "init t");
455 efiPrintf("initializeTriggerWaveform(%s/%d)", getTrigger_type_e(triggerType.type), (int)triggerType.type);
456 #endif
457
458 991 shapeDefinitionError = false;
459
460
91/91
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 11 times.
✓ Branch 8 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 10 taken 9 times.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 1 time.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 1 time.
✓ Branch 15 taken 9 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 11 times.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 1 time.
✓ Branch 20 taken 1 time.
✓ Branch 21 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 23 taken 4 times.
✓ Branch 24 taken 1 time.
✓ Branch 25 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 28 taken 1 time.
✓ Branch 29 taken 1 time.
✓ Branch 30 taken 3 times.
✓ Branch 31 taken 520 times.
✓ Branch 32 taken 1 time.
✓ Branch 33 taken 1 time.
✓ Branch 34 taken 107 times.
✓ Branch 35 taken 1 time.
✓ Branch 36 taken 1 time.
✓ Branch 37 taken 1 time.
✓ Branch 38 taken 1 time.
✓ Branch 39 taken 14 times.
✓ Branch 40 taken 2 times.
✓ Branch 41 taken 5 times.
✓ Branch 42 taken 21 times.
✓ Branch 43 taken 30 times.
✓ Branch 44 taken 2 times.
✓ Branch 45 taken 5 times.
✓ Branch 46 taken 1 time.
✓ Branch 47 taken 16 times.
✓ Branch 48 taken 1 time.
✓ Branch 49 taken 2 times.
✓ Branch 50 taken 6 times.
✓ Branch 51 taken 1 time.
✓ Branch 52 taken 1 time.
✓ Branch 53 taken 1 time.
✓ Branch 54 taken 1 time.
✓ Branch 55 taken 1 time.
✓ Branch 56 taken 3 times.
✓ Branch 57 taken 8 times.
✓ Branch 58 taken 1 time.
✓ Branch 59 taken 1 time.
✓ Branch 60 taken 1 time.
✓ Branch 61 taken 5 times.
✓ Branch 62 taken 2 times.
✓ Branch 63 taken 1 time.
✓ Branch 64 taken 1 time.
✓ Branch 65 taken 3 times.
✓ Branch 66 taken 2 times.
✓ Branch 67 taken 1 time.
✓ Branch 68 taken 1 time.
✓ Branch 69 taken 5 times.
✓ Branch 70 taken 1 time.
✓ Branch 71 taken 1 time.
✓ Branch 72 taken 11 times.
✓ Branch 73 taken 1 time.
✓ Branch 74 taken 3 times.
✓ Branch 75 taken 3 times.
✓ Branch 76 taken 3 times.
✓ Branch 77 taken 7 times.
✓ Branch 78 taken 5 times.
✓ Branch 79 taken 1 time.
✓ Branch 80 taken 1 time.
✓ Branch 81 taken 1 time.
✓ Branch 82 taken 3 times.
✓ Branch 83 taken 1 time.
✓ Branch 84 taken 7 times.
✓ Branch 85 taken 1 time.
✓ Branch 86 taken 1 time.
✓ Branch 87 taken 1 time.
✓ Branch 88 taken 1 time.
✓ Branch 89 taken 5 times.
✓ Branch 90 taken 2 times.
991 switch (triggerType.type) {
461
1/1
✓ Decision 'true' taken 59 times.
59 case trigger_type_e::TT_TOOTHED_WHEEL:
462 59 initializeSkippedToothTrigger(this, triggerType.customTotalToothCount,
463 59 triggerType.customSkippedToothCount, triggerOperationMode, SyncEdge::RiseOnly);
464 59 break;
465
466
1/1
✓ Decision 'true' taken 10 times.
10 case trigger_type_e::TT_MAZDA_MIATA_NA:
467 10 initializeMazdaMiataNaShape(this);
468 10 break;
469
470
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_MAZDA_MIATA_VVT_TEST:
471 1 initializeMazdaMiataVVtTestShape(this);
472 1 break;
473
474
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SUZUKI_K6A:
475 1 initializeSuzukiK6A(this);
476 1 break;
477
478
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SUZUKI_G13B:
479 1 initializeSuzukiG13B(this);
480 1 break;
481
482
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_FORD_TFI_PIP:
483 1 configureFordPip(this);
484 1 break;
485
486
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_FORD_ST170:
487 1 configureFordST170(this);
488 1 break;
489
490
1/1
✓ Decision 'true' taken 11 times.
11 case trigger_type_e::TT_VVT_MIATA_NB:
491 11 initializeMazdaMiataVVtCamShape(this);
492 11 break;
493
494
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_RENIX_66_2_2_2:
495 1 initializeRenix66_2_2(this);
496 1 break;
497
498
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_RENIX_44_2_2:
499 1 initializeRenix44_2_2(this);
500 1 break;
501
502
1/1
✓ Decision 'true' taken 9 times.
9 case trigger_type_e::TT_MIATA_VVT:
503 9 initializeMazdaMiataNb2Crank(this);
504 9 break;
505
506
1/1
✓ Decision 'true' taken 6 times.
6 case trigger_type_e::TT_DODGE_NEON_1995:
507 case trigger_type_e::TT_DODGE_NEON_1995_ONLY_CRANK:
508
1/1
✓ Decision 'true' taken 6 times.
6 configureNeon1995TriggerWaveformOnlyCrank(this);
509 6 break;
510
511
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_DODGE_STRATUS:
512 1 configureDodgeStratusTriggerWaveform(this);
513 1 break;
514
515
1/1
✓ Decision 'true' taken 4 times.
4 case trigger_type_e::TT_DODGE_NEON_2003_CAM:
516 4 configureNeon2003TriggerWaveformCam(this);
517 4 break;
518
519
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_DODGE_NEON_2003_CRANK:
520 1 configureNeon2003TriggerWaveformCam(this);
521 // configureNeon2003TriggerWaveformCrank(triggerShape);
522 1 break;
523
524
1/1
✓ Decision 'true' taken 9 times.
9 case trigger_type_e::TT_FORD_ASPIRE:
525 9 configureFordAspireTriggerWaveform(this);
526 9 break;
527
528
1/1
✓ Decision 'true' taken 4 times.
4 case trigger_type_e::TT_VVT_NISSAN_VQ35:
529 4 initializeNissanVQvvt(this);
530 4 break;
531
532
1/1
✓ Decision 'true' taken 11 times.
11 case trigger_type_e::TT_VVT_MITSU_6G72:
533 11 initializeVvt6G72(this);
534 11 break;
535
536
1/1
✓ Decision 'true' taken 4 times.
4 case trigger_type_e::TT_VVT_MITSUBISHI_3A92:
537 4 initializeVvt3A92(this);
538 4 break;
539
540
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_TOYOTA_3_TOOTH_UZ:
541 1 initializeUzCam(this);
542 1 break;
543
544
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_VVT_TOYOTA_4_1:
545 1 initializeSkippedToothTrigger(this, 4, 1, triggerOperationMode, SyncEdge::RiseOnly);
546 1 setTriggerSynchronizationGap3(/*gapIndex*/0, /*from*/1.60, 2.40);
547 1 setTriggerSynchronizationGap3(/*gapIndex*/1, /*from*/0.75, 1.25);
548 1 break;
549
550
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_NISSAN_QR25:
551 1 initializeNissanQR25crank(this);
552 1 break;
553
554
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_NISSAN_VQ30:
555 1 initializeNissanVQ30cam(this);
556 1 break;
557
558
1/1
✓ Decision 'true' taken 4 times.
4 case trigger_type_e::TT_NISSAN_VQ35:
559 4 initializeNissanVQ35crank(this);
560 4 break;
561
562
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_NISSAN_MR18_CRANK:
563 1 initializeNissanMR18crank(this);
564 1 break;
565
566
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_NISSAN_MR18_CAM_VVT:
567 1 initializeNissanMRvvt(this);
568 1 break;
569
570
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_KAWA_KX450F:
571 1 configureKawaKX450F(this);
572 1 break;
573
574
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SKODA_FAVORIT:
575 1 setSkodaFavorit(this);
576 1 break;
577
578
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_GM_60_2_2_2:
579 1 configureGm60_2_2_2(this);
580 1 break;
581
582
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_GM_7X:
583 1 configureGmTriggerWaveform(this);
584 1 break;
585
586
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_MAZDA_DOHC_1_4:
587 3 configureMazdaProtegeLx(this);
588 3 break;
589
590
1/1
✓ Decision 'true' taken 520 times.
520 case trigger_type_e::TT_ONE_PLUS_ONE:
591 520 configureOnePlusOne(this);
592 520 break;
593
594
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_3_1_CAM:
595 1 configure3_1_cam(this);
596 1 break;
597
598
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_MERCEDES_2_SEGMENT:
599 1 setMercedesTwoSegment(this);
600 1 break;
601
602
1/1
✓ Decision 'true' taken 107 times.
107 case trigger_type_e::TT_HALF_MOON:
603 /** @note TT_HALF_MOON setup events as 180 and 360 degrees. It uses SyncEdge::Rise
604 * for additional phase align on falling edge and will not work with non-
605 * symmetrical blind type where open and closed sections are not equal */
606 107 initializeSkippedToothTrigger(this, 1, 0, triggerOperationMode, SyncEdge::Rise);
607 107 break;
608
609
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_NARROW_SINGLE_TOOTH:
610 /** different from TT_HALF_MOON */
611 1 initializeSkippedToothTrigger(this, 1, 0, triggerOperationMode, SyncEdge::RiseOnly);
612 1 break;
613
614
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_MAZDA_SOHC_4:
615 1 configureMazdaProtegeSOHC(this);
616 1 break;
617
618
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_DAIHATSU_3_CYL:
619 1 configureDaihatsu3cyl(this);
620 1 break;
621
622
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_DAIHATSU_4_CYL:
623 1 configureDaihatsu4cyl(this);
624 1 break;
625
626
1/1
✓ Decision 'true' taken 14 times.
14 case trigger_type_e::TT_VVT_TOYOTA_3_TOOTH:
627 14 initializeSkippedToothTrigger(this, 3, 0, triggerOperationMode, SyncEdge::RiseOnly);
628 14 break;
629
630
1/1
✓ Decision 'true' taken 2 times.
2 case trigger_type_e::TT_36_2_1_1:
631 2 initialize36_2_1_1(this);
632 2 break;
633
634
1/1
✓ Decision 'true' taken 5 times.
5 case trigger_type_e::TT_36_2_1:
635 5 initialize36_2_1(this);
636 5 break;
637
638
1/1
✓ Decision 'true' taken 21 times.
21 case trigger_type_e::TT_TOOTHED_WHEEL_32_2:
639 21 initializeSkippedToothTrigger(this, 32, 2, triggerOperationMode, SyncEdge::RiseOnly);
640 // todo: why is this 32/2 asking for third gap while 60/2 is happy with just two gaps?
641 // method above sets second gap, here we add third
642 // this third gap is not required to sync on perfect signal but is needed to handle to reject cranking transition noise
643 21 setThirdTriggerSynchronizationGap(1);
644 21 break;
645
646
1/1
✓ Decision 'true' taken 30 times.
30 case trigger_type_e::TT_TOOTHED_WHEEL_60_2:
647 30 initializeSkippedToothTrigger(this, 60, 2, triggerOperationMode, SyncEdge::RiseOnly);
648 30 break;
649
650
1/1
✓ Decision 'true' taken 2 times.
2 case trigger_type_e::TT_TOOTHED_WHEEL_36_2:
651 2 initializeSkippedToothTrigger(this, 36, 2, triggerOperationMode, SyncEdge::RiseOnly);
652 2 setTriggerSynchronizationGap3(/*gapIndex*/0, /*from*/1.6, 3.5);
653 2 setTriggerSynchronizationGap3(/*gapIndex*/1, /*from*/0.7, 1.3); // second gap is not required to synch on perfect signal but is needed to handle to reject cranking transition noise
654 2 break;
655
656
1/1
✓ Decision 'true' taken 5 times.
5 case trigger_type_e::TT_60_2_WRONG_POLARITY:
657 5 setVwConfiguration(this);
658 5 break;
659
660
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_TOOTHED_WHEEL_36_1:
661 1 initializeSkippedToothTrigger(this, 36, 1, triggerOperationMode, SyncEdge::RiseOnly);
662 1 break;
663
664
1/1
✓ Decision 'true' taken 16 times.
16 case trigger_type_e::TT_VVT_BOSCH_QUICK_START:
665 16 configureQuickStartSenderWheel(this);
666 16 break;
667
668
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_VVT_BARRA_3_PLUS_1:
669 1 configureBarra3plus1cam(this);
670 1 break;
671
672
1/1
✓ Decision 'true' taken 2 times.
2 case trigger_type_e::TT_HONDA_K_CAM_4_1:
673 2 configureHondaK_4_1(this);
674 2 break;
675
676
1/1
✓ Decision 'true' taken 6 times.
6 case trigger_type_e::TT_HONDA_K_CRANK_12_1:
677 6 configureHondaK_12_1(this);
678 6 break;
679
680
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_HONDA_J30A2_24_1_1:
681 1 configureHondaJ30A2_24_1_1(this);
682 1 break;
683
684
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SUBARU_EZ30:
685 1 initializeSubaruEZ30(this);
686 1 break;
687
688
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_VVT_MAZDA_SKYACTIV:
689 1 initializeMazdaSkyactivCam(this);
690 1 break;
691
692
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_VVT_MAZDA_L:
693 1 initializeMazdaLCam(this);
694 1 break;
695
696
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_BENELLI_TRE:
697 1 configureBenelli(this);
698 1 break;
699
700
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_MITSU_4G63_CRANK:
701 3 initializeMitsubishi4gSymmetricalCrank(this);
702 3 break;
703
1/1
✓ Decision 'true' taken 8 times.
8 case trigger_type_e::TT_DEV:
704 case trigger_type_e::TT_VVT_FORD_COYOTE:
705
1/1
✓ Decision 'true' taken 8 times.
8 configureFordCoyote(this);
706 8 break;
707
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_60DEG_TOOTH:
708 /** @note
709 * Have a something like TT_ONE_PHASED trigger with
710 * externally setuped blind width will be a good
711 * approach to utilize ::Rise(and::Both in future)
712 * with both edges phase-sync, but to stay simple I suggest
713 * just to use another enum for each trigger type. */
714 1 configure60degSingleTooth(this);
715 1 break;
716
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_60_2_2_F3R:
717 1 initialize60_2_2_Renault_F(this);
718 1 break;
719
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_VVT_MITSUBISHI_4G69:
720 1 initializeMitsubishi4G69Cam(this);
721 1 break;
722
1/1
✓ Decision 'true' taken 5 times.
5 case trigger_type_e::TT_MITSU_4G63_CAM:
723 5 initializeMitsubishi4g63Cam(this);
724 5 break;
725
726
1/1
✓ Decision 'true' taken 2 times.
2 case trigger_type_e::TT_UNUSED29:
727 case trigger_type_e::TT_HONDA_CBR_600:
728
1/1
✓ Decision 'true' taken 2 times.
2 configureHondaCbr600(this);
729 2 break;
730
731
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_CHRYSLER_PHASER:
732 1 configureChryslerVtt15(this);
733 1 break;
734
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_CHRYSLER_NGC_36_2_2:
735 1 configureChryslerNGC_36_2_2(this);
736 1 break;
737
738
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_JEEP_EVD_36_2_2:
739 3 configureJeepEVD_36_2_2(this);
740 3 break;
741
742
1/1
✓ Decision 'true' taken 2 times.
2 case trigger_type_e::TT_DODGE_RAM:
743 2 initDodgeRam(this);
744 2 break;
745
746
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_JEEP_4_CYL:
747 1 initJeep_XJ_4cyl_2500(this);
748 1 break;
749
750
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_JEEP_18_2_2_2:
751 1 initJeep18_2_2_2(this);
752 1 break;
753
754
1/1
✓ Decision 'true' taken 5 times.
5 case trigger_type_e::TT_SUBARU_7_6:
755 5 initializeSubaru7_6(this);
756 5 break;
757
758
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_36_2_2_2:
759 1 initialize36_2_2_2(this);
760 1 break;
761
762
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_2JZ_3_34_SIMULATION_ONLY:
763 1 initialize2jzGE3_34_simulation_shape(this);
764 1 break;
765
766
1/1
✓ Decision 'true' taken 11 times.
11 case trigger_type_e::TT_3_TOOTH_CRANK:
767 11 configure3ToothCrank(this);
768 11 break;
769
770
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_6_TOOTH_CRANK:
771 1 configure6ToothCrank(this);
772 1 break;
773
774
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_12_TOOTH_CRANK:
775 3 configure12ToothCrank(this);
776 3 break;
777
778
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_ARCTIC_CAT:
779 3 configureArcticCat(this);
780 3 break;
781
782
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_NISSAN_HR_CAM_IN:
783 3 initializeNissanHRvvtIn(this);
784 3 break;
785
1/1
✓ Decision 'true' taken 7 times.
7 case trigger_type_e::TT_NISSAN_HR:
786 7 initializeNissanHRcrank(this);
787 7 break;
788
1/1
✓ Decision 'true' taken 5 times.
5 case trigger_type_e::TT_NISSAN_SR20VE:
789 5 initializeNissanSR20VE_4(this);
790 5 break;
791
792
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_ROVER_K:
793 1 initializeRoverK(this);
794 1 break;
795
796
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_FIAT_IAW_P8:
797 1 configureFiatIAQ_P8(this);
798 1 break;
799
800
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_TRI_TACH:
801 1 configureTriTach(this);
802 1 break;
803
804
1/1
✓ Decision 'true' taken 3 times.
3 case trigger_type_e::TT_GM_24x_5:
805 3 initGmLS24_5deg(this);
806 3 break;
807
808
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_GM_24x_3:
809 1 initGmLS24_3deg(this);
810 1 break;
811
812
1/1
✓ Decision 'true' taken 7 times.
7 case trigger_type_e::TT_VVT_SUBARU_7_WITHOUT_6:
813 7 initializeSubaruOnly7(this);
814 7 break;
815
816
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SUBARU_SVX:
817 1 initializeSubaru_SVX(this);
818 1 break;
819
820
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SUBARU_SVX_CRANK_1:
821 1 initializeSubaru_SVX(this);
822 1 break;
823
824
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_SUBARU_SVX_CAM_VVT:
825 1 initializeSubaru_SVX(this);
826 1 break;
827
828
1/1
✓ Decision 'true' taken 1 time.
1 case trigger_type_e::TT_JEEPRENIX_66_2_2_2:
829 1 initializeJeepRenix66_2_2(this);
830 1 break;
831
832
1/1
✓ Decision 'true' taken 5 times.
5 case trigger_type_e::TT_SUBARU_7_6_CRANK:
833 5 initializeSubaru7_6_crankOnly(this);
834 5 break;
835
836
837
1/1
✓ Decision 'true' taken 2 times.
2 default:
838 2 customTrigger(triggerOperationMode, this, triggerType.type);
839 }
840
841
4/4
✓ Branch 0 taken 911 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 352 times.
✓ Branch 3 taken 559 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 991 times.
991 if (isCrankWheel && !needSecondTriggerInput &&
842 #if EFI_UNIT_TEST
843
2/2
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 6 times.
352 engineConfiguration != nullptr &&
844 #endif
845
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
346 engineConfiguration->triggerInputPins[1] != Gpio::Unassigned) {
846 // todo: technical debt: HW CI should not require special treatment
847 #ifndef HARDWARE_CI
848 criticalError("Single-channel trigger %s selected while two inputs were configured", getTrigger_type_e(triggerType.type));
849 #endif
850 }
851
852 /**
853 * Feb 2019 suggestion: it would be an improvement to remove 'expectedEventCount' logic from 'addEvent'
854 * and move it here, after all events were added.
855 */
856 991 calculateExpectedEventCounts();
857 991 version++;
858
859
1/2
✓ Branch 0 taken 991 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 991 times.
✗ Decision 'false' not taken.
991 if (!shapeDefinitionError) {
860 991 wave.checkSwitchTimes(getCycleDuration());
861 }
862 991 }
863