rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
trigger_simulator.cpp
Go to the documentation of this file.
1/*
2 * @file trigger_simulator.cpp
3 *
4 * @date Sep 23, 2015
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 */
7
8#include "pch.h"
9
10#include "trigger_simulator.h"
12
13#if EFI_UNIT_TEST
14 extern bool printTriggerTrace;
15#endif
16
17/**
18 * todo: should this method be invoked somewhere deeper? at the moment we have too many usages too high
19 * @return true if front should be decoded further, false if we are not interested
20 */
22 if (shape.useOnlyRisingEdges) {
23 return isTriggerUpEvent(signal);
24 }
25
26 // consider both edges, so all edges are useful
27 return true;
28}
29
30#if EFI_UNIT_TEST
31extern bool printTriggerDebug;
32#endif /* ! EFI_UNIT_TEST */
33
34int getSimulatedEventTime(const TriggerWaveform& shape, int i) {
35 int stateIndex = i % shape.getSize();
36 int loopIndex = i / shape.getSize();
37
38 return (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape.wave.getSwitchTime(stateIndex)));
39}
40
42 const TriggerConfiguration& triggerConfiguration,
44 const TriggerWaveform& shape,
45 int index
46 ) {
47 efiAssertVoid(ObdCode::CUSTOM_ERR_6593, shape.getSize() > 0, "size not zero");
48 int stateIndex = index % shape.getSize();
49
50 int time = getSimulatedEventTime(shape, index);
51
52 const auto & multiChannelStateSequence = shape.wave;
53
54#if EFI_UNIT_TEST
55 int prevIndex = getPreviousIndex(stateIndex, shape.getSize());
56
57 pin_state_t primaryWheelState = multiChannelStateSequence.getChannelState(0, prevIndex);
58 pin_state_t newPrimaryWheelState = multiChannelStateSequence.getChannelState(0, stateIndex);
59
60 pin_state_t secondaryWheelState = multiChannelStateSequence.getChannelState(1, prevIndex);
61 pin_state_t newSecondaryWheelState = multiChannelStateSequence.getChannelState(1, stateIndex);
62
63// pin_state_t thirdWheelState = multiChannelStateSequence->getChannelState(2, prevIndex);
64// pin_state_t new3rdWheelState = multiChannelStateSequence->getChannelState(2, stateIndex);
65
67 printf("TriggerStimulator: simulatedEvent: %d>%d primary %d>%d secondary %d>%d\r\n", prevIndex, stateIndex, primaryWheelState, newPrimaryWheelState,
68 secondaryWheelState, newSecondaryWheelState );
69 }
70#endif /* EFI_UNIT_TEST */
71
72
73 // todo: code duplication with TriggerEmulatorHelper::handleEmulatorCallback?
74
77
78 for (size_t i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
79 if (needEvent(stateIndex, multiChannelStateSequence, i)) {
80 pin_state_t currentValue = multiChannelStateSequence.getChannelState(/*phaseIndex*/i, stateIndex);
81 trigger_event_e event = (currentValue == TriggerValue::RISE ? riseEvents : fallEvents)[i];
82 if (isUsefulSignal(event, shape)) {
83 state.decodeTriggerEvent(
84 "sim",
85 shape,
86 /* override */ nullptr,
87 triggerConfiguration,
88 event, time);
89 }
90 }
91 }
92}
93
95 const TriggerConfiguration& triggerConfiguration,
96 const uint32_t syncIndex,
98 TriggerWaveform& shape
99 ) {
100
101// todo: is anything limiting this TEST_REVOLUTIONS? why does value '8' not work for example?
102#define TEST_REVOLUTIONS 6
103
104 /**
105 * let's feed two more cycles to validate shape definition
106 */
107 for (uint32_t i = syncIndex + 1; i <= syncIndex + TEST_REVOLUTIONS * shape.getSize(); i++) {
108 feedSimulatedEvent(triggerConfiguration, state, shape, i);
109 }
110
111 int revolutionCounter = state.getSynchronizationCounter();
112 if (revolutionCounter != TEST_REVOLUTIONS) {
113 warning(ObdCode::CUSTOM_OBD_TRIGGER_WAVEFORM, "sync failed/wrong gap parameters trigger=%s revolutionCounter=%d",
114 getTrigger_type_e(triggerConfiguration.TriggerType.type),
115 revolutionCounter);
116 shape.setShapeDefinitionError(true);
117 return;
118 }
119 shape.shapeDefinitionError = false;
120#if EFI_UNIT_TEST
121 if (printTriggerTrace) {
122 printf("Happy %s revolutionCounter=%d\r\n",
123 getTrigger_type_e(triggerConfiguration.TriggerType.type),
124 revolutionCounter);
125 }
126#endif /* EFI_UNIT_TEST */
127}
128
129/**
130 * @return trigger synchronization point index, or error code if not found
131 */
133 TriggerWaveform& shape,
134 const TriggerConfiguration& triggerConfiguration,
136 for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
137 feedSimulatedEvent(triggerConfiguration, state, shape, i);
138
139 if (state.getShaftSynchronized()) {
140 return i;
141 }
142 }
143 shape.setShapeDefinitionError(true);
144
146 firmwareError(ObdCode::CUSTOM_ERR_CUSTOM_GAPS_BAD, "The custom trigger gaps are invalid for the current trigger type.");
147 } else {
148 firmwareError(ObdCode::CUSTOM_ERR_TRIGGER_SYNC, "findTriggerZeroEventIndex() failed");
149 }
150 return unexpected;
151}
const char * getTrigger_type_e(trigger_type_e value)
float getSwitchTime(int phaseIndex) const override
trigger_config_s TriggerType
static expected< uint32_t > findTriggerSyncPoint(TriggerWaveform &shape, const TriggerConfiguration &triggerConfiguration, TriggerDecoderBase &state)
static void feedSimulatedEvent(const TriggerConfiguration &triggerConfiguration, TriggerDecoderBase &state, const TriggerWaveform &shape, int i)
static void assertSyncPosition(const TriggerConfiguration &triggerConfiguration, const uint32_t index, TriggerDecoderBase &state, TriggerWaveform &shape)
Trigger shape has all the fields needed to describe and decode trigger signal.
void setShapeDefinitionError(bool value)
MultiChannelStateSequenceWithData< PWM_PHASE_MAX_COUNT > wave
size_t getSize() const
static constexpr engine_configuration_s * engineConfiguration
bool warning(ObdCode code, const char *fmt,...)
void firmwareError(ObdCode code, const char *fmt,...)
@ CUSTOM_ERR_6593
@ CUSTOM_ERR_CUSTOM_GAPS_BAD
@ CUSTOM_OBD_TRIGGER_WAVEFORM
@ CUSTOM_ERR_TRIGGER_SYNC
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
trigger_event_e
@ SHAFT_SECONDARY_RISING
@ SHAFT_SECONDARY_FALLING
@ SHAFT_PRIMARY_FALLING
@ SHAFT_PRIMARY_RISING
TriggerValue
constexpr bool isTriggerUpEvent(trigger_event_e event)
bool printTriggerTrace
int getPreviousIndex(const int currentIndex, const int size)
bool needEvent(const int currentIndex, const MultiChannelStateSequence &mcss, int channelIndex)
int getSimulatedEventTime(const TriggerWaveform &shape, int i)
bool printTriggerTrace
bool printTriggerDebug
bool isUsefulSignal(trigger_event_e signal, const TriggerWaveform &shape)
int getSimulatedEventTime(const TriggerWaveform &shape, int i)
bool isUsefulSignal(trigger_event_e signal, const TriggerWaveform &shape)
bool printTriggerDebug
printf("\n")