rusefi-1/firmware/controllers/trigger/trigger_simulator.cpp

123 lines
4.9 KiB
C++
Raw Normal View History

2015-09-23 18:02:33 -07:00
/*
* @file trigger_simulator.cpp
*
* @date Sep 23, 2015
2018-01-20 17:55:31 -08:00
* @author Andrey Belomutskiy, (c) 2012-2018
2015-09-23 18:02:33 -07:00
*/
2018-09-16 19:26:57 -07:00
#include "global.h"
2015-09-23 18:02:33 -07:00
#include "engine.h"
#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
#define SIMULATION_CYCLE_PERIOD 720000
EXTERN_ENGINE;
2017-03-03 21:17:53 -08:00
// this is not the only place where we have 'isUpEvent'. todo: reuse
2019-01-13 20:05:03 -08:00
static const bool isRisingEdge[6] = { false, true, false, true, false, true };
2017-03-03 21:17:53 -08:00
2017-10-16 11:01:39 -07:00
// todo: should this method be invoked somewhere deeper? at the moment we have too many usages too high
2019-11-07 08:28:49 -08:00
bool isUsefulSignal(trigger_event_e signal DECLARE_ENGINE_PARAMETER_SUFFIX) {
2017-03-03 21:17:53 -08:00
return !engineConfiguration->useOnlyRisingEdgeForTrigger || isRisingEdge[(int) signal];
}
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 */
void TriggerStimulatorHelper::feedSimulatedEvent(const TriggerStateCallback triggerCycleCallback,
TriggerState *state, TriggerShape * shape, int i
2018-02-05 14:41:05 -08:00
DECLARE_ENGINE_PARAMETER_SUFFIX) {
2018-07-25 20:03:04 -07:00
efiAssertVoid(CUSTOM_ERR_6593, shape->getSize() > 0, "size not zero");
2015-09-23 18:02:33 -07:00
int stateIndex = i % shape->getSize();
2019-03-03 22:10:31 -08:00
int size = shape->getSize();
2015-09-23 18:02:33 -07:00
int loopIndex = i / shape->getSize();
int time = (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
MultiChannelStateSequence *multiChannelStateSequence = &shape->wave;
2019-04-14 10:52:27 -07:00
#if EFI_UNIT_TEST
int prevIndex = getPreviousIndex(stateIndex, shape->getSize());
pin_state_t primaryWheelState = multiChannelStateSequence->getChannelState(0, prevIndex);
pin_state_t newPrimaryWheelState = multiChannelStateSequence->getChannelState(0, stateIndex);
2015-09-23 18:02:33 -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
// 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) {
2018-02-05 14:41:05 -08:00
printf("feedSimulatedEvent: %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?
if (needEvent(stateIndex, size, multiChannelStateSequence, 0)) {
pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/0, stateIndex);
2019-03-03 22:10:31 -08:00
trigger_event_e s = currentValue ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING;
2019-11-07 08:28:49 -08:00
if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX))
state->decodeTriggerEvent(triggerCycleCallback, s, time PASS_ENGINE_PARAMETER_SUFFIX);
2015-09-23 18:02:33 -07:00
}
if (needEvent(stateIndex, size, multiChannelStateSequence, 1)) {
pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/1, stateIndex);
2019-03-03 22:10:31 -08:00
trigger_event_e s = currentValue ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING;
2019-11-07 08:28:49 -08:00
if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX))
state->decodeTriggerEvent(triggerCycleCallback, s, time PASS_ENGINE_PARAMETER_SUFFIX);
2015-09-23 18:02:33 -07:00
}
if (needEvent(stateIndex, size, multiChannelStateSequence, 2)) {
pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/2, stateIndex);
2019-03-03 22:10:31 -08:00
trigger_event_e s = currentValue ? SHAFT_3RD_RISING : SHAFT_3RD_FALLING;
2019-11-07 08:28:49 -08:00
if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX))
state->decodeTriggerEvent(triggerCycleCallback, s, time PASS_ENGINE_PARAMETER_SUFFIX);
2015-09-23 18:02:33 -07:00
}
}
void TriggerStimulatorHelper::assertSyncPositionAndSetDutyCycle(const TriggerStateCallback triggerCycleCallback,
const uint32_t syncIndex, TriggerState *state, TriggerShape * shape
2018-02-05 14:44:10 -08:00
DECLARE_ENGINE_PARAMETER_SUFFIX) {
2015-09-23 18:02:33 -07:00
2018-02-05 14:41:05 -08:00
/**
* let's feed two more cycles to validate shape definition
*/
2018-10-28 14:20:43 -07:00
for (uint32_t i = syncIndex + 1; i <= syncIndex + GAP_TRACKING_LENGTH * shape->getSize(); i++) {
feedSimulatedEvent(triggerCycleCallback, state, shape, i PASS_ENGINE_PARAMETER_SUFFIX);
2015-09-23 18:02:33 -07:00
}
2017-03-04 05:35:22 -08:00
int revolutionCounter = state->getTotalRevolutionCounter();
2018-10-28 14:20:43 -07:00
if (revolutionCounter != GAP_TRACKING_LENGTH + 1) {
2017-03-04 05:35:22 -08:00
warning(CUSTOM_OBD_TRIGGER_SHAPE, "sync failed/wrong gap parameters trigger=%s rc=%d", getTrigger_type_e(engineConfiguration->trigger.type), revolutionCounter);
shape->setShapeDefinitionError(true);
2016-01-24 15:01:56 -08:00
return;
}
2017-03-01 19:37:10 -08:00
shape->shapeDefinitionError = false;
2015-09-23 18:02:33 -07:00
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
2018-02-05 14:16:34 -08:00
shape->expectedDutyCycle[i] = 1.0 * state->expectedTotalTime[i] / SIMULATION_CYCLE_PERIOD;
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
*/
2018-02-05 14:41:05 -08:00
uint32_t TriggerStimulatorHelper::findTriggerSyncPoint(TriggerShape * shape,
TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX) {
2015-09-23 18:02:33 -07:00
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
feedSimulatedEvent(nullptr, state, shape, i PASS_ENGINE_PARAMETER_SUFFIX);
2015-09-23 18:02:33 -07:00
if (state->shaft_is_synchronized)
return i;
}
engine->triggerCentral.triggerShape.setShapeDefinitionError(true);
2017-03-06 14:31:20 -08:00
warning(CUSTOM_ERR_TRIGGER_SYNC, "findTriggerZeroEventIndex() failed");
2015-09-23 18:02:33 -07:00
return EFI_ERROR_CODE;
}