36#ifndef NOISE_RATIO_THRESHOLD
37#define NOISE_RATIO_THRESHOLD 3000
100#if EFI_SHAFT_POSITION_INPUT
119 if (triggerShapeSynchPointIndex == EFI_ERROR_CODE) {
130 size_t triggerShapeLength = shape->
getSize();
135 float lastAnglePrimary = 0.0;
136 float lastAngleSecondary = 0.0;
146 auto wrappedIndex = (triggerShapeSynchPointIndex +
eventIndex) % length;
150 auto triggerDefinitionIndex = wrappedIndex % triggerShapeLength;
153 float angle = shape->
getAngle(wrappedIndex) - firstAngle;
160 criticalAssertVoid(triggerDefinitionIndex < triggerShapeLength,
"trigger shape fail");
161 assertIsInBounds(triggerDefinitionIndex, shape->
isRiseEvent,
"isRise");
167 lastAnglePrimary = angle;
169 lastAngleSecondary = angle;
172 }
else if (primary) {
207#define PRINT_INC_INDEX if (printTriggerTrace) {\
208 printf("nextTriggerEvent index=%d\r\n", currentCycle.current_index); \
211#define PRINT_INC_INDEX {}
214#define nextTriggerEvent() \
216 if (useOnlyRisingEdgeForTrigger) {currentCycle.current_index++;} \
217 currentCycle.current_index++; \
236 totalShift += engineCycle / divider;
242 if (totalShift > 0) {
259 #pragma GCC diagnostic push
260 #pragma GCC diagnostic ignored "-Waddress"
266 #pragma GCC diagnostic pop
293 return "SHAFT_PRIMARY_FALLING";
295 return "SHAFT_PRIMARY_RISING";
297 return "SHAFT_SECONDARY_FALLING";
299 return "SHAFT_SECONDARY_RISING";
306 return "TriggerValue::FALL";
308 return "TriggerValue::RISE";
327 int countersError = 0;
328 for (
int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
330 if (countersError != 0) {
335#if EFI_DETAILED_LOGGING
336 printf(
"getEventCountersError: isDecodingError=%d\n", (countersError != 0));
337 if (countersError != 0) {
338 for (
int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
344 return countersError;
348 bool wasSynchronized,
349 const efitick_t nowNt,
354 if (wasSynchronized) {
365 printf(
"onShaftSynchronization index=%d %d\r\n",
396 if (std::isnan(ratioFrom)) {
402 if (std::isnan(gap)) {
403 efiPrintf(
"%s index=%d NaN gap, you have noise issues?", prefix, i);
407 bool gapOk =
isInRange(ratioFrom, gap, ratioTo);
409 efiPrintf(
"%s %srpm=%d time=%d eventIndex=%lu gapIndex=%d: %s gap=%.3f expected from %.3f to %.3f error=%s",
439 const efitick_t nowNt) {
452 if (triggerStateListener) {
465 if (!useOnlyRisingEdgeForTrigger &&
prevSignal == signal) {
484 currentDurationLong > 10 * NT_PER_SECOND ? 10 * NT_PER_SECOND : currentDurationLong;
489 printf(
"%s isLessImportant %s now=%d index=%d\r\n",
502 printf(
"%s event %s %lld\r\n",
512 bool isSynchronizationPoint;
523 if (isSynchronizationPoint) {
534#if EFI_PROD_CODE || EFI_SIMULATOR
538 const char * prefix = verbose ?
"[vrb]" :
"[err]";
539 printGaps(prefix, triggerConfiguration, triggerShape);
545 printf(
"%sindex=%d: gap=%.2f expected from %.2f to %.2f error=%s\r\n",
563 unsigned int endOfCycleIndex = triggerShape.
getSize() - (useOnlyRisingEdgeForTrigger ? 2 : 1);
569 printf(
"decodeTriggerEvent sync=%d isSynchronizationPoint=%d index=%d size=%d\r\n",
571 isSynchronizationPoint,
579 printf(
"decodeTriggerEvent gap %s isSynchronizationPoint=%d index=%d %s\r\n",
586 if (isSynchronizationPoint) {
590 if (triggerStateListener) {
600 if (wasSynchronized && isDecodingError) {
609 printGaps(
"newerr", triggerConfiguration, triggerShape);
630 if (wasSynchronized) {
692 if (!currentGapOk || !secondGapOk) {
705 if (std::isnan(from)) {
714 bool isGapCondition =
718 if (!isGapCondition) {
747 triggerConfiguration,
750 return EFI_ERROR_CODE;
758 printf(
"findTriggerZeroEventIndex: syncIndex located %lu!\r\n", syncIndex.Value);
763 syncIndex.Value, *
this, shape);
765 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
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1890, 1.0, -1.0, -1.0, "")
triggerCountersError("triggerCountersError", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1605, 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)