rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Data Fields | Protected Member Functions | Private Member Functions | Private Attributes
TriggerDecoderBase Class Reference

#include <trigger_decoder.h>

Inheritance diagram for TriggerDecoderBase:
Inheritance graph
[legend]
Collaboration diagram for TriggerDecoderBase:
Collaboration graph
[legend]

Public Member Functions

 TriggerDecoderBase (const char *name)
 
void printGaps (const char *prefix, const TriggerConfiguration &triggerConfiguration, const TriggerWaveform &triggerShape)
 
int getCurrentIndex () const
 
int getSynchronizationCounter () const
 
void incrementShaftSynchronizationCounter ()
 
int64_t getTotalEventCounter () const
 
expected< TriggerDecodeResultdecodeTriggerEvent (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 invoking this method, for Hall this method is invoked every time we have a fall or rise on one of the trigger sensors. This method changes the state of trigger_state_s data structure according to the trigger event.
 
void onShaftSynchronization (bool wasSynchronized, const efitick_t nowNt, const TriggerWaveform &triggerShape)
 
bool isValidIndex (const TriggerWaveform &triggerShape) const
 
virtual void resetState ()
 
void setShaftSynchronized (bool value)
 
bool getShaftSynchronized () const
 
uint32_t findTriggerZeroEventIndex (TriggerWaveform &shape, const TriggerConfiguration &triggerConfiguration)
 
bool someSortOfTriggerError () const
 

Data Fields

float gapRatio [PWM_PHASE_MAX_COUNT *6]
 
bool shaft_is_synchronized = false
 
efitick_t mostRecentSyncTime
 
Timer previousEventTimer
 
uint32_t toothDurations [GAP_TRACKING_LENGTH+1]
 
efitick_t toothed_previous_time
 
current_cycle_state_s currentCycle
 
const char *const name
 
uint32_t totalTriggerErrorCounter
 
uint32_t orderingErrorCounter
 
efitick_t startOfCycleNt
 
- Data Fields inherited from trigger_state_s
uint32_t synchronizationCounter = (uint32_t)0
 
uint32_t vvtToothDurations0 = (uint32_t)0
 
float vvtCurrentPosition = (float)0
 
float vvtToothPosition [4] = {}
 
float triggerSyncGapRatio = (float)0
 
uint8_t triggerStateIndex = (uint8_t)0
 
int8_t triggerCountersError = (int8_t)0
 
uint8_t alignmentFill_at_34 [2] = {}
 

Protected Member Functions

virtual void onTriggerError ()
 
virtual void onNotEnoughTeeth (int, int)
 
virtual void onTooManyTeeth (int, int)
 

Private Member Functions

void setTriggerErrorState (int errorIncrement=1)
 
void resetCurrentCycleState ()
 
bool isSyncPoint (const TriggerWaveform &triggerShape, trigger_type_e triggerType) const
 
int getEventCountersError (const TriggerWaveform &triggerShape) const
 

Private Attributes

trigger_event_e prevSignal
 
int64_t totalEventCountBase
 
bool isFirstEvent
 
Timer m_timeSinceDecodeError
 

Detailed Description

See also
TriggerWaveform for trigger wheel shape definition

Definition at line 85 of file trigger_decoder.h.

Constructor & Destructor Documentation

◆ TriggerDecoderBase()

TriggerDecoderBase::TriggerDecoderBase ( const char name)

Definition at line 40 of file trigger_decoder.cpp.

41 : name(p_name)
42{
44}
virtual void resetState()
const char *const name
Here is the call graph for this function:

Member Function Documentation

◆ decodeTriggerEvent()

expected< TriggerDecodeResult > TriggerDecoderBase::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 invoking this method, for Hall this method is invoked every time we have a fall or rise on one of the trigger sensors. This method changes the state of trigger_state_s data structure according to the trigger event.

Parameters
signaltype of event which just happened
nowNtcurrent time

We are here if there is a time gap between now and previous shaft event - that means the engine is not running. That means we have lost synchronization since the engine is not running :)

For performance reasons, we want to work with 32 bit values. If there has been more then 10 seconds since previous trigger event we do not really care.

todo: technically we can afford detailed logging even with 60/2 as long as low RPM todo: figure out exact threshold as a function of RPM and tooth count? Open question what is 'triggerShape.getSize()' for 60/2 is it 58 or 58*2 or 58*4?

