rusefi/firmware/controllers/trigger/decoders/trigger_universal.cpp

184 lines
6.1 KiB
C++
Raw Normal View History

2017-01-03 03:05:22 -08:00
/*
* @file trigger_universal.cpp
*
* @date Jan 3, 2017
2020-01-13 18:57:43 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2017-01-03 03:05:22 -08:00
*/
#include "pch.h"
2017-01-03 14:01:42 -08:00
#include "trigger_universal.h"
2017-01-03 03:05:22 -08:00
/**
* @see getCycleDuration
*/
2017-01-03 14:01:42 -08:00
angle_t getEngineCycle(operation_mode_e operationMode) {
2019-01-01 11:05:11 -08:00
return operationMode == TWO_STROKE ? 360 : FOUR_STROKE_ENGINE_CYCLE;
2017-01-03 14:01:42 -08:00
}
2017-01-03 03:05:22 -08:00
2023-08-15 09:25:53 -07:00
/**
* last fall aligned at 720 and skipped area is right before 720
*/
2022-09-11 00:46:50 -07:00
void addSkippedToothTriggerEvents(TriggerWheel wheel, TriggerWaveform *s, int totalTeethCount, int skippedCount,
2018-12-25 16:42:27 -08:00
float toothWidth, float offset, float engineCycle, float filterLeft, float filterRight) {
efiAssertVoid(ObdCode::CUSTOM_ERR_6586, totalTeethCount > 0, "total count");
efiAssertVoid(ObdCode::CUSTOM_ERR_6587, skippedCount >= 0, "skipped count");
2017-01-03 14:01:42 -08:00
2023-08-15 09:25:53 -07:00
float oneTooth = engineCycle / totalTeethCount;
2017-01-03 14:01:42 -08:00
for (int i = 0; i < totalTeethCount - skippedCount - 1; i++) {
2023-08-15 09:25:53 -07:00
float angleDown = oneTooth * (i + (1 - toothWidth));
float angleUp = oneTooth * (i + 1);
s->addEventClamped(offset + angleDown, TriggerValue::RISE, wheel, filterLeft, filterRight);
s->addEventClamped(offset + angleUp, TriggerValue::FALL, wheel, filterLeft, filterRight);
2017-01-03 14:01:42 -08:00
}
2023-08-15 09:25:53 -07:00
float angleDown = oneTooth * (totalTeethCount - skippedCount - 1 + (1 - toothWidth));
s->addEventClamped(offset + angleDown, TriggerValue::RISE, wheel, filterLeft, filterRight);
// custom handling of last event in order to avoid rounding error
s->addEventClamped(offset + engineCycle, TriggerValue::FALL, wheel, filterLeft, filterRight);
2017-01-03 14:01:42 -08:00
}
void initializeSkippedToothTrigger(TriggerWaveform *s, int totalTeethCount, int skippedCount,
operation_mode_e operationMode, SyncEdge syncEdge) {
2017-02-23 05:20:24 -08:00
if (totalTeethCount <= 0) {
firmwareError(ObdCode::CUSTOM_OBD_TRIGGER_WAVEFORM, "Invalid total tooth count for missing tooth decoder: %d", totalTeethCount);
s->setShapeDefinitionError(true);
2017-02-23 05:20:24 -08:00
return;
}
efiAssertVoid(ObdCode::CUSTOM_NULL_SHAPE, s != NULL, "TriggerWaveform is NULL");
s->initialize(operationMode, syncEdge);
#if EFI_UNIT_TEST
s->knownOperationMode = false;
#endif // EFI_UNIT_TEST
2017-01-03 14:01:42 -08:00
s->setTriggerSynchronizationGap(skippedCount + 1);
if (totalTeethCount > 6 && skippedCount > 0) {
// 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
s->setSecondTriggerSynchronizationGap(1);
}
s->shapeWithoutTdc = (totalTeethCount > 1) && (skippedCount == 0);
2017-03-06 14:42:16 -08:00
s->isSynchronizationNeeded = (totalTeethCount > 2) && (skippedCount != 0);
2017-01-03 14:01:42 -08:00
2020-01-14 00:54:46 -08:00
2022-09-11 00:46:50 -07:00
addSkippedToothTriggerEvents(TriggerWheel::T_PRIMARY, s, totalTeethCount, skippedCount, 0.5, 0, getEngineCycle(operationMode),
2018-12-25 16:42:27 -08:00
NO_LEFT_FILTER, NO_RIGHT_FILTER);
2017-01-03 14:01:42 -08:00
}
2017-01-03 03:05:22 -08:00
2020-04-25 19:23:53 -07:00
void configureOnePlusOne(TriggerWaveform *s) {
s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::Rise);
2017-12-13 18:17:32 -08:00
s->addEvent360( 90, TriggerValue::RISE, TriggerWheel::T_PRIMARY);
s->addEvent360(180, TriggerValue::FALL, TriggerWheel::T_PRIMARY);
2017-12-13 18:17:32 -08:00
s->addEvent360(270, TriggerValue::RISE, TriggerWheel::T_SECONDARY);
s->addEvent360(360, TriggerValue::FALL, TriggerWheel::T_SECONDARY);
2017-12-13 18:17:32 -08:00
s->isSynchronizationNeeded = false;
s->useOnlyPrimaryForSync = true;
}
2020-04-25 19:23:53 -07:00
void configure3_1_cam(TriggerWaveform *s) {
s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::RiseOnly);
2017-12-13 18:17:32 -08:00
const float crankW = 360 / 3 / 2;
TriggerWheel crank = TriggerWheel::T_SECONDARY;
2017-12-13 18:17:32 -08:00
s->addEvent720(10, TriggerValue::RISE, TriggerWheel::T_PRIMARY);
s->addEvent720(50, TriggerValue::FALL, TriggerWheel::T_PRIMARY);
2017-12-13 18:17:32 -08:00
float a = 2 * crankW;
// #1/3
s->addEvent720(a += crankW, TriggerValue::RISE, crank);
s->addEvent720(a += crankW, TriggerValue::FALL, crank);
2017-12-13 18:17:32 -08:00
// #2/3
s->addEvent720(a += crankW, TriggerValue::RISE, crank);
s->addEvent720(a += crankW, TriggerValue::FALL, crank);
2017-12-13 18:17:32 -08:00
// #3/3
a += crankW;
a += crankW;
// 2nd #1/3
s->addEvent720(a += crankW, TriggerValue::RISE, crank);
s->addEvent720(a += crankW, TriggerValue::FALL, crank);
2017-12-13 18:17:32 -08:00
// 2nd #2/3
s->addEvent720(a += crankW, TriggerValue::RISE, crank);
s->addEvent720(a += crankW, TriggerValue::FALL, crank);
2017-12-13 18:17:32 -08:00
s->isSynchronizationNeeded = false;
}
2020-04-25 16:50:43 -07:00
2021-04-08 20:23:01 -07:00
/**
* https://rusefi.com/forum/viewtopic.php?f=5&t=1977
*/
2021-04-08 19:16:14 -07:00
void configureKawaKX450F(TriggerWaveform *s) {
2021-04-08 20:23:01 -07:00
float engineCycle = FOUR_STROKE_ENGINE_CYCLE;
s->initialize(FOUR_STROKE_CRANK_SENSOR, SyncEdge::Rise);
2021-04-08 20:23:01 -07:00
2021-04-12 21:24:52 -07:00
s->setTriggerSynchronizationGap(2.28);
2021-04-08 20:23:01 -07:00
float toothWidth = 3 / 20.0;
2022-09-11 00:46:50 -07:00
addSkippedToothTriggerEvents(TriggerWheel::T_PRIMARY, s, 18, 0, toothWidth, 0, engineCycle,
2021-04-08 20:23:01 -07:00
NO_LEFT_FILTER, 720 - 39);
2021-04-08 19:16:14 -07:00
s->addToothRiseFall(360, /* width*/10.80);
2021-04-08 19:16:14 -07:00
}
2020-04-25 16:50:43 -07:00
void configureQuickStartSenderWheel(TriggerWaveform *s) {
2023-05-13 10:40:47 -07:00
// todo: most cam wheels are defined as 'SyncEdge::Rise' or 'SyncEdge::RiseOnly' shall we unify?
s->initialize(FOUR_STROKE_CAM_SENSOR, SyncEdge::Fall);
2020-04-25 19:23:53 -07:00
// our preference is to sync not too close to crank sync point
s->setTriggerSynchronizationGap(0.645);
s->setSecondTriggerSynchronizationGap(1.556);
2020-04-25 19:23:53 -07:00
s->addToothRiseFall(90, /* width*/ 70);
s->addToothRiseFall(130, /* width*/ 20);
s->addToothRiseFall(220, /* width*/ 20);
s->addToothRiseFall(360, /* width*/ 70);
2020-04-25 16:50:43 -07:00
}
static void commonSymmetrical(TriggerWaveform* s, int count) {
s->shapeWithoutTdc = true;
2023-01-09 12:48:49 -08:00
// Sync after 2 good teeth
for (size_t i = 0; i < 2; i++) {
/**
* https://github.com/rusefi/rusefi/issues/4943#issuecomment-1376289608
* gaps would be nice during running but horrible during running
* Hopefully we do not want variable gap logic yet?
*/
s->setTriggerSynchronizationGap3(i, 0.2f, 3.4f);
}
float width = 360 / count;
// Just a single tooth with 50% duty cycle
s->addEventAngle(width / 2, TriggerValue::FALL, TriggerWheel::T_PRIMARY);
s->addEventAngle(width, TriggerValue::RISE, TriggerWheel::T_PRIMARY);
}
// Useful for:
// - Honda 24+1 (set this on crank primary, single tooth cam)
// - AEM 24+1 CAS wheel (same config as Honda)
void configure12ToothCrank(TriggerWaveform* s) {
s->initialize(FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR, SyncEdge::RiseOnly);
// 2JZ would be global trigger offset 65 but same wheel could be Honda, not hard coding for now
commonSymmetrical(s, 12);
}
2023-12-25 17:28:55 -08:00
void configure3ToothCrank(TriggerWaveform* s) {
s->initialize(FOUR_STROKE_THREE_TIMES_CRANK_SENSOR, SyncEdge::RiseOnly);
commonSymmetrical(s, 3);
}