| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | /* | |||
| 2 | * @file trigger_universal.cpp | |||
| 3 | * | |||
| 4 | * @date Jan 3, 2017 | |||
| 5 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
| 6 | */ | |||
| 7 | ||||
| 8 | #include "pch.h" | |||
| 9 | ||||
| 10 | #include "trigger_universal.h" | |||
| 11 | ||||
| 12 | /** | |||
| 13 | * @see getCycleDuration | |||
| 14 | */ | |||
| 15 | 133854 | angle_t getEngineCycle(operation_mode_e operationMode) { | ||
| 16 |
2/2✓ Branch 0 taken 2826 times.
✓ Branch 1 taken 131028 times.
|
133854 | return operationMode == TWO_STROKE ? 360 : FOUR_STROKE_ENGINE_CYCLE; | |
| 17 | } | |||
| 18 | ||||
| 19 | /** | |||
| 20 | * last fall aligned at 720 and skipped area is right before 720 | |||
| 21 | */ | |||
| 22 | 277 | void addSkippedToothTriggerEvents(TriggerWheel wheel, TriggerWaveform *s, int totalTeethCount, int skippedCount, | ||
| 23 | float toothWidthPercentage, float offset, float engineCycle, float filterLeft, float filterRight) { | |||
| 24 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 277 times.
|
277 | criticalAssertVoid(totalTeethCount > 0, "total count"); | |
| 25 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 277 times.
|
277 | criticalAssertVoid(skippedCount >= 0, "skipped count"); | |
| 26 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 277 times.
|
277 | criticalAssertVoid(toothWidthPercentage < 1, "toothWidthPercentage"); | |
| 27 | ||||
| 28 | 277 | float oneTooth = engineCycle / totalTeethCount; | ||
| 29 | ||||
| 30 |
2/2✓ Branch 0 taken 4632 times.
✓ Branch 1 taken 277 times.
|
2/2✓ Decision 'true' taken 4632 times.
✓ Decision 'false' taken 277 times.
|
4909 | for (int i = 0; i < totalTeethCount - skippedCount - 1; i++) { |
| 31 | 4632 | float angleDown = oneTooth * (i + (1 - toothWidthPercentage)); | ||
| 32 | 4632 | float angleUp = oneTooth * (i + 1); | ||
| 33 | 4632 | s->addEventClamped(offset + angleDown, TriggerValue::RISE, wheel, filterLeft, filterRight); | ||
| 34 | 4632 | s->addEventClamped(offset + angleUp, TriggerValue::FALL, wheel, filterLeft, filterRight); | ||
| 35 | } | |||
| 36 | ||||
| 37 | 277 | float angleDown = oneTooth * (totalTeethCount - skippedCount - 1 + (1 - toothWidthPercentage)); | ||
| 38 | 277 | s->addEventClamped(offset + angleDown, TriggerValue::RISE, wheel, filterLeft, filterRight); | ||
| 39 | // custom handling of last event in order to avoid rounding error | |||
| 40 | 277 | s->addEventClamped(offset + engineCycle, TriggerValue::FALL, wheel, filterLeft, filterRight); | ||
| 41 | } | |||
| 42 | ||||
| 43 | 242 | void initializeSkippedToothTrigger(TriggerWaveform *s, int totalTeethCount, int skippedCount, | ||
| 44 | operation_mode_e operationMode, SyncEdge syncEdge) { | |||
| 45 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 242 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 242 times.
|
242 | if (totalTeethCount <= 0) { |
| 46 | ✗ | firmwareError(ObdCode::CUSTOM_OBD_TRIGGER_WAVEFORM, "Invalid total tooth count for missing tooth decoder: %d", totalTeethCount); | ||
| 47 | ✗ | s->setShapeDefinitionError(true); | ||
| 48 | ✗ | return; | ||
| 49 | } | |||
| 50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 242 times.
|
242 | efiAssertVoid(ObdCode::CUSTOM_NULL_SHAPE, s != NULL, "TriggerWaveform is NULL"); | |
| 51 | ||||
| 52 | 242 | s->initialize(operationMode, syncEdge); | ||
| 53 | ||||
| 54 | #if EFI_UNIT_TEST | |||
| 55 | 242 | s->knownOperationMode = false; | ||
| 56 | #endif // EFI_UNIT_TEST | |||
| 57 | ||||
| 58 | 242 | s->setTriggerSynchronizationGap(skippedCount + 1); | ||
| 59 |
4/4✓ Branch 0 taken 90 times.
✓ Branch 1 taken 152 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 4 times.
|
2/2✓ Decision 'true' taken 86 times.
✓ Decision 'false' taken 156 times.
|
242 | if (totalTeethCount > 6 && skippedCount > 0) { |
| 60 | // this gap is not required to synch on perfect signal but is needed to handle to reject cranking transition noise and potentially high rev noise as well | |||
| 61 | 86 | s->setSecondTriggerSynchronizationGap(1); | ||
| 62 | } | |||
| 63 |
4/4✓ Branch 0 taken 127 times.
✓ Branch 1 taken 115 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 99 times.
|
242 | s->shapeWithoutTdc = (totalTeethCount > 1) && (skippedCount == 0); | |
| 64 |
4/4✓ Branch 0 taken 122 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 25 times.
|
242 | s->isSynchronizationNeeded = (totalTeethCount > 2) && (skippedCount != 0); | |
| 65 | ||||
| 66 | ||||
| 67 | 242 | addSkippedToothTriggerEvents(TriggerWheel::T_PRIMARY, s, totalTeethCount, skippedCount, 0.5, 0, getEngineCycle(operationMode), | ||
| 68 | NO_LEFT_FILTER, NO_RIGHT_FILTER); | |||
| 69 | } | |||
| 70 | ||||
| 71 | 521 | void configureOnePlusOne(TriggerWaveform *s) { | ||
| 72 | 521 | s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::Rise); | ||
| 73 | ||||
| 74 | 521 | s->addEvent360( 90, TriggerValue::RISE, TriggerWheel::T_PRIMARY); | ||
| 75 | 521 | s->addEvent360(180, TriggerValue::FALL, TriggerWheel::T_PRIMARY); | ||
| 76 | ||||
| 77 | 521 | s->addEvent360(270, TriggerValue::RISE, TriggerWheel::T_SECONDARY); | ||
| 78 | 521 | s->addEvent360(360, TriggerValue::FALL, TriggerWheel::T_SECONDARY); | ||
| 79 | ||||
| 80 | 521 | s->isSynchronizationNeeded = false; | ||
| 81 | 521 | s->useOnlyPrimaryForSync = true; | ||
| 82 | 521 | } | ||
| 83 | ||||
| 84 | 1 | void configure3_1_cam(TriggerWaveform *s) { | ||
| 85 | 1 | s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::RiseOnly); | ||
| 86 | ||||
| 87 | ||||
| 88 | 1 | const float crankW = 360 / 3 / 2; | ||
| 89 | ||||
| 90 | ||||
| 91 | 1 | TriggerWheel crank = TriggerWheel::T_SECONDARY; | ||
| 92 | ||||
| 93 | 1 | s->addEvent720(10, TriggerValue::RISE, TriggerWheel::T_PRIMARY); | ||
| 94 | 1 | s->addEvent720(50, TriggerValue::FALL, TriggerWheel::T_PRIMARY); | ||
| 95 | ||||
| 96 | ||||
| 97 | 1 | float a = 2 * crankW; | ||
| 98 | ||||
| 99 | // #1/3 | |||
| 100 | 1 | s->addEvent720(a += crankW, TriggerValue::RISE, crank); | ||
| 101 | 1 | s->addEvent720(a += crankW, TriggerValue::FALL, crank); | ||
| 102 | // #2/3 | |||
| 103 | 1 | s->addEvent720(a += crankW, TriggerValue::RISE, crank); | ||
| 104 | 1 | s->addEvent720(a += crankW, TriggerValue::FALL, crank); | ||
| 105 | // #3/3 | |||
| 106 | 1 | a += crankW; | ||
| 107 | 1 | a += crankW; | ||
| 108 | ||||
| 109 | // 2nd #1/3 | |||
| 110 | 1 | s->addEvent720(a += crankW, TriggerValue::RISE, crank); | ||
| 111 | 1 | s->addEvent720(a += crankW, TriggerValue::FALL, crank); | ||
| 112 | ||||
| 113 | // 2nd #2/3 | |||
| 114 | 1 | s->addEvent720(a += crankW, TriggerValue::RISE, crank); | ||
| 115 | 1 | s->addEvent720(a += crankW, TriggerValue::FALL, crank); | ||
| 116 | ||||
| 117 | 1 | s->isSynchronizationNeeded = false; | ||
| 118 | 1 | } | ||
| 119 | ||||
| 120 | /** | |||
| 121 | * https://rusefi.com/forum/viewtopic.php?f=5&t=1977 | |||
| 122 | */ | |||
| 123 | 1 | void configureKawaKX450F(TriggerWaveform *s) { | ||
| 124 | 1 | float engineCycle = FOUR_STROKE_ENGINE_CYCLE; | ||
| 125 | 1 | s->initialize(FOUR_STROKE_CRANK_SENSOR, SyncEdge::Rise); | ||
| 126 | ||||
| 127 | 1 | s->setTriggerSynchronizationGap(2.28); | ||
| 128 | ||||
| 129 | 1 | float toothWidth = 3 / 20.0; | ||
| 130 | ||||
| 131 | 1 | addSkippedToothTriggerEvents(TriggerWheel::T_PRIMARY, s, 18, 0, toothWidth, 0, engineCycle, | ||
| 132 | NO_LEFT_FILTER, 720 - 39); | |||
| 133 | ||||
| 134 | 1 | s->addToothRiseFall(360, /* width*/10.80); | ||
| 135 | 1 | } | ||
| 136 | ||||
| 137 | // TT_VVT_BOSCH_QUICK_START | |||
| 138 | 17 | void configureQuickStartSenderWheel(TriggerWaveform *s) { | ||
| 139 | // todo: most cam wheels are defined as 'SyncEdge::Rise' or 'SyncEdge::RiseOnly' shall we unify? | |||
| 140 | 17 | s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::Fall); | ||
| 141 | ||||
| 142 | // our preference is to sync not too close to crank sync point | |||
| 143 | 17 | s->setTriggerSynchronizationGap(0.645); | ||
| 144 | 17 | s->setSecondTriggerSynchronizationGap(1.556); | ||
| 145 | ||||
| 146 | 17 | s->addToothRiseFall(90, /* width*/ 70); | ||
| 147 | 17 | s->addToothRiseFall(130, /* width*/ 20); | ||
| 148 | 17 | s->addToothRiseFall(220, /* width*/ 20); | ||
| 149 | 17 | s->addToothRiseFall(360, /* width*/ 70); | ||
| 150 | 17 | } | ||
| 151 | ||||
| 152 | 15 | static void commonSymmetrical(TriggerWaveform* s, int count, float gapFrom, float gapTo) { | ||
| 153 | 15 | s->shapeWithoutTdc = true; | ||
| 154 | ||||
| 155 | // Sync after 2 good teeth | |||
| 156 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
|
2/2✓ Decision 'true' taken 30 times.
✓ Decision 'false' taken 15 times.
|
45 | for (size_t i = 0; i < 2; i++) { |
| 157 | /** | |||
| 158 | * https://github.com/rusefi/rusefi/issues/4943#issuecomment-1376289608 | |||
| 159 | * gaps would be nice during running but horrible during running | |||
| 160 | * Hopefully we do not want variable gap logic yet? | |||
| 161 | */ | |||
| 162 | 30 | s->setTriggerSynchronizationGap3(i, gapFrom, gapTo); | ||
| 163 | } | |||
| 164 | ||||
| 165 | 15 | float width = 360 / count; | ||
| 166 | ||||
| 167 | // Just a single tooth with 50% duty cycle | |||
| 168 | 15 | s->addEventAngle(width / 2, TriggerValue::FALL, TriggerWheel::T_PRIMARY); | ||
| 169 | 15 | s->addEventAngle(width, TriggerValue::RISE, TriggerWheel::T_PRIMARY); | ||
| 170 | 15 | } | ||
| 171 | ||||
| 172 | // Useful for: | |||
| 173 | // - Honda 24+1 (set this on crank primary, single tooth cam) | |||
| 174 | // - AEM 24+1 CAS wheel (same config as Honda) | |||
| 175 | 3 | void configure12ToothCrank(TriggerWaveform* s) { | ||
| 176 | 3 | s->initialize(FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR, SyncEdge::RiseOnly); | ||
| 177 | ||||
| 178 | // 2JZ would be global trigger offset 65 but same wheel could be Honda, not hard coding for now | |||
| 179 | 3 | commonSymmetrical(s, 12, 0.2f, 3.4f); | ||
| 180 | 3 | } | ||
| 181 | ||||
| 182 | 11 | void configure3ToothCrank(TriggerWaveform* s) { | ||
| 183 | 11 | s->initialize(FOUR_STROKE_THREE_TIMES_CRANK_SENSOR, SyncEdge::RiseOnly); | ||
| 184 | 11 | commonSymmetrical(s, 3, 0.5, 1.4); | ||
| 185 | 11 | } | ||
| 186 | ||||
| 187 | 1 | void configure6ToothCrank(TriggerWaveform* s) { | ||
| 188 | 1 | s->initialize(FOUR_STROKE_SIX_TIMES_CRANK_SENSOR, SyncEdge::RiseOnly); | ||
| 189 | 1 | commonSymmetrical(s, 6, 0.7, 1.4); | ||
| 190 | 1 | } | ||
| 191 |