fome-fw/firmware/controllers/trigger/decoders/trigger_subaru.cpp

323 lines
10 KiB
C++

/**
* @file trigger_subaru.cpp
*
* @date Sep 10, 2015
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "trigger_subaru.h"
/**
* This trigger is also used by Nissan and Mazda
* https://rusefi.com/forum/viewtopic.php?f=2&t=1932
*/
void initialize36_2_2_2(TriggerWaveform *s) {
s->initialize(FOUR_STROKE_CAM_SENSOR);
float wide = 30 * 2;
float narrow = 10 * 2;
s->setTriggerSynchronizationGap(0.6);
s->setSecondTriggerSynchronizationGap(0.9);
float base = 0;
for (int i = 0; i < 12; i++) {
s->addEvent720(base + narrow / 2, T_PRIMARY, TV_RISE);
s->addEvent720(base + narrow, T_PRIMARY, TV_FALL);
base += narrow;
}
s->addEvent720(base + wide / 2, T_PRIMARY, TV_RISE);
s->addEvent720(base + wide, T_PRIMARY, TV_FALL);
base += wide;
for (int i = 0; i < 15; i++) {
s->addEvent720(base + narrow / 2, T_PRIMARY, TV_RISE);
s->addEvent720(base + narrow, T_PRIMARY, TV_FALL);
base += narrow;
}
s->addEvent720(720 - wide - wide / 2, T_PRIMARY, TV_RISE);
s->addEvent720(720 - wide, T_PRIMARY, TV_FALL);
s->addEvent720(720 - wide / 2, T_PRIMARY, TV_RISE);
s->addEvent720(720, T_PRIMARY, TV_FALL);
s->useOnlyPrimaryForSync = true;
}
static void initializeSubaru7_6(TriggerWaveform *s, bool withCrankWheel) {
s->initialize(FOUR_STROKE_CAM_SENSOR);
/* To make trigger decoder happy last event should be exactly at 720
* This code generates two trigger patterns: crank+cam (7+6) and
* cam only (7-6).
* So last event should be CAM event
* Crank: --------||-|---||-|-----||-|---||-|
* Cam: -|-|-|------|------!-|------|------
* '!' pulse is selected as event at 720
* So next event is the first one on following description
* '!' pulse happens 20 degrees ATDC #2 (third in order)
* or 180 + 180 + 20. So we have */
s->tdcPosition = 160 + 360;
float width = 5;
/* 97 degrees BTDC, but we have 20 degrees shift:
* 180 - 97 - 20 = 63 */
#define SUBARU76_CRANK_PULSE0(cycle) \
s->addEvent720((180 * (cycle)) + 63 - width, T_SECONDARY, TV_RISE); \
s->addEvent720((180 * (cycle)) + 63, T_SECONDARY, TV_FALL)
/* 65 degrees BTDC, but we have 20 degrees shift:
* 180 - 65 - 20 = 95 */
#define SUBARU76_CRANK_PULSE1(cycle) \
s->addEvent720((180 * (cycle)) + 95 - width, T_SECONDARY, TV_RISE); \
s->addEvent720((180 * (cycle)) + 95, T_SECONDARY, TV_FALL)
/* 10 degrees BTDC, but we have 20 degrees shift:
* 180 - 10 - 20 = 150 */
#define SUBARU76_CRANK_PULSE2(cycle) \
s->addEvent720((180 * (cycle)) + 150 - width, T_SECONDARY, TV_RISE); \
s->addEvent720((180 * (cycle)) + 150, T_SECONDARY, TV_FALL)
#define SUBARU76_CAM_PULSE(cycle, offset) \
s->addEvent720((180 * (cycle)) + (offset) - width, T_PRIMARY, TV_RISE); \
s->addEvent720((180 * (cycle)) + (offset), T_PRIMARY, TV_FALL)
/* (TDC#2 + 20) + 15 */
SUBARU76_CAM_PULSE(0, +15);
if (withCrankWheel) {
SUBARU76_CRANK_PULSE0(0);
SUBARU76_CRANK_PULSE1(0);
SUBARU76_CRANK_PULSE2(0);
}
/* (TDC#4 + 20) */
SUBARU76_CAM_PULSE(1, 0);
if (withCrankWheel) {
SUBARU76_CRANK_PULSE0(1);
SUBARU76_CRANK_PULSE1(1);
SUBARU76_CRANK_PULSE2(1);
}
/* (TDC#1 + 20) - 15 */
SUBARU76_CAM_PULSE(2, -15);
/* (TDC#1 + 20) */
SUBARU76_CAM_PULSE(2, 0);
/* (TDC#1 + 20) + 15 */
SUBARU76_CAM_PULSE(2, +15);
if (withCrankWheel) {
SUBARU76_CRANK_PULSE0(2);
SUBARU76_CRANK_PULSE1(2);
SUBARU76_CRANK_PULSE2(2);
}
/* (TDC#3 + 20) */
SUBARU76_CAM_PULSE(3, 0);
if (withCrankWheel) {
SUBARU76_CRANK_PULSE0(3);
SUBARU76_CRANK_PULSE1(3);
SUBARU76_CRANK_PULSE2(3);
}
/* (TDC#2 + 20) */
SUBARU76_CAM_PULSE(4, 0);
// why is this trigger gap wider than average?
s->setTriggerSynchronizationGap2(6.53 * TRIGGER_GAP_DEVIATION_LOW, 10.4 * TRIGGER_GAP_DEVIATION_HIGH);
s->setTriggerSynchronizationGap3(1, 0.8 * TRIGGER_GAP_DEVIATION_LOW, 1 * TRIGGER_GAP_DEVIATION_HIGH);
s->useOnlyPrimaryForSync = true;
}
void initializeSubaruOnly7(TriggerWaveform *s) {
initializeSubaru7_6(s, false);
}
void initializeSubaru7_6(TriggerWaveform *s) {
initializeSubaru7_6(s, true);
}
void initializeSubaru_SVX(TriggerWaveform *s) {
int n;
float cam_offset = 15.0;
/* we should use only falling edges */
float width = 5.0;
/* additional 10 degrees should be removed!!! */
#define CRANK_1_FALL(n) (20.0 + 10.0 + 30.0 * (n))
#define CRANK_1_RISE(n) (CRANK_1_FALL(n) - width)
/* T_CHANNEL_3 currently not supported, to keep trigger decode happy
* set cam second as secondary, so logic will be able to sync
* Crank angle sensor #1 = T_SECONDARY
* Crank andle sensor #2 = T_CHANNEL_3 - not supported yet
* Cam angle sensor = T_PRIMARY */
#define SVX_CRANK_1 T_SECONDARY
//#define SVX_CRANK_2 T_CHANNEL_3
#define SVX_CAM T_PRIMARY
#ifdef SVX_CRANK_2
/* crank 2 falling happens between crank #1 fallings */
float crank_2_offset = 15.0;
#endif
s->initialize(FOUR_STROKE_CAM_SENSOR);
/****** 0 *****/
n = 0;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 1;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - one 1/1 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 2;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 3;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* +10 - TDC #1 */
n = 4;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* cam - one */
s->addEvent720(CRANK_1_RISE(n) + cam_offset, SVX_CAM, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + cam_offset, SVX_CAM, TV_FALL);
n = 5;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - three - 1/3 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 6;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - three - 2/3 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 7;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* +10 - TDC #6 */
#ifdef SVX_CRANK_2
/* crank #2 - three - 3/3 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 8;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 9;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - two - 1/2 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 10;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - two - 2/2 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 11;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* +10 - TDC #3 */
/****** 360 *****/
n = 12;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 13;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - one - 1/1 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 14;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 15;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* +10 - TDC #2 */
n = 16;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 17;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - three - 1/3 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 18;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - three - 2/3 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 19;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* +10 - TDC #5 */
#ifdef SVX_CRANK_2
/* crank #2 - three - 3/3 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 20;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
n = 21;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - two - 1/2 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 22;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
#ifdef SVX_CRANK_2
/* crank #2 - two - 2/2 */
s->addEvent720(CRANK_1_RISE(n) + crank_2_offset, SVX_CRANK_2, TV_RISE);
s->addEvent720(CRANK_1_FALL(n) + crank_2_offset, SVX_CRANK_2, TV_FALL);
#endif
n = 23;
s->addEvent720(CRANK_1_RISE(n), SVX_CRANK_1, TV_RISE);
s->addEvent720(CRANK_1_FALL(n), SVX_CRANK_1, TV_FALL);
/* +10 - TDC #4 */
/****** 720 *****/
s->isSynchronizationNeeded = false;
s->useOnlyPrimaryForSync = true;
s->tdcPosition = -60;
}