We are here in case of a wheel without synchronization - we just need to count events, synchronization point simply happens once we have the right number of events

in case of noise the counter could be above the expected number of events, that's why 'more or equals' and not just 'equals'

Definition at line 416 of file trigger_decoder.cpp.

422 {
424
425#if EFI_PROD_CODE
427#endif
428
429 if (previousEventTimer.getElapsedSecondsAndReset(nowNt) > 1) {
430 /**
431 * We are here if there is a time gap between now and previous shaft event - that means the engine is not running.
432 * That means we have lost synchronization since the engine is not running :)
433 */
435 if (triggerStateListener) {
436 triggerStateListener->OnTriggerSynchronizationLost();
437 }
438 }
439
440 bool useOnlyRisingEdgeForTrigger = triggerShape.useOnlyRisingEdges;
441
442 efiAssert(ObdCode::CUSTOM_TRIGGER_UNEXPECTED, signal <= SHAFT_SECONDARY_RISING, "unexpected signal", unexpected);
443
444 TriggerWheel triggerWheel = eventIndex[signal];
445 TriggerValue type = eventType[signal];
446
447 // Check that we didn't get the same edge twice in a row - that should be impossible
448 if (!useOnlyRisingEdgeForTrigger && prevSignal == signal) {
450 }
451
452 prevSignal = signal;
453
454 currentCycle.eventCount[(int)triggerWheel]++;
455
456 if (toothed_previous_time > nowNt) {
457 firmwareError(ObdCode::CUSTOM_OBD_93, "[%s] toothed_previous_time after nowNt prev=%lu now=%lu", msg, (uint32_t)toothed_previous_time, (uint32_t)nowNt);
458 }
459
460 efidur_t currentDurationLong = isFirstEvent ? 0 : (nowNt - toothed_previous_time);
461
462 /**
463 * For performance reasons, we want to work with 32 bit values. If there has been more then
464 * 10 seconds since previous trigger event we do not really care.
465 */
466 toothDurations[0] =
467 currentDurationLong > 10 * NT_PER_SECOND ? 10 * NT_PER_SECOND : currentDurationLong;
468
469 if (!shouldConsiderEdge(triggerShape, triggerWheel, type)) {
470#if EFI_UNIT_TEST
471 if (printTriggerTrace) {
472 printf("%s isLessImportant %s now=%d index=%d\r\n",
473 getTrigger_type_e(triggerConfiguration.TriggerType.type),
474 getTrigger_event_e(signal),
475 (int)nowNt,
477 }
478#endif /* EFI_UNIT_TEST */
479
480 // For less important events we simply increment the index.
481 nextTriggerEvent();
482 } else {
483#if !EFI_PROD_CODE
484 if (printTriggerTrace) {
485 printf("%s event %s %lld\r\n",
486 getTrigger_type_e(triggerConfiguration.TriggerType.type),
487 getTrigger_event_e(signal),
488 nowNt);
489 printf("decodeTriggerEvent ratio %.2f: current=%d previous=%d\r\n", 1.0 * toothDurations[0] / toothDurations[1],
491 }
492#endif
493
494 isFirstEvent = false;
495 bool isSynchronizationPoint;
496 bool wasSynchronized = getShaftSynchronized();
497
498 if (triggerShape.isSynchronizationNeeded) {
500
501 if (wasSynchronized && triggerSyncGapRatio > NOISE_RATIO_THRESHOLD) {
503 }
504
505 isSynchronizationPoint = isSyncPoint(triggerShape, triggerConfiguration.TriggerType.type);
506 if (isSynchronizationPoint) {
508 }
509
510 /**
511 * todo: technically we can afford detailed logging even with 60/2 as long as low RPM
512 * todo: figure out exact threshold as a function of RPM and tooth count?
513 * Open question what is 'triggerShape.getSize()' for 60/2 is it 58 or 58*2 or 58*4?
514 */
515 bool silentTriggerError = triggerShape.getSize() > 40 && engineConfiguration->silentTriggerError;
516
517#if EFI_PROD_CODE || EFI_SIMULATOR
518 bool verbose = getTriggerCentral()->isEngineSnifferEnabled && triggerConfiguration.VerboseTriggerSynchDetails;
519
520 if (verbose || (someSortOfTriggerError() && !silentTriggerError)) {
521 const char * prefix = verbose ? "[vrb]" : "[err]";
522 printGaps(prefix, triggerConfiguration, triggerShape);
523 }
524#else
525 if (printTriggerTrace) {
526 for (int i = 0;i<triggerShape.gapTrackingLength;i++) {
527 float gap = 1.0 * toothDurations[i] / toothDurations[i + 1];
528 printf("%sindex=%d: gap=%.2f expected from %.2f to %.2f error=%s\r\n",
529 triggerConfiguration.PrintPrefix,
530 i,
531 gap,
532 triggerShape.synchronizationRatioFrom[i],
533 triggerShape.synchronizationRatioTo[i],
535 }
536 }
537#endif /* EFI_PROD_CODE */
538 } else {
539 /**
540 * We are here in case of a wheel without synchronization - we just need to count events,
541 * synchronization point simply happens once we have the right number of events
542 *
543 * in case of noise the counter could be above the expected number of events, that's why 'more or equals' and not just 'equals'
544 */
545
546 unsigned int endOfCycleIndex = triggerShape.getSize() - (useOnlyRisingEdgeForTrigger ? 2 : 1);
547
548 isSynchronizationPoint = !getShaftSynchronized() || (currentCycle.current_index >= endOfCycleIndex);
549
550#if EFI_UNIT_TEST
551 if (printTriggerTrace) {
552 printf("decodeTriggerEvent sync=%d isSynchronizationPoint=%d index=%d size=%d\r\n",
554 isSynchronizationPoint,
556 triggerShape.getSize());
557 }
558#endif /* EFI_UNIT_TEST */
559 }
560#if EFI_UNIT_TEST
561 if (printTriggerTrace) {
562 printf("decodeTriggerEvent gap %s isSynchronizationPoint=%d index=%d %s\r\n",
563 getTrigger_type_e(triggerConfiguration.TriggerType.type),
564 isSynchronizationPoint, currentCycle.current_index,
565 getTrigger_event_e(signal));
566 }
567#endif /* EFI_UNIT_TEST */
568
569 if (isSynchronizationPoint) {
571 bool isDecodingError = isTriggerCounterError(triggerCountersError);
572
573 if (triggerStateListener) {
574 triggerStateListener->OnTriggerSynchronization(wasSynchronized, isDecodingError);
575 }
576
577 // If we got a sync point, but the wrong number of events since the last sync point
578 // One of two things has happened:
579 // - We missed a tooth, and this is the real sync point
580 // - Due to some mistake in timing, we found what looks like a sync point but actually isn't
581 // In either case, we should wait for another sync point before doing anything to try and run an engine,
582 // so we clear the synchronized flag.
583 if (wasSynchronized && isDecodingError) {
586
587 // Something wrong, no longer synchronized
589
590 // This is a decoding error
592 printGaps("newerr", triggerConfiguration, triggerShape);
593 } else {
594 // If this was the first sync point OR no decode error, we're synchronized!
596 }
597
598 // this call would update duty cycle values
599 nextTriggerEvent();
600
601 onShaftSynchronization(wasSynchronized, nowNt, triggerShape);
602 } else { /* if (!isSynchronizationPoint) */
603 nextTriggerEvent();
604 }
605
606 for (int i = triggerShape.gapTrackingLength; i > 0; i--) {
607 toothDurations[i] = toothDurations[i - 1];
608 }
609
610 toothed_previous_time = nowNt;
611
612#if EFI_UNIT_TEST
613 if (wasSynchronized) {
614 int uiGapIndex = (currentCycle.current_index) % triggerShape.getLength();
615 gapRatio[uiGapIndex] = triggerSyncGapRatio;
616 }
617#endif // EFI_UNIT_TEST
618 }
619
620 if (getShaftSynchronized() && !isValidIndex(triggerShape)) {
621 // We've had too many events since the last sync point, we should have seen a sync point by now.
622 // This is a trigger error.
623
624 // let's not show a warning if we are just starting to spin
628 }
629
631
633
634 return unexpected;
635 }
636
638
639 // Needed for early instant-RPM detection
640 TriggerStateListener * l = triggerStateListener;
641 while (l) {
643 l = l->nextListener();
644 }
645
646 if (getShaftSynchronized()) {
648 } else {
649 return unexpected;
650 }
651}
const char * getTrigger_type_e(trigger_type_e value)
OutputPin debugTriggerSync
Definition efi_gpio.h:110
void toggle()
Definition efi_gpio.cpp:571
static float getOrZero(SensorType type)
Definition sensor.h:87
const char *const PrintPrefix
trigger_config_s TriggerType
void printGaps(const char *prefix, const TriggerConfiguration &triggerConfiguration, const TriggerWaveform &triggerShape)
virtual void onTriggerError()
float gapRatio[PWM_PHASE_MAX_COUNT *6]
void onShaftSynchronization(bool wasSynchronized, const efitick_t nowNt, const TriggerWaveform &triggerShape)
virtual void onNotEnoughTeeth(int, int)
virtual void onTooManyTeeth(int, int)
efitick_t toothed_previous_time
int getEventCountersError(const TriggerWaveform &triggerShape) const
void setShaftSynchronized(bool value)
trigger_event_e prevSignal
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]
bool isSyncPoint(const TriggerWaveform &triggerShape, trigger_type_e triggerType) const
bool getShaftSynchronized() const
float synchronizationRatioFrom[GAP_TRACKING_LENGTH]
size_t getLength() const
float synchronizationRatioTo[GAP_TRACKING_LENGTH]
size_t getSize() const
EnginePins enginePins
Definition efi_gpio.cpp:24
const char * boolToString(bool value)
Definition efilib.cpp:19
TriggerCentral * getTriggerCentral()
Definition engine.cpp:593
static constexpr engine_configuration_s * engineConfiguration
void firmwareError(ObdCode code, const char *fmt,...)
@ CUSTOM_OBD_93
@ CUSTOM_TRIGGER_UNEXPECTED
@ DecodeTriggerEvent
TriggerWheel
efitick_t efidur_t
@ SHAFT_SECONDARY_RISING
TriggerValue
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]
static bool shouldConsiderEdge(const TriggerWaveform &triggerShape, TriggerWheel triggerWheel, TriggerValue edge)
PUBLIC_API_WEAK bool isTriggerCounterError(int8_t triggerCountersError)
static TriggerValue eventType[4]
bool printTriggerTrace
static TriggerWheel eventIndex[4]
const char * getTrigger_event_e(trigger_event_e value)
printf("\n")

