rusefi/firmware/controllers/trigger/trigger_decoder.h

234 lines
6.0 KiB
C
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file trigger_decoder.h
*
* @date Dec 24, 2013
2020-01-07 21:02:40 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2015-07-10 06:01:56 -07:00
*/
2019-12-05 21:07:27 -08:00
#pragma once
2015-07-10 06:01:56 -07:00
#include "trigger_structure.h"
2019-09-03 16:30:51 -07:00
#include "trigger_state_generated.h"
#include "trigger_state_primary_generated.h"
2023-08-30 20:11:24 -07:00
#include <rusefi/timer.h>
2015-07-10 06:01:56 -07:00
const char *getTrigger_event_e(trigger_event_e value);
2022-09-10 23:57:35 -07:00
const char *getTrigger_value_e(TriggerValue value);
2015-07-10 06:01:56 -07:00
struct TriggerStateListener {
#if EFI_SHAFT_POSITION_INPUT
virtual void OnTriggerStateProperState(efitick_t nowNt) = 0;
2023-09-09 16:51:09 -07:00
virtual void OnTriggerSynchronization(bool wasSynchronized, bool isDecodingError) = 0;
virtual void OnTriggerSynchronizationLost() = 0;
2020-08-23 22:21:42 -07:00
#endif // EFI_SHAFT_POSITION_INPUT
};
class TriggerConfiguration {
2020-08-23 22:21:42 -07:00
public:
explicit TriggerConfiguration(const char* printPrefix) : PrintPrefix(printPrefix) {}
void update();
const char* const PrintPrefix;
bool VerboseTriggerSynchDetails;
trigger_config_s TriggerType;
protected:
2020-08-23 23:01:50 -07:00
virtual bool isVerboseTriggerSynchDetails() const = 0;
virtual trigger_config_s getType() const = 0;
};
class PrimaryTriggerConfiguration final : public TriggerConfiguration {
public:
PrimaryTriggerConfiguration() : TriggerConfiguration("TRG ") {}
protected:
bool isVerboseTriggerSynchDetails() const override;
trigger_config_s getType() const override;
};
class VvtTriggerConfiguration final : public TriggerConfiguration {
public:
const int index;
2023-11-01 06:48:33 -07:00
VvtTriggerConfiguration(const char * prefix, const int p_index) : TriggerConfiguration(prefix), index(p_index) {
}
protected:
bool isVerboseTriggerSynchDetails() const override;
trigger_config_s getType() const override;
};
2015-09-08 20:01:07 -07:00
typedef struct {
/**
* index within trigger revolution, from 0 to trigger event count
*/
uint32_t current_index;
/**
2015-09-12 13:01:43 -07:00
* Number of actual events of each channel within current trigger cycle, these
* values are used to detect trigger signal errors.
* see TriggerWaveform
2015-09-08 20:01:07 -07:00
*/
2021-07-13 11:50:10 -07:00
size_t eventCount[PWM_PHASE_MAX_WAVE_PER_PWM];
2015-09-08 20:01:07 -07:00
} current_cycle_state_s;
struct TriggerDecodeResult {
uint32_t CurrentIndex;
};
2018-02-05 14:16:34 -08:00
/**
* @see TriggerWaveform for trigger wheel shape definition
2018-02-05 14:16:34 -08:00
*/
2022-05-10 01:41:39 -07:00
class TriggerDecoderBase : public trigger_state_s {
2015-07-10 06:01:56 -07:00
public:
TriggerDecoderBase(const char* name);
2018-02-05 14:16:34 -08:00
/**
* current trigger processing index, between zero and #size
*/
2019-01-15 17:24:36 -08:00
int getCurrentIndex() const;
int getCrankSynchronizationCounter() const;
2016-08-23 19:02:18 -07:00
/**
* this is important for crank-based virtual trigger and VVT magic
*/
void incrementShaftSynchronizationCounter();
2021-07-05 21:09:35 -07:00
#if EFI_UNIT_TEST
/**
* used for trigger export only
*/
float gapRatio[PWM_PHASE_MAX_COUNT * 6];
#endif // EFI_UNIT_TEST
int64_t getTotalEventCounter() const;
expected<TriggerDecodeResult> decodeTriggerEvent(
2022-03-21 17:39:47 -07:00
const char *msg,
const TriggerWaveform& triggerShape,
TriggerStateListener* triggerStateListener,
const TriggerConfiguration& triggerConfiguration,
2020-08-23 22:21:42 -07:00
const trigger_event_e signal,
const efitick_t nowNt);
2020-08-26 14:30:13 -07:00
void onShaftSynchronization(
bool wasSynchronized,
2020-08-26 14:30:13 -07:00
const efitick_t nowNt,
const TriggerWaveform& triggerShape);
2020-01-26 09:02:54 -08:00
bool isValidIndex(const TriggerWaveform& triggerShape) const;
2015-07-10 06:01:56 -07:00
/**
* TRUE if we know where we are
*/
bool shaft_is_synchronized;
efitick_t mostRecentSyncTime;
Timer previousEventTimer;
2015-07-10 06:01:56 -07:00
2018-10-21 09:29:41 -07:00
/**
* current duration at index zero and previous durations are following
*/
2018-10-23 00:47:30 -07:00
uint32_t toothDurations[GAP_TRACKING_LENGTH + 1];
2018-10-21 08:27:14 -07:00
efitick_t toothed_previous_time;
2015-07-10 06:01:56 -07:00
2015-09-08 20:01:07 -07:00
current_cycle_state_s currentCycle;
const char* const name;
2017-12-12 15:04:54 -08:00
2015-08-17 20:02:01 -07:00
/**
* how many times since ECU reboot we had unexpected number of teeth in trigger cycle
*/
2015-07-10 06:01:56 -07:00
uint32_t totalTriggerErrorCounter;
uint32_t orderingErrorCounter;
2022-11-05 21:32:38 -07:00
virtual void resetState();
void setShaftSynchronized(bool value);
2021-07-03 07:37:03 -07:00
bool getShaftSynchronized();
2015-07-10 06:01:56 -07:00
2016-08-22 20:04:55 -07:00
/**
* this is start of real trigger cycle
* for virtual double trigger see timeAtVirtualZeroNt
*/
2016-08-20 19:02:12 -07:00
efitick_t startOfCycleNt;
2020-01-21 21:40:26 -08:00
uint32_t findTriggerZeroEventIndex(
TriggerWaveform& shape,
const TriggerConfiguration& triggerConfiguration
2020-08-23 23:07:58 -07:00
);
2020-01-21 21:40:26 -08:00
bool someSortOfTriggerError() const {
2022-09-20 09:39:16 -07:00
return !m_timeSinceDecodeError.hasElapsedSec(1);
}
protected:
// Called when some problem is detected with trigger decoding.
// That means either:
// - Too many events without a sync point
// - Saw a sync point but the wrong number of events in the cycle
virtual void onTriggerError() { }
virtual void onNotEnoughTeeth(int, int) { }
virtual void onTooManyTeeth(int, int) { }
2015-07-10 06:01:56 -07:00
private:
void setTriggerErrorState(int errorIncrement = 1);
2015-09-08 20:01:07 -07:00
void resetCurrentCycleState();
bool isSyncPoint(const TriggerWaveform& triggerShape, trigger_type_e triggerType) const;
2015-09-08 20:01:07 -07:00
bool validateEventCounters(const TriggerWaveform& triggerShape) const;
2015-07-10 06:01:56 -07:00
trigger_event_e prevSignal;
int64_t totalEventCountBase;
2021-12-09 18:59:51 -08:00
2015-07-10 06:01:56 -07:00
bool isFirstEvent;
Timer m_timeSinceDecodeError;
2015-07-10 06:01:56 -07:00
};
/**
* the reason for sub-class is simply to save RAM but not having statistics in the trigger initialization instance
*/
class PrimaryTriggerDecoder : public TriggerDecoderBase, public trigger_state_primary_s {
public:
PrimaryTriggerDecoder(const char* name);
void resetState() override;
void resetHasFullSync() {
// If this trigger doesn't need disambiguation, we already have phase sync
m_hasSynchronizedPhase = !m_needsDisambiguation;
}
angle_t syncEnginePhase(int divider, int remainder, angle_t engineCycle);
2022-05-09 12:46:36 -07:00
// Returns true if syncEnginePhase has been called,
// i.e. if we have enough VVT information to have full sync on
// an indeterminite crank pattern
bool hasSynchronizedPhase() const {
2022-05-09 21:52:29 -07:00
return m_hasSynchronizedPhase;
2022-05-09 12:46:36 -07:00
}
void setNeedsDisambiguation(bool needsDisambiguation) {
m_needsDisambiguation = needsDisambiguation;
resetHasFullSync();
}
void onTriggerError() override;
void onNotEnoughTeeth(int actual, int expected) override;
void onTooManyTeeth(int actual, int expected) override;
private:
bool m_needsDisambiguation = false;
2017-05-18 13:16:55 -07:00
};
class VvtTriggerDecoder : public TriggerDecoderBase {
public:
2023-11-01 06:48:33 -07:00
VvtTriggerDecoder(const char* p_name) : TriggerDecoderBase(p_name) { }
void onNotEnoughTeeth(int actual, int expected) override;
void onTooManyTeeth(int actual, int expected) override;
};
2022-05-10 01:41:39 -07:00
2016-01-14 21:01:42 -08:00
angle_t getEngineCycle(operation_mode_e operationMode);