GCC Code Coverage Report


Directory: ./
File: firmware/controllers/trigger/decoders/trigger_nissan.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 144 0 144
Functions: 100.0% 12 0 12
Branches: 100.0% 10 0 10
Decisions: 100.0% 10 - 10

Line Branch Decision Exec Source
1 /**
2 * @file trigger_nissan.cpp
3 *
4 * https://rusefi.com/forum/viewtopic.php?f=3&t=1194&start=150#p27784
5 *
6 * @date Sep 19, 2015
7 * @author Andrey Belomutskiy, (c) 2012-2020
8 */
9
10 #include "pch.h"
11
12 #include "trigger_nissan.h"
13 #include "trigger_universal.h"
14 #include "trigger_subaru.h"
15
16 /**
17 * 8,2,2,2 Nissan pattern
18 */
19 5 void initializeNissanSR20VE_4(TriggerWaveform *s) {
20 5 s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::Both);
21
22 5 s->tdcPosition = 630;
23
24 5 s->setTriggerSynchronizationGap2(9.67 * 0.75, 16);
25
26 5 float width = 4;
27
28 5 s->addEvent720(1 * 180 - 4 * width, TriggerValue::RISE);
29 5 s->addEvent720(1 * 180, TriggerValue::FALL);
30
31 5 s->addEvent720(2 * 180 - width, TriggerValue::RISE);
32 5 s->addEvent720(2 * 180, TriggerValue::FALL);
33
34 5 s->addEvent720(3 * 180 - width, TriggerValue::RISE);
35 5 s->addEvent720(3 * 180, TriggerValue::FALL);
36
37 5 s->addEvent720(4 * 180 - width, TriggerValue::RISE);
38 5 s->addEvent720(4 * 180, TriggerValue::FALL);
39 5 }
40
41 6 void initializeNissanVQvvt(TriggerWaveform *s) {
42 6 s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::RiseOnly);
43
44 6 int offset = 360 - 260;
45
46 6 s->addToothRiseFall(offset + 20);
47 6 s->addToothRiseFall(offset + 80);
48 6 s->addToothRiseFall(offset + 100);
49 6 s->addToothRiseFall(offset + 140);
50 6 s->addToothRiseFall(offset + 160);
51 6 s->addToothRiseFall(offset + 260);
52
53 6 s->setTriggerSynchronizationGap2(4, 6);
54 6 s->setSecondTriggerSynchronizationGap2(0.35f, 0.7f);
55 6 }
56
57 6 void makeNissanPattern(TriggerWaveform* s, size_t halfCylinderCount, size_t totalWheel, size_t missing) {
58
59 6 auto toothAngle = 360.0f / totalWheel;
60
61 6 auto patternTeeth = totalWheel / halfCylinderCount;
62 6 auto toothCount = patternTeeth - missing;
63
64 6 float currentAngle = missing * toothAngle;
65
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 6 times.
2/2
✓ Decision 'true' taken 66 times.
✓ Decision 'false' taken 6 times.
72 for (size_t i = 0; i < toothCount; i++) {
66 66 currentAngle += toothAngle;
67 66 s->addEventAngle(currentAngle - 5, TriggerValue::RISE);
68 66 s->addEventAngle(currentAngle, TriggerValue::FALL);
69 }
70 6 }
71
72 5 void initializeNissanVQ35crank(TriggerWaveform *s) {
73 5 s->initialize(FOUR_STROKE_THREE_TIMES_CRANK_SENSOR, SyncEdge::RiseOnly);
74
75 5 s->tdcPosition = 675;
76
77 // 6 cylinder = 36 tooth wheel, missing 2 teeth in 3 spots
78 5 makeNissanPattern(s, 3, 36, 2);
79 5 s->setTriggerSynchronizationGap3(/*gapIndex*/0, 0.2, 0.5);
80 5 s->setTriggerSynchronizationGap3(/*gapIndex*/1, 2, 4);
81 5 s->setTriggerSynchronizationGap3(/*gapIndex*/2, 0.6, 1.4);
82 5 }
83
84 1 void initializeNissanMR18crank(TriggerWaveform *s) {
85 1 s->initialize(FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR, SyncEdge::RiseOnly);
86
87 1 s->tdcPosition = 80;
88
89 // 4 cylinder = 36 tooth wheel, missing 2 teeth in 2 spots
90 1 makeNissanPattern(s, 2, 36, 2);
91 1 s->setTriggerSynchronizationGap(0.33);
92 1 }
93
94 1 void initializeNissanQR25crank(TriggerWaveform *s) {
95 1 s->initialize(FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR, SyncEdge::RiseOnly);
96 1 s->setTriggerSynchronizationGap(0.33);
97 1 s->setSecondTriggerSynchronizationGap(3);
98
99 1 s->tdcPosition = 585;
100
101 1 float currentAngle = 20;
102
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 time.
2/2
✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 1 time.
17 for (int i = 0;i < 16;i++) {
103 16 currentAngle += 10;
104 16 s->addEventAngle(currentAngle - 5, TriggerValue::RISE);
105 16 s->addEventAngle(currentAngle, TriggerValue::FALL);
106 }
107 1 }
108
109 31 static void addvq30tooth(TriggerWaveform *s, float angle) {
110 31 s->addEvent360(angle - 4, TriggerValue::RISE);
111 31 s->addEvent360(angle, TriggerValue::FALL);
112 31 }
113
114 // yes, this is CAM shaft shape NOT crank shaft shape!
115 // we will add crank shape once Pavel makes progress
116 1 void initializeNissanVQ30cam(TriggerWaveform *s) {
117 1 s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::RiseOnly);
118
119 1 s->tdcPosition = 120;
120
121 1 int x = 360 + 52;
122
123 1 addvq30tooth(s, x - (360 - 9 * 0));
124 1 addvq30tooth(s, x - (360 - 9 * 1));
125 1 addvq30tooth(s, x - (360 - 9 * 2));
126
127 1 addvq30tooth(s, x - (252 + 9 * 5));
128 1 addvq30tooth(s, x - (252 + 9 * 4));
129 1 addvq30tooth(s, x - (252 + 9 * 3));
130 1 addvq30tooth(s, x - (252 + 9 * 2));
131 1 addvq30tooth(s, x - (252 + 9 * 1));
132 1 addvq30tooth(s, x - (252 + 9 * 0));
133
134 1 addvq30tooth(s, x - (236 ));
135
136 1 addvq30tooth(s, x - (152 + 9 * 3));
137 1 addvq30tooth(s, x - (152 + 9 * 2));
138 1 addvq30tooth(s, x - (152 + 9 * 1));
139 1 addvq30tooth(s, x - (152 + 9 * 0));
140
141 1 addvq30tooth(s, x - (85 + 9 * 4));
142 1 addvq30tooth(s, x - (85 + 9 * 3));
143 1 addvq30tooth(s, x - (85 + 9 * 2));
144 1 addvq30tooth(s, x - (85 + 9 * 1));
145 1 addvq30tooth(s, x - (85 + 9 * 0));
146
147 1 addvq30tooth(s, x - (52 + 9 * 1));
148 1 addvq30tooth(s, x - (52 + 9 * 0));
149
150 1 s->setTriggerSynchronizationGap4(/*gapIndex*/0, 5.78);
151 1 s->setTriggerSynchronizationGap4(/*gapIndex*/1, 0.38);
152 1 s->setTriggerSynchronizationGap4(/*gapIndex*/2, 2.67);
153 1 }
154
155 1 void initializeNissanMRvvt(TriggerWaveform *s) {
156 1 s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::RiseOnly);
157 1 s->tdcPosition = 0;
158
159 1 int x = 73;
160
161 // All "groups" start every 90 degrees of cam rotation
162 // The groups have 1, 3, 4, 2 teeth each (which is the firing order?)
163
164 // Teeth within a group are spaced 17 cam degrees apart
165 1 int toothSpacing = 17;
166
167 // "1"
168 1 addvq30tooth(s, x + 0); // <-- sync point here
169
170 // "3"
171 1 addvq30tooth(s, x + 90 + 0 * toothSpacing);
172 1 addvq30tooth(s, x + 90 + 1 * toothSpacing);
173 1 addvq30tooth(s, x + 90 + 2 * toothSpacing);
174
175 // "4"
176 1 addvq30tooth(s, x + 180 + 0 * toothSpacing);
177 1 addvq30tooth(s, x + 180 + 1 * toothSpacing);
178 1 addvq30tooth(s, x + 180 + 2 * toothSpacing);
179 1 addvq30tooth(s, x + 180 + 3 * toothSpacing);
180
181 // "2"
182 1 addvq30tooth(s, x + 270 + 0 * toothSpacing);
183 1 addvq30tooth(s, x + 270 + 1 * toothSpacing);
184
185 // nominal gap 4.31
186 1 s->setTriggerSynchronizationGap2(3.8, 5);
187
188 // nominal gap 0.44
189 1 s->setSecondTriggerSynchronizationGap2(0.3, 0.55);
190 1 }
191
192 7 void initialize_one_of_36_2_2(TriggerWaveform *s, int firstCount, int secondCount) {
193 7 s->initialize(FOUR_STROKE_CRANK_SENSOR, SyncEdge::RiseOnly);
194
195 7 float narrow = 360 / 36;
196 7 float wide = narrow * 3;
197
198 7 float base = 0;
199
200
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 7 times.
2/2
✓ Decision 'true' taken 63 times.
✓ Decision 'false' taken 7 times.
70 for (int i = 0; i < firstCount; i++) {
201 63 s->addToothFallRise(base + narrow, narrow / 2);
202 63 base += narrow;
203 }
204
205 7 s->addToothFallRise(base + wide, wide / 2);
206 7 base += wide;
207
208
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 7 times.
2/2
✓ Decision 'true' taken 147 times.
✓ Decision 'false' taken 7 times.
154 for (int i = 0; i < secondCount; i++) {
209 147 s->addToothFallRise(base + narrow, narrow / 2);
210 147 base += narrow;
211 }
212
213 7 s->addToothFallRise(360, narrow/2);
214 7 }
215
216 7 void initializeNissanHRcrank(TriggerWaveform *s) {
217 7 initialize_one_of_36_2_2(s, 9, 21);
218
219 7 size_t count = 9;
220
221 7 s->tdcPosition = 155 + 360;
222
223 7 s->setTriggerSynchronizationGap3(/*gapIndex*/0, 1.7, 5);
224
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 7 times.
2/2
✓ Decision 'true' taken 56 times.
✓ Decision 'false' taken 7 times.
63 for (size_t i = 1 ; i < count ; i++) {
225 56 s->setTriggerSynchronizationGap3(/*gapIndex*/i, 0.6, 1.5);
226 }
227 7 s->setTriggerSynchronizationGap3(/*gapIndex*/count, 0.1, 0.5);
228 7 }
229
230
231 3 void initializeNissanHRvvtIn(TriggerWaveform *s) {
232 3 s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::RiseOnly);
233
234
235 3 s->addToothRiseFall(120);
236 3 s->addToothRiseFall(120 + 22);
237 3 s->addToothRiseFall(240);
238 3 s->addToothRiseFall(360);
239
240 3 s->setTriggerSynchronizationGap3(/*gapIndex*/0, 0.1, 0.3);
241 3 }
242
243