Referenced by TriggerCentral::handleShaftSignal(), and handleVvtCamSignal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ findTriggerZeroEventIndex()

uint32_t TriggerDecoderBase::findTriggerZeroEventIndex ( TriggerWaveform shape,
const TriggerConfiguration triggerConfiguration 
)

Trigger shape is defined in a way which is convenient for trigger shape definition On the other hand, trigger decoder indexing begins from synchronization event.

This function finds the index of synchronization event within TriggerWaveform

Definition at line 711 of file trigger_decoder.cpp.

713 {
714#if EFI_PROD_CODE
715 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, hasLotsOfRemainingStack(), "findPos", -1);
716#endif
717
718
719 resetState();
720
721 if (shape.shapeDefinitionError) {
722 return 0;
723 }
724
725 expected<uint32_t> syncIndex = TriggerStimulatorHelper::findTriggerSyncPoint(shape,
726 triggerConfiguration,
727 *this);
728 if (!syncIndex) {
729 return EFI_ERROR_CODE;
730 }
731
732 // Assert that we found the sync point on the very first revolution
733 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, getSynchronizationCounter() == 0, "findZero_revCounter", EFI_ERROR_CODE);
734
735#if EFI_UNIT_TEST
736 if (printTriggerDebug) {
737 printf("findTriggerZeroEventIndex: syncIndex located %lu!\r\n", syncIndex.Value);
738 }
739#endif /* EFI_UNIT_TEST */
740
742 syncIndex.Value, *this, shape);
743
744 return syncIndex.Value % shape.getSize();
745}
int getSynchronizationCounter() 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)
@ CUSTOM_ERR_ASSERT
bool printTriggerDebug
Here is the call graph for this function:

