rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
trigger_subaru.cpp
Go to the documentation of this file.
1/**
2 * @file trigger_subaru.cpp
3 *
4 * @date Sep 10, 2015
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 */
7
8#include "pch.h"
9
10#include "trigger_subaru.h"
11
12void initialize_one_of_36_2_2_2(TriggerWaveform *s, int firstCount, int secondCount) {
14
15 float narrow = 360 / 36;
16 float wide = narrow * 3;
17
18 float base = 0;
19
20 for (int i = 0; i < firstCount; i++) {
21 s->addToothFallRise(base + narrow, narrow / 2);
22 base += narrow;
23 }
24
25 s->addToothFallRise(base + wide, wide / 2);
26 base += wide;
27
28 for (int i = 0; i < secondCount; i++) {
29 s->addToothFallRise(base + narrow, narrow / 2);
30 base += narrow;
31 }
32
33 // depending on firstCount + secondCount we might have a gap here
34
35 s->addToothFallRise(360 - wide, narrow / 2);
36 s->addToothFallRise(360, narrow / 2);
37}
38
39/**
40 * This trigger is also used by Nissan and Mazda
41 * https://rusefi.com/forum/viewtopic.php?f=2&t=1932
42 */
45
46#if EFI_UNIT_TEST
47 // usually used on crank but placed on 'cam' on '2-stroke' rotary
48 // this 'knownOperationMode' does not matter for trigger decoding only matters for .ini code generation and trigger images
49 s->knownOperationMode = false;
50#endif // EFI_UNIT_TEST
51
52 // 36/2/2/2 data from https://rusefi.com/online/view.php?log=1287
53 // todo: probably should be unified with EZ30 below?
54 s->setTriggerSynchronizationGap3(/*gapIndex*/0, 0.25, 0.5);
55 s->setTriggerSynchronizationGap3(/*gapIndex*/1, 0.7, 1.7);
56 s->setTriggerSynchronizationGap3(/*gapIndex*/2, 2.25, 4.2);
57}
58
61
62 s->tdcPosition = 240;
63
64 s->setTriggerSynchronizationGap3(/*gapIndex*/0, 0.25, 0.5);
65 s->setTriggerSynchronizationGap3(/*gapIndex*/1, 0.7, 1.5);
66 s->setTriggerSynchronizationGap3(/*gapIndex*/2, 2, 4);
67}
68
69static void initializeSubaru7_6(TriggerWaveform *s, bool withCrankWheel) {
71
72 /* To make trigger decoder happy last event should be exactly at 720
73 * This code generates two trigger patterns: crank+cam (7+6) and
74 * cam only (7-6).
75 * So last event should be CAM event
76 * Crank: --------||-|---||-|-----||-|---||-|
77 * Cam: -|-|-|------|------!-|------|------
78 * '!' pulse is selected as event at 720
79 * So next event is the first one on following description
80 * '!' pulse happens 20 degrees ATDC #2 (third in order)
81 * or 180 + 180 + 20. So we have */
82 s->tdcPosition = 160 + 360;
83
84 float width = 5;
85
86 /* 97 degrees BTDC, but we have 20 degrees shift:
87 * 180 - 97 - 20 = 63 */
88 #define SUBARU76_CRANK_PULSE0(cycle) \
89 s->addEvent720((180 * (cycle)) + 63 - width, TriggerValue::RISE, TriggerWheel::T_SECONDARY); \
90 s->addEvent720((180 * (cycle)) + 63, TriggerValue::FALL, TriggerWheel::T_SECONDARY)
91 /* 65 degrees BTDC, but we have 20 degrees shift:
92 * 180 - 65 - 20 = 95 */
93 #define SUBARU76_CRANK_PULSE1(cycle) \
94 s->addEvent720((180 * (cycle)) + 95 - width, TriggerValue::RISE, TriggerWheel::T_SECONDARY); \
95 s->addEvent720((180 * (cycle)) + 95, TriggerValue::FALL, TriggerWheel::T_SECONDARY)
96 /* 10 degrees BTDC, but we have 20 degrees shift:
97 * 180 - 10 - 20 = 150 */
98 #define SUBARU76_CRANK_PULSE2(cycle) \
99 s->addEvent720((180 * (cycle)) + 150 - width, TriggerValue::RISE, TriggerWheel::T_SECONDARY); \
100 s->addEvent720((180 * (cycle)) + 150, TriggerValue::FALL, TriggerWheel::T_SECONDARY)
101
102 #define SUBARU76_CAM_PULSE(cycle, offset) \
103 s->addEvent720((180 * (cycle)) + (offset) - width, TriggerValue::RISE, TriggerWheel::T_PRIMARY); \
104 s->addEvent720((180 * (cycle)) + (offset), TriggerValue::FALL, TriggerWheel::T_PRIMARY)
105
106 /* (TDC#2 + 20) + 15 */
107 SUBARU76_CAM_PULSE(0, +15);
108
109 if (withCrankWheel) {
110 SUBARU76_CRANK_PULSE0(0);
111 SUBARU76_CRANK_PULSE1(0);
112 SUBARU76_CRANK_PULSE2(0);
113 }
114
115 /* (TDC#4 + 20) */
116 SUBARU76_CAM_PULSE(1, 0);
117
118 if (withCrankWheel) {
119 SUBARU76_CRANK_PULSE0(1);
120 SUBARU76_CRANK_PULSE1(1);
121 SUBARU76_CRANK_PULSE2(1);
122 }
123
124 /* (TDC#1 + 20) - 15 */
125 SUBARU76_CAM_PULSE(2, -15);
126
127 /* (TDC#1 + 20) */
128 SUBARU76_CAM_PULSE(2, 0);
129
130 /* (TDC#1 + 20) + 15 */
131 SUBARU76_CAM_PULSE(2, +15);
132
133 if (withCrankWheel) {
134 SUBARU76_CRANK_PULSE0(2);
135 SUBARU76_CRANK_PULSE1(2);
136 SUBARU76_CRANK_PULSE2(2);
137 }
138
139 /* (TDC#3 + 20) */
140 SUBARU76_CAM_PULSE(3, 0);
141
142 if (withCrankWheel) {
143 SUBARU76_CRANK_PULSE0(3);
144 SUBARU76_CRANK_PULSE1(3);
145 SUBARU76_CRANK_PULSE2(3);
146 }
147
148 /* (TDC#2 + 20) */
149 SUBARU76_CAM_PULSE(4, 0);
150
151 // why is this trigger gap wider than average?
152 s->setTriggerSynchronizationGap3(/*index*/0, 6.53 * TRIGGER_GAP_DEVIATION_LOW, 15);
153 s->setTriggerSynchronizationGap3(/*index*/1, 0.3, 1 * TRIGGER_GAP_DEVIATION_HIGH);
154 s->setTriggerSynchronizationGap3(/*index*/2, 0.08, 0.3);
155
156 s->useOnlyPrimaryForSync = withCrankWheel;
157}
158
162
165
166 const float width = 1;
167 const float offset = 720 - (3 * 180 + 20);
168
169 s->tdcPosition = 180 + offset;
170
171 #define SUBARU76_CAMONLY_PULSE(cyl, subtooth) \
172 s->addEventAngle(offset + (180 * (cyl)) + 20 + (15 * (subtooth)) - width, TriggerValue::RISE, TriggerWheel::T_PRIMARY); \
173 s->addEventAngle(offset + (180 * (cyl)) + 20 + (15 * (subtooth)), TriggerValue::FALL, TriggerWheel::T_PRIMARY)
174
175 // CYL1
176 // 5, 20, 35
177 SUBARU76_CAMONLY_PULSE(0, -1);
178 SUBARU76_CAMONLY_PULSE(0, 0);
179 SUBARU76_CAMONLY_PULSE(0, +1);
180
181 // CYL3
182 // 200
183 SUBARU76_CAMONLY_PULSE(1, 0);
184
185 // CYL2
186 // 380, 395
187 SUBARU76_CAMONLY_PULSE(2, 0);
188 SUBARU76_CAMONLY_PULSE(2, +1);
189
190 // CYL4
191 // 560
192 SUBARU76_CAMONLY_PULSE(3, 0);
193
194 // Tooths positions, deltas and gap ratios
195 // (5, 20, 35, 200, 380, 395, 560) 725...
196 // (15, 15, 165, 180, 15, 165, 165) 15...
197 // K: 0.09, 1, 11,1.09,0.08, 11, 1)0.09
198
199 // Gaps: 1, 0.09, 1, 11 at 560
200 //s->setTriggerSynchronizationGap3(0, 0.50, 1.50);
201 //s->setTriggerSynchronizationGap3(0, 0.04, 0.15);
202 //s->setTriggerSynchronizationGap3(1, 0.50, 1.50);
203 //s->setTriggerSynchronizationGap3(2, 7.00, 15.00);
204
205 s->setTriggerSynchronizationGap3(/*index*/0, 6.53 * TRIGGER_GAP_DEVIATION_LOW, 15);
206 s->setTriggerSynchronizationGap3(/*index*/1, 0.3, 1 * TRIGGER_GAP_DEVIATION_HIGH);
207 s->setTriggerSynchronizationGap3(/*index*/2, 0.08, 0.3);
208}
209
211 //initializeSubaru7_6(s, false);
213}
214
216 /**
217 * Note how we use 0..180 range while defining FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR trigger
218 * Note that only half of the physical wheel is defined here!
219 */
221
222 const float width = 1;
223 const float offset = 10;
224
225 s->tdcPosition = 65;
226
227 // BTDC: 97, 65, 10
228 // Distances: 93, 32, 55
231
234
237
238 // Nominal gaps:
239 // 55 / 32 = 1.7187
240 //s->setTriggerSynchronizationGap2(0.85f, 3.43f);
241 // 93 / 55 = 1.6909
242 //s->setTriggerSynchronizationGap2(0.84f, 3.38);
243 // 32 / 93 = 0.344
244 s->setTriggerSynchronizationGap2(0.172f, 0.688f);
245}
246
247/*
248 * Falling edges showed only:
249 * 6 3 2 5 4 1
250 * Cr #1 |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
251 * Cr #2 ---|-|-|---|-|-----|-------|-|-|---|-|-----|-------
252 * Cam -|-------------------------------------------------
253 *
254 * Cr #1 last falling edge BTDC: 10
255 * Cr #2 single tooth's falling edge BTDC #1, #2: (55 + 1)
256 * There is no details about gap betweent Cr #2 tooths in 2 and 3 groups.
257 * Looking at timing diagram it is same as for Cr #1 = 30 degrees.
258 * So:
259 * Cr #2 two tooth group BTDC #3, #4: (55 + 1), (55 + 1 - 30)
260 * Cr #2 three tooth group BTDC #5, #6: (55 + 1), (55 + 1 - 30), (55 + 1 - 60) - last event actually after DTC
261 * Again there is no details about Cam tooth position, looking at
262 * diagrams it is about 30 degrees after #1 TDC
263 * Cam single tooth falling edge BTDC #6: (120 - 30) = 90
264 */
265
267 int n;
268 /* we should use only falling edges */
269 float width = 5.0;
270
271 float offset = 10.0; /* to make last event @ 720 */
272
273 /* T_CHANNEL_3 currently not supported, to keep trigger decode happy
274 * set cam second as primary, so logic will be able to sync
275 * Crank angle sensor #1 = TriggerWheel:: T_SECONDARY
276 * Crank andle sensor #2 = T_CHANNEL_3 - not supported yet
277 * Cam angle sensor = T_PRIMARY */
278#define SVX_CRANK_1 TriggerWheel::T_SECONDARY
279//#define SVX_CRANK_2 T_CHANNEL_3
280#define SVX_CAM TriggerWheel::T_PRIMARY
281
282#define CRANK_1_FALL(n) (20.0 + offset + 30.0 * (n))
283#define CRANK_1_RISE(n) (CRANK_1_FALL(n) - width)
284
285#define SUBARU_SVX_CRANK1_PULSE(n) \
286 s->addEventAngle(CRANK_1_RISE(n), TriggerValue::RISE, SVX_CRANK_1); \
287 s->addEventAngle(CRANK_1_FALL(n), TriggerValue::FALL, SVX_CRANK_1)
288
289 /* cam falling edge offset from preceding Cr #1 falling edge */
290 float cam_offset = (10.0 + 30.0 + 30.0 + 30.0) - 90.0;
291#define SUBARU_SVX_CAM_PULSE(n) \
292 s->addEvent720(CRANK_1_RISE(n) + cam_offset, TriggerValue::RISE, SVX_CAM); \
293 s->addEvent720(CRANK_1_FALL(n) + cam_offset, TriggerValue::FALL, SVX_CAM)
294
295#ifdef SVX_CRANK_2
296 /* Cr #2 signle tooth falling edge is (55 + 1) BTDC
297 * preceding Cr #1 falling edge is (10 + 30 + 30) BTDC */
298 float crank_2_offset = (10.0 + 30.0 + 30.0) - (55.0 + 1.0);
299
300 #define SUBARU_SVX_CRANK2_PULSE(n) \
301 s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, TriggerValue::RISE, SVX_CRANK_2); \
302 s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, TriggerValue::FALL, SVX_CRANK_2)
303#else
304 #define SUBARU_SVX_CRANK2_PULSE(n) (void)(n)
305#endif
306
307 /* we should use only falling edges */
308 // TODO: this trigger needs to be converted to SyncEdge::RiseOnly, so invert all rise/fall events!
309 // see https://github.com/rusefi/rusefi/issues/4624
311 s->isSynchronizationNeeded = false;
312 s->useOnlyPrimaryForSync = true;
313
314 /* counting Crank #1 tooths, should reach 23 at the end */
315 n = 0;
316 /****** 0 *****/
317 SUBARU_SVX_CRANK1_PULSE(n);
318 n++;
319 SUBARU_SVX_CRANK1_PULSE(n);
320 /* crank #2 - one 1/1 */
321 SUBARU_SVX_CRANK2_PULSE(n);
322 n++;
323 SUBARU_SVX_CRANK1_PULSE(n);
324 n++;
325 SUBARU_SVX_CRANK1_PULSE(n);
326 /* +10 - TDC #1 */
327 n++;
328 SUBARU_SVX_CRANK1_PULSE(n);
329 /* cam - one */
330 SUBARU_SVX_CAM_PULSE(n);
331 n++;
332 SUBARU_SVX_CRANK1_PULSE(n);
333 /* crank #2 - three - 1/3 */
334 SUBARU_SVX_CRANK2_PULSE(n);
335 n++;
336 SUBARU_SVX_CRANK1_PULSE(n);
337 /* crank #2 - three - 2/3 */
338 SUBARU_SVX_CRANK2_PULSE(n);
339 n++;
340 SUBARU_SVX_CRANK1_PULSE(n);
341 /* +10 - TDC #6 */
342 /* crank #2 - three - 3/3 */
343 SUBARU_SVX_CRANK2_PULSE(n);
344 n++;
345 SUBARU_SVX_CRANK1_PULSE(n);
346 n++;
347 SUBARU_SVX_CRANK1_PULSE(n);
348 /* crank #2 - two - 1/2 */
349 SUBARU_SVX_CRANK2_PULSE(n);
350 n++;
351 SUBARU_SVX_CRANK1_PULSE(n);
352 /* crank #2 - two - 2/2 */
353 SUBARU_SVX_CRANK2_PULSE(n);
354 n++;
355 SUBARU_SVX_CRANK1_PULSE(n);
356 /* +10 - TDC #3 */
357
358 /****** 360 *****/
359 n++;
360 SUBARU_SVX_CRANK1_PULSE(n);
361 n++;
362 SUBARU_SVX_CRANK1_PULSE(n);
363 /* crank #2 - one - 1/1 */
364 SUBARU_SVX_CRANK2_PULSE(n);
365 n++;
366 SUBARU_SVX_CRANK1_PULSE(n);
367 n++;
368 SUBARU_SVX_CRANK1_PULSE(n);
369 /* +10 - TDC #2 */
370 n++;
371 SUBARU_SVX_CRANK1_PULSE(n);
372 n++;
373 SUBARU_SVX_CRANK1_PULSE(n);
374 /* crank #2 - three - 1/3 */
375 SUBARU_SVX_CRANK2_PULSE(n);
376 n++;
377 SUBARU_SVX_CRANK1_PULSE(n);
378 /* crank #2 - three - 2/3 */
379 SUBARU_SVX_CRANK2_PULSE(n);
380 n++;
381 SUBARU_SVX_CRANK1_PULSE(n);
382 /* +10 - TDC #5 */
383 /* crank #2 - three - 3/3 */
384 SUBARU_SVX_CRANK2_PULSE(n);
385 n++;
386 SUBARU_SVX_CRANK1_PULSE(n);
387 n++;
388 SUBARU_SVX_CRANK1_PULSE(n);
389 /* crank #2 - two - 1/2 */
390 SUBARU_SVX_CRANK2_PULSE(n);
391 n++;
392 SUBARU_SVX_CRANK1_PULSE(n);
393 /* crank #2 - two - 2/2 */
394 SUBARU_SVX_CRANK2_PULSE(n);
395 n++;
396 SUBARU_SVX_CRANK1_PULSE(n);
397 /* +10 - TDC #4 */
398 /****** 720 *****/
399
400 /* from sichronization point, which is Cam falling */
401 s->tdcPosition = 720 - 30;
402
403#undef SUBARU_SVX_CRANK1_PULSE
404#undef SUBARU_SVX_CRANK2_PULSE
405#undef SUBARU_SVX_CAM_PULSE
406}
Trigger shape has all the fields needed to describe and decode trigger signal.
void initialize(operation_mode_e operationMode, SyncEdge syncEdge)
void addToothFallRise(angle_t angle, angle_t width=10, TriggerWheel const channelIndex=TriggerWheel::T_PRIMARY)
void addEventAngle(angle_t angle, TriggerValue const state, TriggerWheel const channelIndex=TriggerWheel::T_PRIMARY)
void setTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo)
void setTriggerSynchronizationGap3(int index, float syncRatioFrom, float syncRatioTo)
@ FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR
@ FOUR_STROKE_CRANK_SENSOR
@ FOUR_STROKE_CAM_SENSOR
void initialize_one_of_36_2_2_2(TriggerWaveform *s, int firstCount, int secondCount)
void initializeSubaru_SVX(TriggerWaveform *s)
void initializeSubaru7_6_crankOnly(TriggerWaveform *s)
void initialize36_2_2_2(TriggerWaveform *s)
void initializeSubaru7_6_camOnly(TriggerWaveform *s)
static void initializeSubaru7_6(TriggerWaveform *s, bool withCrankWheel)
void initializeSubaruOnly7(TriggerWaveform *s)
void initializeSubaruEZ30(TriggerWaveform *s)
uint16_t offset
Definition tunerstudio.h:0