36#ifndef NOISE_RATIO_THRESHOLD
37#define NOISE_RATIO_THRESHOLD 3000
100#if EFI_SHAFT_POSITION_INPUT
119 if (triggerShapeSynchPointIndex == EFI_ERROR_CODE) {
125 int riseOnlyIndex = 0;
132 size_t triggerShapeLength = shape->
getSize();
145 auto wrappedIndex = (triggerShapeSynchPointIndex +
eventIndex) % length;
149 auto triggerDefinitionIndex = wrappedIndex % triggerShapeLength;
152 float angle = shape->
getAngle(wrappedIndex) - firstAngle;
159 criticalAssertVoid(triggerDefinitionIndex < triggerShapeLength,
"trigger shape fail");
160 assertIsInBounds(triggerDefinitionIndex, shape->
isRiseEvent,
"isRise");
198#define PRINT_INC_INDEX if (printTriggerTrace) {\
199 printf("nextTriggerEvent index=%d\r\n", currentCycle.current_index); \
202#define PRINT_INC_INDEX {}
205#define nextTriggerEvent() \
207 if (useOnlyRisingEdgeForTrigger) {currentCycle.current_index++;} \
208 currentCycle.current_index++; \
227 totalShift += engineCycle / divider;
233 if (totalShift > 0) {
250 #pragma GCC diagnostic push
251 #pragma GCC diagnostic ignored "-Waddress"
257 #pragma GCC diagnostic pop
279 return "SHAFT_PRIMARY_FALLING";
281 return "SHAFT_PRIMARY_RISING";
283 return "SHAFT_SECONDARY_FALLING";
285 return "SHAFT_SECONDARY_RISING";
292 return "TriggerValue::FALL";
294 return "TriggerValue::RISE";
313 int countersError = 0;
314 for (
int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
316 if (countersError != 0) {
321#if EFI_DETAILED_LOGGING
322 printf(
"getEventCountersError: isDecodingError=%d\n", (countersError != 0));
323 if (countersError != 0) {
324 for (
int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
330 return countersError;
334 bool wasSynchronized,
335 const efitick_t nowNt,
340 if (wasSynchronized) {
351 printf(
"onShaftSynchronization index=%d %d\r\n",
382 if (std::isnan(ratioFrom)) {
388 if (std::isnan(gap)) {
389 efiPrintf(
"%s index=%d NaN gap, you have noise issues?", prefix, i);
393 bool gapOk =
isInRange(ratioFrom, gap, ratioTo);
395 efiPrintf(
"%s %srpm=%d time=%d eventIndex=%lu gapIndex=%d: %s gap=%.3f expected from %.3f to %.3f error=%s",
425 const efitick_t nowNt) {
438 if (triggerStateListener) {
451 if (!useOnlyRisingEdgeForTrigger &&
prevSignal == signal) {
470 currentDurationLong > 10 * NT_PER_SECOND ? 10 * NT_PER_SECOND : currentDurationLong;
475 printf(
"%s isLessImportant %s now=%d index=%d\r\n",
488 printf(
"%s event %s %lld\r\n",
498 bool isSynchronizationPoint;
509 if (isSynchronizationPoint) {
520#if EFI_PROD_CODE || EFI_SIMULATOR
524 const char * prefix = verbose ?
"[vrb]" :
"[err]";
525 printGaps(prefix, triggerConfiguration, triggerShape);
531 printf(
"%sindex=%d: gap=%.2f expected from %.2f to %.2f error=%s\r\n",
549 unsigned int endOfCycleIndex = triggerShape.
getSize() - (useOnlyRisingEdgeForTrigger ? 2 : 1);
555 printf(
"decodeTriggerEvent sync=%d isSynchronizationPoint=%d index=%d size=%d\r\n",
557 isSynchronizationPoint,
565 printf(
"decodeTriggerEvent gap %s isSynchronizationPoint=%d index=%d %s\r\n",
572 if (isSynchronizationPoint) {
576 if (triggerStateListener) {
586 if (wasSynchronized && isDecodingError) {
595 printGaps(
"newerr", triggerConfiguration, triggerShape);
616 if (wasSynchronized) {
674 if (!currentGapOk || !secondGapOk) {
687 if (std::isnan(from)) {
696 bool isGapCondition =
700 if (!isGapCondition) {
729 triggerConfiguration,
732 return EFI_ERROR_CODE;
740 printf(
"findTriggerZeroEventIndex: syncIndex located %lu!\r\n", syncIndex.Value);
745 syncIndex.Value, *
this, shape);
747 return syncIndex.Value % shape.
getSize();
const char * getTrigger_type_e(trigger_type_e value)
TriggerCentral triggerCentral
RpmCalculator rpmCalculator
OutputPin debugTriggerSync
PrimaryTriggerDecoder(const char *name)
void onTooManyTeeth(int actual, int expected) override
void resetState() override
void onTriggerError() override
void onNotEnoughTeeth(int actual, int expected) override
angle_t syncEnginePhase(int divider, int remainder, angle_t engineCycle)
static float getOrZero(SensorType type)
InstantRpmCalculator instantRpm
bool isEngineSnifferEnabled
const char *const PrintPrefix
trigger_config_s TriggerType
bool VerboseTriggerSynchDetails
virtual void resetState()
efitick_t mostRecentSyncTime
void printGaps(const char *prefix, const TriggerConfiguration &triggerConfiguration, const TriggerWaveform &triggerShape)
void resetCurrentCycleState()
void incrementShaftSynchronizationCounter()
TriggerDecoderBase(const char *name)
virtual void onTriggerError()
float gapRatio[PWM_PHASE_MAX_COUNT *6]
void onShaftSynchronization(bool wasSynchronized, const efitick_t nowNt, const TriggerWaveform &triggerShape)
int getCurrentIndex() const
uint32_t findTriggerZeroEventIndex(TriggerWaveform &shape, const TriggerConfiguration &triggerConfiguration)
virtual void onNotEnoughTeeth(int, int)
virtual void onTooManyTeeth(int, int)
Timer m_timeSinceDecodeError
uint32_t orderingErrorCounter
efitick_t toothed_previous_time
bool shaft_is_synchronized
int getSynchronizationCounter() const
int getEventCountersError(const TriggerWaveform &triggerShape) const
void setShaftSynchronized(bool value)
int64_t totalEventCountBase
int64_t getTotalEventCounter() const
trigger_event_e prevSignal
expected< TriggerDecodeResult > decodeTriggerEvent(const char *msg, const TriggerWaveform &triggerShape, TriggerStateListener *triggerStateListener, const TriggerConfiguration &triggerConfiguration, const trigger_event_e signal, const efitick_t nowNt)
Trigger decoding happens here VR falls are filtered out and some VR noise detection happens prior to ...
bool isValidIndex(const TriggerWaveform &triggerShape) const
current_cycle_state_s currentCycle
bool someSortOfTriggerError() const
void setTriggerErrorState(int errorIncrement=1)
uint32_t toothDurations[GAP_TRACKING_LENGTH+1]
uint32_t totalTriggerErrorCounter
bool isSyncPoint(const TriggerWaveform &triggerShape, trigger_type_e triggerType) const
bool getShaftSynchronized() const
static expected< uint32_t > findTriggerSyncPoint(TriggerWaveform &shape, const TriggerConfiguration &triggerConfiguration, TriggerDecoderBase &state)
static void assertSyncPosition(const TriggerConfiguration &triggerConfiguration, const uint32_t index, TriggerDecoderBase &state, TriggerWaveform &shape)
void onTooManyTeeth(int actual, int expected) override
void onNotEnoughTeeth(int actual, int expected) override
const char * boolToString(bool value)
bool isInRange(T min, T val, T max)
efitimesec_t getTimeNowS()
Current system time in seconds (32 bits)
TriggerCentral * getTriggerCentral()
static EngineAccessor engine
Main engine configuration data structure.
static constexpr engine_configuration_s * engineConfiguration
bool warning(ObdCode code, const char *fmt,...)
void firmwareError(ObdCode code, const char *fmt,...)
@ CUSTOM_TRIGGER_SYNC_ANGLE_RANGE
@ CUSTOM_TRIGGER_SYNC_ANGLE2
@ CUSTOM_CAM_TOO_MANY_TEETH
@ OBD_PCM_Processor_Fault
@ CUSTOM_TRIGGER_SYNC_ANGLE
@ CUSTOM_PRIMARY_TOO_MANY_TEETH
@ CUSTOM_CAM_NOT_ENOUGH_TEETH
@ CUSTOM_PRIMARY_NOT_ENOUGH_TEETH
@ CUSTOM_TRIGGER_UNEXPECTED
triggerCountersError("triggerCountersError", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1585, 1.0, -1.0, -1.0, "")
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
@ SHAFT_SECONDARY_FALLING
virtual void OnTriggerStateProperState(efitick_t nowNt, size_t triggerStateIndex)=0
virtual void OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError)=0
virtual void OnTriggerSynchronizationLost()=0
virtual TriggerStateListener * nextListener()=0
size_t eventCount[PWM_PHASE_MAX_WAVE_PER_PWM]
uint32_t triggerElapsedUs
bool m_hasSynchronizedPhase
int8_t triggerCountersError
uint8_t triggerStateIndex
float triggerSyncGapRatio
uint32_t synchronizationCounter
void setArrayValues(TValue(&array)[TSize], float value)
void LogTriggerSync(bool isSync, efitick_t timestamp)
void onTransitionEvent(TransitionEvent event)
const char * getTrigger_value_e(TriggerValue value)
static bool shouldConsiderEdge(const TriggerWaveform &triggerShape, TriggerWheel triggerWheel, TriggerValue edge)
PUBLIC_API_WEAK bool isTriggerCounterError(int8_t triggerCountersError)
static TriggerValue eventType[4]
const char * getTrigger_event_e(trigger_event_e value)
static TriggerWheel eventIndex[4]
const char * getTrigger_event_e(trigger_event_e value)
void wrapAngle(angle_t &angle, const char *msg, ObdCode code)