◆ getCurrentIndex()

int TriggerDecoderBase::getCurrentIndex ( ) const

current trigger processing index, between zero and size

Definition at line 209 of file trigger_decoder.cpp.

209 {
211}

◆ getEventCountersError()

int TriggerDecoderBase::getEventCountersError ( const TriggerWaveform triggerShape) const
private

Definition at line 308 of file trigger_decoder.cpp.

308 {
309 // We can check if things are fine by comparing the number of events in a cycle with the expected number of event.
310 int countersError = 0;
311 for (int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
312 countersError = currentCycle.eventCount[i] - triggerShape.getExpectedEventCount((TriggerWheel)i);
313 if (countersError != 0) {
314 break;
315 }
316 }
317
318#if EFI_DETAILED_LOGGING
319 printf("getEventCountersError: isDecodingError=%d\n", (countersError != 0));
320 if (countersError != 0) {
321 for (int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
322 printf(" count: cur=%d exp=%d\n", currentCycle.eventCount[i], triggerShape.getExpectedEventCount((TriggerWheel)i));
323 }
324 }
325#endif /* EFI_UNIT_TEST */
326
327 return countersError;
328}
size_t getExpectedEventCount(TriggerWheel channelIndex) const

Referenced by decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getShaftSynchronized()

bool TriggerDecoderBase::getShaftSynchronized ( ) const

