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();
143 auto wrappedIndex = (triggerShapeSynchPointIndex +
eventIndex) % length;
147 auto triggerDefinitionIndex = wrappedIndex % triggerShapeLength;
150 float angle = shape->
getAngle(wrappedIndex) - firstAngle;
157 criticalAssertVoid(triggerDefinitionIndex < triggerShapeLength,
"trigger shape fail");
158 assertIsInBounds(triggerDefinitionIndex, shape->
isRiseEvent,
"isRise");
195#define PRINT_INC_INDEX if (printTriggerTrace) {\
196 printf("nextTriggerEvent index=%d\r\n", currentCycle.current_index); \
199#define PRINT_INC_INDEX {}
202#define nextTriggerEvent() \
204 if (useOnlyRisingEdgeForTrigger) {currentCycle.current_index++;} \
205 currentCycle.current_index++; \
224 totalShift += engineCycle / divider;
230 if (totalShift > 0) {
247 #pragma GCC diagnostic push
248 #pragma GCC diagnostic ignored "-Waddress"
254 #pragma GCC diagnostic pop
276 return "SHAFT_PRIMARY_FALLING";
278 return "SHAFT_PRIMARY_RISING";
280 return "SHAFT_SECONDARY_FALLING";
282 return "SHAFT_SECONDARY_RISING";
289 return "TriggerValue::FALL";
291 return "TriggerValue::RISE";
310 int countersError = 0;
311 for (
int i = 0;i < PWM_PHASE_MAX_WAVE_PER_PWM;i++) {
313 if (countersError != 0) {
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++) {
327 return countersError;
331 bool wasSynchronized,
332 const efitick_t nowNt,
337 if (wasSynchronized) {
348 printf(
"onShaftSynchronization index=%d %d\r\n",
379 if (std::isnan(ratioFrom)) {
385 if (std::isnan(gap)) {
386 efiPrintf(
"%s index=%d NaN gap, you have noise issues?", prefix, i);
390 bool gapOk =
isInRange(ratioFrom, gap, ratioTo);
392 efiPrintf(
"%s %srpm=%d time=%d eventIndex=%lu gapIndex=%d: %s gap=%.3f expected from %.3f to %.3f error=%s",
422 const efitick_t nowNt) {
435 if (triggerStateListener) {
448 if (!useOnlyRisingEdgeForTrigger &&
prevSignal == signal) {
467 currentDurationLong > 10 * NT_PER_SECOND ? 10 * NT_PER_SECOND : currentDurationLong;
472 printf(
"%s isLessImportant %s now=%d index=%d\r\n",
485 printf(
"%s event %s %lld\r\n",
495 bool isSynchronizationPoint;
506 if (isSynchronizationPoint) {
517#if EFI_PROD_CODE || EFI_SIMULATOR
521 const char * prefix = verbose ?
"[vrb]" :
"[err]";
522 printGaps(prefix, triggerConfiguration, triggerShape);
528 printf(
"%sindex=%d: gap=%.2f expected from %.2f to %.2f error=%s\r\n",
546 unsigned int endOfCycleIndex = triggerShape.
getSize() - (useOnlyRisingEdgeForTrigger ? 2 : 1);
552 printf(
"decodeTriggerEvent sync=%d isSynchronizationPoint=%d index=%d size=%d\r\n",
554 isSynchronizationPoint,
562 printf(
"decodeTriggerEvent gap %s isSynchronizationPoint=%d index=%d %s\r\n",
569 if (isSynchronizationPoint) {
573 if (triggerStateListener) {
583 if (wasSynchronized && isDecodingError) {
592 printGaps(
"newerr", triggerConfiguration, triggerShape);
613 if (wasSynchronized) {
671 if (!currentGapOk || !secondGapOk) {
684 if (std::isnan(from)) {
693 bool isGapCondition =
697 if (!isGapCondition) {
726 triggerConfiguration,
729 return EFI_ERROR_CODE;
737 printf(
"findTriggerZeroEventIndex: syncIndex located %lu!\r\n", syncIndex.Value);
742 syncIndex.Value, *
this, shape);
744 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, 1601, 1.0, -1.0, -1.0, "")
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1886, 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)