trigger decoder returns a result (#4206)

This commit is contained in:
Matthew Kennedy 2022-05-28 06:01:45 -07:00 committed by GitHub
parent 52cb3204f5
commit 720c463ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 85 deletions

View File

@ -362,14 +362,6 @@ void mainTriggerCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp) {
}
#endif /* EFI_CDM_INTEGRATION */
if (trgEventIndex >= engine->engineCycleEventCount) {
/**
* this could happen in case of a trigger error, just exit silently since the trigger error is supposed to be handled already
* todo: should this check be somewhere higher so that no trigger listeners are invoked with noise?
*/
return;
}
int rpm = engine->rpmCalculator.getCachedRpm();
if (rpm == 0) {
// this happens while we just start cranking

View File

@ -587,6 +587,52 @@ bool TriggerNoiseFilter::noiseFilter(efitick_t nowNt,
return false;
}
void TriggerCentral::decodeMapCam(efitick_t timestamp, float currentPhase) {
#if WITH_TS_STATE
if (engineConfiguration->vvtMode[0] == VVT_MAP_V_TWIN_ANOTHER &&
Sensor::getOrZero(SensorType::Rpm) < engineConfiguration->cranking.rpm) {
// we are trying to figure out which 360 half of the total 720 degree cycle is which, so we compare those in 360 degree sense.
auto toothAngle360 = currentPhase;
while (toothAngle360 >= 360) {
toothAngle360 -= 360;
}
if (mapCamPrevToothAngle < engineConfiguration->mapCamDetectionAnglePosition && toothAngle360 > engineConfiguration->mapCamDetectionAnglePosition) {
// we are somewhere close to 'mapCamDetectionAnglePosition'
// warning: hack hack hack
float map = engine->outputChannels.instantMAPValue;
// Compute diff against the last time we were here
float diff = map - mapCamPrevCycleValue;
mapCamPrevCycleValue = map;
if (diff > 0) {
mapVvt_map_peak++;
int revolutionCounter = engine->triggerCentral.triggerState.getTotalRevolutionCounter();
mapVvt_MAP_AT_CYCLE_COUNT = revolutionCounter - prevChangeAtCycle;
prevChangeAtCycle = revolutionCounter;
hwHandleVvtCamSignal(TV_RISE, timestamp, /*index*/0);
hwHandleVvtCamSignal(TV_FALL, timestamp, /*index*/0);
#if EFI_UNIT_TEST
// hack? feature? existing unit test relies on VVT phase available right away
// but current implementation which is based on periodicFastCallback would only make result available on NEXT tooth
int rpm = Sensor::getOrZero(SensorType::Rpm);
efitick_t nowNt = getTimeNowNt();
engine->limpManager.updateState(rpm, nowNt);
#endif // EFI_UNIT_TEST
}
mapVvt_MAP_AT_SPECIAL_POINT = map;
mapVvt_MAP_AT_DIFF = diff;
}
mapCamPrevToothAngle = toothAngle360;
}
#endif // WITH_TS_STATE
}
/**
* This method is NOT invoked for VR falls.
*/
@ -617,11 +663,8 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
efiAssertVoid(CUSTOM_TRIGGER_EVENT_TYPE, eventIndex >= 0 && eventIndex < HW_EVENT_TYPES, "signal type");
hwEventCounters[eventIndex]++;
/**
* This invocation changes the state of triggerState
*/
triggerState.decodeTriggerEvent(
// Decode the trigger!
auto decodeResult = triggerState.decodeTriggerEvent(
"trigger",
triggerShape,
nullptr,
@ -629,33 +672,38 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
engine->primaryTriggerConfiguration,
signal, timestamp);
/**
* If we only have a crank position sensor with four stroke, here we are extending crank revolutions with a 360 degree
* cycle into a four stroke, 720 degrees cycle.
*/
operation_mode_e operationMode = engine->getOperationMode();
int crankDivider = getCrankDivider(operationMode);
int crankInternalIndex = triggerState.getTotalRevolutionCounter() % crankDivider;
int triggerIndexForListeners = triggerState.getCurrentIndex() + (crankInternalIndex * getTriggerSize());
if (triggerIndexForListeners == 0) {
m_syncPointTimer.reset(timestamp);
}
reportEventToWaveChart(signal, triggerIndexForListeners);
if (!triggerState.getShaftSynchronized()) {
// we should not propagate event if we do not know where we are
return;
}
if (triggerState.isValidIndex(engine->triggerCentral.triggerShape)) {
// Don't propagate state if we don't know where we are
if (decodeResult) {
ScopePerf perf(PE::ShaftPositionListeners);
/**
* If we only have a crank position sensor with four stroke, here we are extending crank revolutions with a 360 degree
* cycle into a four stroke, 720 degrees cycle.
*/
int crankDivider = getCrankDivider(engine->getOperationMode());
int crankInternalIndex = triggerState.getTotalRevolutionCounter() % crankDivider;
int triggerIndexForListeners = decodeResult.Value.CurrentIndex + (crankInternalIndex * getTriggerSize());
if (triggerIndexForListeners == 0) {
m_syncPointTimer.reset(timestamp);
}
reportEventToWaveChart(signal, triggerIndexForListeners);
// Compute the current engine absolute phase, 0 means currently at #1 TDC
auto currentPhase = engine->triggerCentral.triggerFormDetails.eventAngles[triggerIndexForListeners] - tdcPosition();
wrapAngle(currentPhase, "currentEnginePhase", CUSTOM_ERR_6555);
#if EFI_TUNER_STUDIO
engine->outputChannels.currentEnginePhase = currentPhase;
#endif // EFI_TUNER_STUDIO
#if TRIGGER_EXTREME_LOGGING
efiPrintf("trigger %d %d %d", triggerIndexForListeners, getRevolutionCounter(), (int)getTimeNowUs());
#endif /* TRIGGER_EXTREME_LOGGING */
// Update engine RPM
rpmShaftPositionCallback(signal, triggerIndexForListeners, timestamp);
// Schedule the TDC mark
tdcMarkCallback(triggerIndexForListeners, timestamp);
#if !EFI_UNIT_TEST
@ -668,57 +716,13 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
waTriggerEventListener(signal, triggerIndexForListeners, timestamp);
#endif
// Handle ignition and injection
mainTriggerCallback(triggerIndexForListeners, timestamp);
auto toothAngle = engine->triggerCentral.triggerFormDetails.eventAngles[triggerIndexForListeners] - tdcPosition();
wrapAngle(toothAngle, "currentEnginePhase", CUSTOM_ERR_6555);
#if EFI_TUNER_STUDIO
engine->outputChannels.currentEnginePhase = toothAngle;
#endif // EFI_TUNER_STUDIO
#if WITH_TS_STATE
if (engineConfiguration->vvtMode[0] == VVT_MAP_V_TWIN_ANOTHER &&
Sensor::getOrZero(SensorType::Rpm) < engineConfiguration->cranking.rpm) {
// we are trying to figure out which 360 half of the total 720 degree cycle is which, so we compare those in 360 degree sense.
auto toothAngle360 = toothAngle;
while (toothAngle360 >= 360) {
toothAngle360 -= 360;
}
if (mapCamPrevToothAngle < engineConfiguration->mapCamDetectionAnglePosition && toothAngle360 > engineConfiguration->mapCamDetectionAnglePosition) {
// we are somewhere close to 'mapCamDetectionAnglePosition'
// warning: hack hack hack
float map = engine->outputChannels.instantMAPValue;
// Compute diff against the last time we were here
float diff = map - mapCamPrevCycleValue;
mapCamPrevCycleValue = map;
if (diff > 0) {
mapVvt_map_peak++;
int revolutionCounter = engine->triggerCentral.triggerState.getTotalRevolutionCounter();
mapVvt_MAP_AT_CYCLE_COUNT = revolutionCounter - prevChangeAtCycle;
prevChangeAtCycle = revolutionCounter;
hwHandleVvtCamSignal(TV_RISE, timestamp, /*index*/0);
hwHandleVvtCamSignal(TV_FALL, timestamp, /*index*/0);
#if EFI_UNIT_TEST
// hack? feature? existing unit test relies on VVT phase available right away
// but current implementation which is based on periodicFastCallback would only make result available on NEXT tooth
int rpm = Sensor::getOrZero(SensorType::Rpm);
efitick_t nowNt = getTimeNowNt();
engine->limpManager.updateState(rpm, nowNt);
#endif // EFI_UNIT_TEST
}
mapVvt_MAP_AT_SPECIAL_POINT = map;
mapVvt_MAP_AT_DIFF = diff;
}
mapCamPrevToothAngle = toothAngle360;
}
#endif // WITH_TS_STATE
// Decode the MAP based "cam" sensor
decodeMapCam(timestamp, currentPhase);
} else {
reportEventToWaveChart(signal, 0);
}
}

View File

@ -122,6 +122,8 @@ public:
Timer m_lastEventTimer;
private:
void decodeMapCam(efitick_t nowNt, float currentPhase);
// Keep track of the last time we saw the sync tooth go by (trigger index 0)
// not TDC point
Timer m_syncPointTimer;

View File

@ -479,7 +479,7 @@ void TriggerDecoderBase::onShaftSynchronization(
* @param signal type of event which just happened
* @param nowNt current time
*/
void TriggerDecoderBase::decodeTriggerEvent(
expected<TriggerDecodeResult> TriggerDecoderBase::decodeTriggerEvent(
const char *msg,
const TriggerWaveform& triggerShape,
const TriggerStateCallback triggerCycleCallback,
@ -502,7 +502,7 @@ void TriggerDecoderBase::decodeTriggerEvent(
bool useOnlyRisingEdgeForTrigger = triggerConfiguration.UseOnlyRisingEdgeForTrigger;
efiAssertVoid(CUSTOM_TRIGGER_UNEXPECTED, signal <= SHAFT_3RD_RISING, "unexpected signal");
efiAssert(CUSTOM_TRIGGER_UNEXPECTED, signal <= SHAFT_3RD_RISING, "unexpected signal", unexpected);
trigger_wheel_e triggerWheel = eventIndex[signal];
trigger_value_e type = eventType[signal];
@ -727,7 +727,7 @@ void TriggerDecoderBase::decodeTriggerEvent(
setShaftSynchronized(false);
return;
return unexpected;
}
// Needed for early instant-RPM detection
@ -736,6 +736,12 @@ void TriggerDecoderBase::decodeTriggerEvent(
}
triggerStateIndex = currentCycle.current_index;
if (getShaftSynchronized()) {
return TriggerDecodeResult{ currentCycle.current_index };
} else {
return unexpected;
}
}
bool TriggerDecoderBase::isSyncPoint(const TriggerWaveform& triggerShape, trigger_type_e triggerType) const {

View File

@ -70,6 +70,10 @@ typedef struct {
#endif // EFI_UNIT_TEST
} current_cycle_state_s;
struct TriggerDecodeResult {
uint32_t CurrentIndex;
};
/**
* @see TriggerWaveform for trigger wheel shape definition
*/
@ -88,7 +92,7 @@ public:
efitime_t getTotalEventCounter() const;
void decodeTriggerEvent(
expected<TriggerDecodeResult> decodeTriggerEvent(
const char *msg,
const TriggerWaveform& triggerShape,
const TriggerStateCallback triggerCycleCallback,