Definition at line 46 of file trigger_decoder.cpp.

46 {
48}

Referenced by decodeTriggerEvent(), handleVvtCamSignal(), TriggerNoiseFilter::noiseFilter(), SetNextCompositeEntry(), and RpmCalculator::setSpinningUp().

Here is the caller graph for this function:

◆ getSynchronizationCounter()

int TriggerDecoderBase::getSynchronizationCounter ( ) const

◆ getTotalEventCounter()

int64_t TriggerDecoderBase::getTotalEventCounter ( ) const

Definition at line 172 of file trigger_decoder.cpp.

Referenced by updateDevConsoleState().

Here is the caller graph for this function:

◆ incrementShaftSynchronizationCounter()

void TriggerDecoderBase::incrementShaftSynchronizationCounter ( )

this is important for crank-based virtual trigger and VVT magic

Definition at line 238 of file trigger_decoder.cpp.

238 {
240}

Referenced by onShaftSynchronization(), and PrimaryTriggerDecoder::syncEnginePhase().

Here is the caller graph for this function:

◆ isSyncPoint()

bool TriggerDecoderBase::isSyncPoint ( const TriggerWaveform triggerShape,
trigger_type_e  triggerType 
) const
private

Definition at line 653 of file trigger_decoder.cpp.

653 {
654 // Miata NB needs a special decoder.
655 // The problem is that the crank wheel only has 4 teeth, also symmetrical, so the pattern
656 // is long-short-long-short for one crank rotation.
657 // A quick acceleration can result in two successive "short gaps", so we see
658 // long-short-short-short-long instead of the correct long-short-long-short-long
659 // This logic expands the lower bound on a "long" tooth, then compares the last
660 // tooth to the current one.
661
662 // Instead of detecting short/long, this logic first checks for "maybe short" and "maybe long",
663 // then simply tests longer vs. shorter instead of absolute value.
665 auto secondGap = (float)toothDurations[1] / toothDurations[2];
666
667 bool currentGapOk = isInRange(triggerShape.synchronizationRatioFrom[0], (float)triggerSyncGapRatio, triggerShape.synchronizationRatioTo[0]);
668 bool secondGapOk = isInRange(triggerShape.synchronizationRatioFrom[1], secondGap, triggerShape.synchronizationRatioTo[1]);
669
670 // One or both teeth was impossible range, this is not the sync point
671 if (!currentGapOk || !secondGapOk) {
672 return false;
673 }
674
675 // If both teeth are in the range of possibility, return whether this gap is
676 // shorter than the last or not. If it is, this is the sync point.
677 return triggerSyncGapRatio < secondGap;
678 }
679
680 for (int i = 0; i < triggerShape.gapTrackingLength; i++) {
681 auto from = triggerShape.synchronizationRatioFrom[i];
682 auto to = triggerShape.synchronizationRatioTo[i];
683
684 if (std::isnan(from)) {
685 // don't check this gap, skip it
686 continue;
687 }
688
689 // This is transformed to avoid a division and use a cheaper multiply instead
690 // toothDurations[i] / toothDurations[i+1] > from
691 // is an equivalent comparison to
692 // toothDurations[i] > toothDurations[i+1] * from
693 bool isGapCondition =
694 (toothDurations[i] > toothDurations[i + 1] * from
695 && toothDurations[i] < toothDurations[i + 1] * to);
696
697 if (!isGapCondition) {
698 return false;
699 }
700 }
701
702 return true;
703}
bool isInRange(T min, T val, T max)
Definition efilib.h:82
triggerType

Referenced by decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isValidIndex()

bool TriggerDecoderBase::isValidIndex ( const TriggerWaveform triggerShape) const

