2015-09-23 18:02:33 -07:00
|
|
|
/*
|
|
|
|
* @file trigger_simulator.cpp
|
|
|
|
*
|
|
|
|
* @date Sep 23, 2015
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2015-09-23 18:02:33 -07:00
|
|
|
*/
|
|
|
|
|
2021-07-25 22:05:17 -07:00
|
|
|
#include "pch.h"
|
|
|
|
|
2015-09-23 18:02:33 -07:00
|
|
|
#include "trigger_simulator.h"
|
2017-03-03 21:17:53 -08:00
|
|
|
#include "trigger_emulator_algo.h"
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2020-12-04 11:00:49 -08:00
|
|
|
#if EFI_UNIT_TEST
|
|
|
|
extern bool printTriggerTrace;
|
|
|
|
#endif
|
|
|
|
|
2017-03-03 21:17:53 -08:00
|
|
|
// this is not the only place where we have 'isUpEvent'. todo: reuse
|
2020-01-27 21:27:30 -08:00
|
|
|
static const bool isRisingEdge[HW_EVENT_TYPES] = { false, true, false, true, false, true };
|
2017-03-03 21:17:53 -08:00
|
|
|
|
2020-07-30 16:24:55 -07:00
|
|
|
/**
|
|
|
|
* todo: should this method be invoked somewhere deeper? at the moment we have too many usages too high
|
|
|
|
* @return true if front should be decoded further, false if we are not interested
|
|
|
|
*/
|
2022-09-25 15:49:54 -07:00
|
|
|
bool isUsefulSignal(trigger_event_e signal, const TriggerWaveform& shape) {
|
|
|
|
return !shape.useOnlyRisingEdges || isRisingEdge[(int) signal];
|
2017-03-03 21:17:53 -08:00
|
|
|
}
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_UNIT_TEST
|
2017-03-04 06:07:10 -08:00
|
|
|
extern bool printTriggerDebug;
|
|
|
|
#endif /* ! EFI_UNIT_TEST */
|
|
|
|
|
2021-06-25 09:50:19 -07:00
|
|
|
int getSimulatedEventTime(const TriggerWaveform& shape, int i) {
|
|
|
|
int stateIndex = i % shape.getSize();
|
|
|
|
int loopIndex = i / shape.getSize();
|
|
|
|
|
2021-11-21 01:56:07 -08:00
|
|
|
return (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape.wave.getSwitchTime(stateIndex)));
|
2021-06-25 09:50:19 -07:00
|
|
|
}
|
|
|
|
|
2020-10-05 11:22:59 -07:00
|
|
|
void TriggerStimulatorHelper::feedSimulatedEvent(
|
|
|
|
const TriggerConfiguration& triggerConfiguration,
|
2022-05-10 01:41:39 -07:00
|
|
|
TriggerDecoderBase& state,
|
2020-10-05 11:22:59 -07:00
|
|
|
const TriggerWaveform& shape,
|
|
|
|
int i
|
2020-08-23 23:23:13 -07:00
|
|
|
) {
|
2023-04-11 17:01:34 -07:00
|
|
|
efiAssertVoid(ObdCode::CUSTOM_ERR_6593, shape.getSize() > 0, "size not zero");
|
2020-10-05 11:22:59 -07:00
|
|
|
int stateIndex = i % shape.getSize();
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2021-06-25 09:50:19 -07:00
|
|
|
int time = getSimulatedEventTime(shape, i);
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2021-11-21 01:56:07 -08:00
|
|
|
const auto & multiChannelStateSequence = shape.wave;
|
2019-04-14 10:52:27 -07:00
|
|
|
|
|
|
|
#if EFI_UNIT_TEST
|
2020-10-05 11:22:59 -07:00
|
|
|
int prevIndex = getPreviousIndex(stateIndex, shape.getSize());
|
2019-04-14 10:52:27 -07:00
|
|
|
|
2020-10-05 11:22:59 -07:00
|
|
|
pin_state_t primaryWheelState = multiChannelStateSequence.getChannelState(0, prevIndex);
|
|
|
|
pin_state_t newPrimaryWheelState = multiChannelStateSequence.getChannelState(0, stateIndex);
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2020-10-05 11:22:59 -07:00
|
|
|
pin_state_t secondaryWheelState = multiChannelStateSequence.getChannelState(1, prevIndex);
|
|
|
|
pin_state_t newSecondaryWheelState = multiChannelStateSequence.getChannelState(1, stateIndex);
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2019-12-03 22:11:10 -08:00
|
|
|
// pin_state_t thirdWheelState = multiChannelStateSequence->getChannelState(2, prevIndex);
|
|
|
|
// pin_state_t new3rdWheelState = multiChannelStateSequence->getChannelState(2, stateIndex);
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2017-03-04 06:07:10 -08:00
|
|
|
if (printTriggerDebug) {
|
2020-07-19 11:17:15 -07:00
|
|
|
printf("TriggerStimulator: simulatedEvent: %d>%d primary %d>%d secondary %d>%d\r\n", prevIndex, stateIndex, primaryWheelState, newPrimaryWheelState,
|
2017-03-04 06:07:10 -08:00
|
|
|
secondaryWheelState, newSecondaryWheelState );
|
|
|
|
}
|
|
|
|
#endif /* EFI_UNIT_TEST */
|
|
|
|
|
|
|
|
|
2017-03-03 21:08:56 -08:00
|
|
|
// todo: code duplication with TriggerEmulatorHelper::handleEmulatorCallback?
|
|
|
|
|
2022-06-01 18:24:20 -07:00
|
|
|
constexpr trigger_event_e riseEvents[] = { SHAFT_PRIMARY_RISING, SHAFT_SECONDARY_RISING };
|
|
|
|
constexpr trigger_event_e fallEvents[] = { SHAFT_PRIMARY_FALLING, SHAFT_SECONDARY_FALLING };
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2021-06-25 07:55:46 -07:00
|
|
|
for (size_t i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
|
2021-11-10 16:47:27 -08:00
|
|
|
if (needEvent(stateIndex, multiChannelStateSequence, i)) {
|
2021-06-25 07:55:46 -07:00
|
|
|
pin_state_t currentValue = multiChannelStateSequence.getChannelState(/*phaseIndex*/i, stateIndex);
|
2022-09-10 23:57:35 -07:00
|
|
|
trigger_event_e event = (currentValue == TriggerValue::RISE ? riseEvents : fallEvents)[i];
|
2022-09-25 15:49:54 -07:00
|
|
|
if (isUsefulSignal(event, shape)) {
|
2022-03-21 17:39:47 -07:00
|
|
|
state.decodeTriggerEvent(
|
|
|
|
"sim",
|
|
|
|
shape,
|
2019-12-05 22:57:11 -08:00
|
|
|
/* override */ nullptr,
|
2020-08-23 22:21:42 -07:00
|
|
|
triggerConfiguration,
|
2020-08-26 14:30:13 -07:00
|
|
|
event, time);
|
2021-06-25 07:55:46 -07:00
|
|
|
}
|
2019-12-05 22:57:11 -08:00
|
|
|
}
|
2015-09-23 18:02:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-30 19:39:57 -07:00
|
|
|
void TriggerStimulatorHelper::assertSyncPosition(
|
2020-10-05 11:22:59 -07:00
|
|
|
const TriggerConfiguration& triggerConfiguration,
|
|
|
|
const uint32_t syncIndex,
|
2022-05-10 01:41:39 -07:00
|
|
|
TriggerDecoderBase& state,
|
2020-10-05 11:22:59 -07:00
|
|
|
TriggerWaveform& shape
|
2020-08-23 23:23:13 -07:00
|
|
|
) {
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2020-12-04 13:03:27 -08:00
|
|
|
// todo: is anything limiting this TEST_REVOLUTIONS? why does value '8' not work for example?
|
|
|
|
#define TEST_REVOLUTIONS 6
|
|
|
|
|
2018-02-05 14:41:05 -08:00
|
|
|
/**
|
|
|
|
* let's feed two more cycles to validate shape definition
|
|
|
|
*/
|
2020-12-04 13:03:27 -08:00
|
|
|
for (uint32_t i = syncIndex + 1; i <= syncIndex + TEST_REVOLUTIONS * shape.getSize(); i++) {
|
2022-05-30 19:39:57 -07:00
|
|
|
feedSimulatedEvent(triggerConfiguration, state, shape, i);
|
2015-09-23 18:02:33 -07:00
|
|
|
}
|
2022-05-30 19:39:57 -07:00
|
|
|
|
2022-09-07 19:24:28 -07:00
|
|
|
int revolutionCounter = state.getCrankSynchronizationCounter();
|
2021-11-20 22:01:27 -08:00
|
|
|
if (revolutionCounter != TEST_REVOLUTIONS) {
|
2023-04-11 17:01:34 -07:00
|
|
|
warning(ObdCode::CUSTOM_OBD_TRIGGER_WAVEFORM, "sync failed/wrong gap parameters trigger=%s revolutionCounter=%d",
|
2022-05-30 16:36:47 -07:00
|
|
|
getTrigger_type_e(triggerConfiguration.TriggerType.type),
|
2021-01-03 21:26:05 -08:00
|
|
|
revolutionCounter);
|
2020-10-05 11:22:59 -07:00
|
|
|
shape.setShapeDefinitionError(true);
|
2016-01-24 15:01:56 -08:00
|
|
|
return;
|
|
|
|
}
|
2020-10-05 11:22:59 -07:00
|
|
|
shape.shapeDefinitionError = false;
|
2020-12-04 11:00:49 -08:00
|
|
|
#if EFI_UNIT_TEST
|
|
|
|
if (printTriggerTrace) {
|
|
|
|
printf("Happy %s revolutionCounter=%d\r\n",
|
2022-05-30 16:36:47 -07:00
|
|
|
getTrigger_type_e(triggerConfiguration.TriggerType.type),
|
2020-12-04 11:00:49 -08:00
|
|
|
revolutionCounter);
|
|
|
|
}
|
|
|
|
#endif /* EFI_UNIT_TEST */
|
2015-09-23 18:02:33 -07:00
|
|
|
}
|
|
|
|
|
2017-03-04 06:07:10 -08:00
|
|
|
/**
|
|
|
|
* @return trigger synchronization point index, or error code if not found
|
|
|
|
*/
|
2022-11-05 21:10:50 -07:00
|
|
|
expected<uint32_t> TriggerStimulatorHelper::findTriggerSyncPoint(
|
2020-10-05 11:22:59 -07:00
|
|
|
TriggerWaveform& shape,
|
|
|
|
const TriggerConfiguration& triggerConfiguration,
|
2022-05-10 01:41:39 -07:00
|
|
|
TriggerDecoderBase& state) {
|
2015-09-23 18:02:33 -07:00
|
|
|
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
|
2022-05-30 19:39:57 -07:00
|
|
|
feedSimulatedEvent(triggerConfiguration, state, shape, i);
|
2015-09-23 18:02:33 -07:00
|
|
|
|
2021-07-03 07:37:03 -07:00
|
|
|
if (state.getShaftSynchronized()) {
|
2015-09-23 18:02:33 -07:00
|
|
|
return i;
|
2020-01-26 11:20:55 -08:00
|
|
|
}
|
2015-09-23 18:02:33 -07:00
|
|
|
}
|
2020-10-05 11:22:59 -07:00
|
|
|
shape.setShapeDefinitionError(true);
|
2022-11-08 18:48:39 -08:00
|
|
|
|
2023-06-01 11:43:41 -07:00
|
|
|
if (engineConfiguration->overrideTriggerGaps) {
|
|
|
|
firmwareError(ObdCode::CUSTOM_ERR_CUSTOM_GAPS_BAD, "The custom trigger gaps are invalid for the current trigger type.");
|
2023-01-04 10:15:45 -08:00
|
|
|
} else {
|
2023-06-01 11:43:41 -07:00
|
|
|
firmwareError(ObdCode::CUSTOM_ERR_TRIGGER_SYNC, "findTriggerZeroEventIndex() failed");
|
2023-01-04 10:15:45 -08:00
|
|
|
}
|
2022-11-05 21:10:50 -07:00
|
|
|
return unexpected;
|
2015-09-23 18:02:33 -07:00
|
|
|
}
|