Definition at line 187 of file trigger_decoder.cpp.

187 {
188 return currentCycle.current_index < triggerShape.getSize();
189}

Referenced by decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onNotEnoughTeeth()

virtual void TriggerDecoderBase::onNotEnoughTeeth ( int  ,
int   
)
inlineprotectedvirtual

Reimplemented in PrimaryTriggerDecoder, and VvtTriggerDecoder.

Definition at line 177 of file trigger_decoder.h.

177{ }

Referenced by decodeTriggerEvent().

Here is the caller graph for this function:

◆ onShaftSynchronization()

void TriggerDecoderBase::onShaftSynchronization ( bool  wasSynchronized,
const efitick_t  nowNt,
const TriggerWaveform triggerShape 
)

Definition at line 330 of file trigger_decoder.cpp.

333 {
334 startOfCycleNt = nowNt;
336
337 if (wasSynchronized) {
339 } else {
340 // We have just synchronized, this is the zeroth revolution
342 }
343
344 totalEventCountBase += triggerShape.getSize();
345
346#if EFI_UNIT_TEST
347 if (printTriggerDebug) {
348 printf("onShaftSynchronization index=%d %d\r\n",
351 }
352#endif /* EFI_UNIT_TEST */
353}
void incrementShaftSynchronizationCounter()

Referenced by decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onTooManyTeeth()

virtual void TriggerDecoderBase::onTooManyTeeth ( int  ,
int   
)
inlineprotectedvirtual

Reimplemented in PrimaryTriggerDecoder, and VvtTriggerDecoder.

Definition at line 178 of file trigger_decoder.h.

178{ }

Referenced by decodeTriggerEvent().

Here is the caller graph for this function:

◆ onTriggerError()

virtual void TriggerDecoderBase::onTriggerError ( )
inlineprotectedvirtual

Reimplemented in PrimaryTriggerDecoder.

Definition at line 175 of file trigger_decoder.h.

175{ }

Referenced by decodeTriggerEvent().

Here is the caller graph for this function:

◆ printGaps()

void TriggerDecoderBase::printGaps ( const char prefix,
const TriggerConfiguration triggerConfiguration,
const TriggerWaveform triggerShape 
)

Definition at line 374 of file trigger_decoder.cpp.

376 {
377 for (int i = 0;i<triggerShape.gapTrackingLength;i++) {
378 float ratioFrom = triggerShape.synchronizationRatioFrom[i];
379 if (std::isnan(ratioFrom)) {
380 // we do not track gap at this depth
381 continue;
382 }
383
384 float gap = 1.0 * toothDurations[i] / toothDurations[i + 1];
385 if (std::isnan(gap)) {
386 efiPrintf("%s index=%d NaN gap, you have noise issues?", prefix, i);
387 } else {
388 float ratioTo = triggerShape.synchronizationRatioTo[i];
389
390 bool gapOk = isInRange(ratioFrom, gap, ratioTo);
391
392 efiPrintf("%s %srpm=%d time=%d eventIndex=%lu gapIndex=%d: %s gap=%.3f expected from %.3f to %.3f error=%s",
393 prefix,
394 triggerConfiguration.PrintPrefix,
396 /* cast is needed to make sure we do not put 64 bit value to stack*/ (int)getTimeNowS(),
398 i,
399 gapOk ? "Y" : "n",
400 gap,
401 ratioFrom,
402 ratioTo,
404 }
405 }
406}
efitimesec_t getTimeNowS()
Current system time in seconds (32 bits)
Definition efitime.cpp:42

Referenced by decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resetCurrentCycleState()

void TriggerDecoderBase::resetCurrentCycleState ( )
private

Definition at line 95 of file trigger_decoder.cpp.

95 {
98}
void setArrayValues(TValue(&array)[TSize], float value)

Referenced by onShaftSynchronization(), and resetState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resetState()

void TriggerDecoderBase::resetState ( )
virtual

Reimplemented in PrimaryTriggerDecoder.

Definition at line 69 of file trigger_decoder.cpp.

Referenced by findTriggerZeroEventIndex(), Engine::OnTriggerSynchronizationLost(), PrimaryTriggerDecoder::resetState(), and TriggerDecoderBase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setShaftSynchronized()

void TriggerDecoderBase::setShaftSynchronized ( bool  value)

Definition at line 50 of file trigger_decoder.cpp.

50 {
51#if EFI_UNIT_TEST
52 if (value != shaft_is_synchronized) {
54 }
55#endif
56
57 if (value) {
59 // just got synchronized
61 }
62 } else {
63 // sync loss
65 }
67}
efitick_t getTimeNowNt()
Definition efitime.cpp:19
void LogTriggerSync(bool isSync, efitick_t timestamp)

Referenced by decodeTriggerEvent(), and resetState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setTriggerErrorState()

void TriggerDecoderBase::setTriggerErrorState ( int  errorIncrement = 1)
private

Definition at line 89 of file trigger_decoder.cpp.

89 {
91 totalTriggerErrorCounter += errorIncrement;
93}
void onTransitionEvent(TransitionEvent event)

Referenced by decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ someSortOfTriggerError()

bool TriggerDecoderBase::someSortOfTriggerError ( ) const
inline

Definition at line 166 of file trigger_decoder.h.

166 {
167 return !m_timeSinceDecodeError.hasElapsedSec(0.3);
168 }

Referenced by decodeTriggerEvent(), isTriggerErrorNow(), Engine::OnTriggerSynchronization(), and printGaps().

Here is the caller graph for this function:

Field Documentation

◆ currentCycle

current_cycle_state_s TriggerDecoderBase::currentCycle

◆ gapRatio

float TriggerDecoderBase::gapRatio[PWM_PHASE_MAX_COUNT *6]

used only for trigger export

Definition at line 107 of file trigger_decoder.h.

Referenced by decodeTriggerEvent().

◆ isFirstEvent

bool TriggerDecoderBase::isFirstEvent
private

Definition at line 190 of file trigger_decoder.h.

Referenced by decodeTriggerEvent(), and resetState().

◆ m_timeSinceDecodeError

Timer TriggerDecoderBase::m_timeSinceDecodeError
private

Definition at line 192 of file trigger_decoder.h.

Referenced by resetState(), setTriggerErrorState(), and someSortOfTriggerError().

◆ mostRecentSyncTime

efitick_t TriggerDecoderBase::mostRecentSyncTime

Definition at line 131 of file trigger_decoder.h.

Referenced by setShaftSynchronized().

◆ name

const char* const TriggerDecoderBase::name

◆ orderingErrorCounter

uint32_t TriggerDecoderBase::orderingErrorCounter

◆ previousEventTimer

Timer TriggerDecoderBase::previousEventTimer

Definition at line 133 of file trigger_decoder.h.

Referenced by decodeTriggerEvent().

◆ prevSignal

trigger_event_e TriggerDecoderBase::prevSignal
private

Definition at line 187 of file trigger_decoder.h.

Referenced by decodeTriggerEvent(), and resetState().

◆ shaft_is_synchronized

bool TriggerDecoderBase::shaft_is_synchronized = false

TRUE if we know where we are

Definition at line 130 of file trigger_decoder.h.

Referenced by getShaftSynchronized(), and setShaftSynchronized().

◆ startOfCycleNt

efitick_t TriggerDecoderBase::startOfCycleNt

this is start of real trigger cycle for virtual double trigger see timeAtVirtualZeroNt

Definition at line 159 of file trigger_decoder.h.

Referenced by onShaftSynchronization(), and resetState().

◆ toothDurations

uint32_t TriggerDecoderBase::toothDurations[GAP_TRACKING_LENGTH+1]

current duration at index zero and previous durations are following

Definition at line 138 of file trigger_decoder.h.

Referenced by decodeTriggerEvent(), handleVvtCamSignal(), isSyncPoint(), printGaps(), and resetState().

◆ toothed_previous_time

efitick_t TriggerDecoderBase::toothed_previous_time

Definition at line 140 of file trigger_decoder.h.

Referenced by decodeTriggerEvent(), and resetState().

◆ totalEventCountBase

int64_t TriggerDecoderBase::totalEventCountBase
private

Definition at line 188 of file trigger_decoder.h.

Referenced by getTotalEventCounter(), onShaftSynchronization(), and resetState().

◆ totalTriggerErrorCounter

uint32_t TriggerDecoderBase::totalTriggerErrorCounter

how many times since ECU reboot we had unexpected number of teeth in trigger cycle

Definition at line 148 of file trigger_decoder.h.

Referenced by canDashboardHaltech(), resetState(), setTriggerErrorState(), triggerInfo(), and updateTunerStudioState().


The documentation for this class was generated from the following files: