rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions | Variables
trigger_emulator_algo.cpp File Reference

Detailed Description

This file is about producing real electrical signals which emulate trigger signal based on a known TriggerWaveform.

Historically this implementation was implemented based on PwmConfig which is maybe not the best way to implement it. (todo: why is not the best way?)

A newer implementation of pretty much the same thing is TriggerStimulatorHelper todo: one emulator should be enough! another one should be eliminated

Date
Mar 3, 2014
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file trigger_emulator_algo.cpp.

Functions

int getPreviousIndex (const int currentIndex, const int size)
 
bool needEvent (const int currentIndex, const MultiChannelStateSequence &mcss, int channelIndex)
 
 fail ("EFI_SHAFT_POSITION_INPUT required to have EFI_EMULATE_POSITION_SENSORS") TriggerEmulatorHelper
 
static float getRpmMultiplier (operation_mode_e mode)
 
void setTriggerEmulatorRPM (int rpm)
 
static void updateTriggerWaveformIfNeeded (PwmConfig *state)
 
PUBLIC_API_WEAK void onTriggerEmulatorPinState (int, int)
 
static void emulatorApplyPinState (int stateIndex, PwmConfig *state)
 
static void startSimulatedTriggerSignal ()
 
void enableTriggerStimulator (bool incGlobalConfiguration)
 
void enableExternalTriggerStimulator ()
 
void disableTriggerStimulator ()
 
void onConfigurationChangeRpmEmulatorCallback (engine_configuration_s *previousConfiguration)
 
void initTriggerEmulator ()
 
void startTriggerEmulatorPins ()
 
void stopTriggerEmulatorPins ()
 

Variables

static OutputPin emulatorOutputs [NUM_EMULATOR_CHANNELS][PWM_PHASE_MAX_WAVE_PER_PWM]
 
PwmConfig triggerEmulatorSignals [NUM_EMULATOR_CHANNELS]
 
TriggerWaveformtriggerEmulatorWaveforms [NUM_EMULATOR_CHANNELS]
 
static int atTriggerVersions [NUM_EMULATOR_CHANNELS] = { 0 }
 
static TriggerEmulatorHelper helper
 
static bool hasStimPins = false
 
static bool hasInitTriggerEmulator = false
 

Function Documentation

◆ disableTriggerStimulator()

void disableTriggerStimulator ( )

Definition at line 222 of file trigger_emulator_algo.cpp.

222 {
224 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
226 }
229}
uint16_t channel
Definition adc_inputs.h:104
TriggerCentral triggerCentral
Definition engine.h:318
static EngineAccessor engine
Definition engine.h:413
void incrementGlobalConfigurationVersion(const char *msg)
PwmConfig triggerEmulatorSignals[NUM_EMULATOR_CHANNELS]
static bool hasInitTriggerEmulator

Referenced by configureRusefiLuaHooks(), enableOrDisable(), and handleCommandX14().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ emulatorApplyPinState()

static void emulatorApplyPinState ( int  stateIndex,
PwmConfig state 
)
static

this callback would invoke the input signal handlers directly

Definition at line 147 of file trigger_emulator_algo.cpp.

147 {
148 assertStackVoid("emulator", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK);
150 /**
151 * this callback would invoke the input signal handlers directly
152 */
153 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
155 continue;
157 *state->multiChannelStateSequence,
158 stateIndex);
159 }
160 }
161
162#if EFI_PROD_CODE
163 // Only set pins if they're configured - no need to waste the cycles otherwise
164 else if (hasStimPins) {
165 applyPinState(stateIndex, state);
166
167 // this allows any arbitrary code to synchronize with the trigger emulator
168 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
170 continue;
172 }
173 }
174#endif /* EFI_PROD_CODE */
175}
void handleEmulatorCallback(int channel, const MultiChannelStateSequence &mcss, int stateIndex)
@ STACK_USAGE_MISC
void applyPinState(int stateIndex, PwmConfig *state)
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
static bool hasStimPins
static TriggerEmulatorHelper helper
PUBLIC_API_WEAK void onTriggerEmulatorPinState(int, int)

Referenced by startSimulatedTriggerSignal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enableExternalTriggerStimulator()

void enableExternalTriggerStimulator ( )

Definition at line 216 of file trigger_emulator_algo.cpp.

216 {
220}
static void startSimulatedTriggerSignal()

Referenced by enableOrDisable(), and handleCommandX14().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enableTriggerStimulator()

void enableTriggerStimulator ( bool  incGlobalConfiguration)

Definition at line 205 of file trigger_emulator_algo.cpp.

205 {
209 if (incGlobalConfiguration) {
211 }
212}
RpmCalculator rpmCalculator
Definition engine.h:306
bool Register()
Definition sensor.cpp:131

Referenced by configureRusefiLuaHooks(), enableOrDisable(), and handleCommandX14().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fail()

fail ( "EFI_SHAFT_POSITION_INPUT required to have EFI_EMULATE_POSITION_SENSORS"  )

this instance does not have a real physical pin - it's only used for engine sniffer

todo: we can kind of add real physical pin just for a very narrow case of troubleshooting but only if we ever need it :)

Engine idles around 20Hz and revs up to 140Hz, at 60/2 and 8 cylinders we have about 20Khz events If we can read buffer at 50Hz we want buffer to be about 400 elements.

Definition at line 34 of file trigger_emulator_algo.cpp.

41 {
42}

◆ getPreviousIndex()

int getPreviousIndex ( const int  currentIndex,
const int  size 
)

Definition at line 19 of file trigger_emulator_algo.cpp.

19 {
20 return (currentIndex + size - 1) % size;
21}
composite packet size

Referenced by TriggerStimulatorHelper::feedSimulatedEvent(), and needEvent().

Here is the caller graph for this function:

◆ getRpmMultiplier()

static float getRpmMultiplier ( operation_mode_e  mode)
static

todo: why is this method NOT reciprocal to getCrankDivider?! todo: oh this method has only one usage? there must me another very similar method!

Definition at line 78 of file trigger_emulator_algo.cpp.

78 {
79 switch (mode) {
86 case OM_NONE:
87 return getCrankDivider(mode) / 2.0;
88 case TWO_STROKE:
89 // unit test coverage still runs if the value below is changed to '2' not a great sign!
90 // but HW CI insists that we have '1' here
91 return 1;
92 };
93 criticalError("We should not have reach this line");
94 return 1;
95}
@ FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR
@ FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR
@ FOUR_STROKE_THREE_TIMES_CRANK_SENSOR
@ FOUR_STROKE_CRANK_SENSOR
@ OM_NONE
@ FOUR_STROKE_CAM_SENSOR
@ TWO_STROKE
@ FOUR_STROKE_SIX_TIMES_CRANK_SENSOR
int getCrankDivider(operation_mode_e operationMode)

Referenced by setTriggerEmulatorRPM().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initTriggerEmulator()

void initTriggerEmulator ( )

Definition at line 239 of file trigger_emulator_algo.cpp.

239 {
240 efiPrintf("Emulating %s", getEngine_type_e(engineConfiguration->engineType));
241
243
245}
const char * getEngine_type_e(engine_type_e value)
void addConsoleActionI(const char *token, VoidInt callback)
Register a console command with one Integer parameter.
static constexpr engine_configuration_s * engineConfiguration
void setTriggerEmulatorRPM(int rpm)
void startTriggerEmulatorPins()

Referenced by initEngineEmulator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ needEvent()

bool needEvent ( const int  currentIndex,
const MultiChannelStateSequence mcss,
int  channelIndex 
)

Definition at line 23 of file trigger_emulator_algo.cpp.

23 {
24 int prevIndex = getPreviousIndex(currentIndex, mcss.phaseCount);
25 pin_state_t previousValue = mcss.getChannelState(channelIndex, /*phaseIndex*/prevIndex);
26 pin_state_t currentValue = mcss.getChannelState(channelIndex, /*phaseIndex*/currentIndex);
27
28 return previousValue != currentValue;
29}
virtual pin_state_t getChannelState(int channelIndex, int phaseIndex) const =0
TriggerValue
int getPreviousIndex(const int currentIndex, const int size)

Referenced by TriggerStimulatorHelper::feedSimulatedEvent(), and TriggerEmulatorHelper::handleEmulatorCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onConfigurationChangeRpmEmulatorCallback()

void onConfigurationChangeRpmEmulatorCallback ( engine_configuration_s previousConfiguration)

Definition at line 231 of file trigger_emulator_algo.cpp.

Referenced by incrementGlobalConfigurationVersion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onTriggerEmulatorPinState()

PUBLIC_API_WEAK void onTriggerEmulatorPinState ( int  ,
int   
)

Definition at line 142 of file trigger_emulator_algo.cpp.

142{ }

Referenced by emulatorApplyPinState().

Here is the caller graph for this function:

◆ setTriggerEmulatorRPM()

void setTriggerEmulatorRPM ( int  rpm)

All we need to do here is to change the periodMs togglePwmState() would see that the periodMs has changed and act accordingly

Definition at line 97 of file trigger_emulator_algo.cpp.

97 {
98 criticalAssertVoid(rpm >= 0 && rpm <= 30000, "emulator RPM out of range");
99
101 /**
102 * All we need to do here is to change the periodMs
103 * togglePwmState() would see that the periodMs has changed and act accordingly
104 */
105 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
106 float rPerSecond = NAN;
107 if (rpm != 0) {
108 // use 0.5 multiplier for cam
109 float rpmM = (channel == 0) ? getRpmMultiplier(getEngineRotationState()->getOperationMode()) : 0.5f;
110 rPerSecond = rpm * rpmM / 60.0; // per minute converted to per second
111 }
113 }
114
116
117 efiPrintf("Emulating position sensor(s). RPM=%d", rpm);
118}
void resetEngineSnifferIfInTestMode()
Definition engine.cpp:53
virtual operation_mode_e getOperationMode() const =0
void setFrequency(float frequency)
EngineRotationState * getEngineRotationState()
Definition engine.cpp:573
static float getRpmMultiplier(operation_mode_e mode)

Referenced by configureRusefiLuaHooks(), initTriggerEmulator(), onConfigurationChangeRpmEmulatorCallback(), setValue(), and startSimulatedTriggerSignal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startSimulatedTriggerSignal()

static void startSimulatedTriggerSignal ( )
static

Definition at line 177 of file trigger_emulator_algo.cpp.

177 {
178 // No need to start more than once
180 return;
181 }
182
183 // store the crank+cam waveforms
185 for (int cami = 0; cami < CAMS_PER_BANK; cami++) {
187 }
188
190
191 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
193 if (s->getSize() == 0)
194 continue;
197 &s->wave,
199 }
201}
SingleTimerExecutor scheduler
Definition engine.h:271
void weComplexInit(Scheduler *executor, MultiChannelStateSequence const *seq, pwm_cycle_callback *pwmCycleCallback, pwm_gen_callback *callback)
TriggerWaveform vvtShape[CAMS_PER_BANK]
TriggerWaveform triggerShape
Trigger shape has all the fields needed to describe and decode trigger signal.
MultiChannelStateSequenceWithData< PWM_PHASE_MAX_COUNT > wave
size_t getSize() const
static void emulatorApplyPinState(int stateIndex, PwmConfig *state)
static void updateTriggerWaveformIfNeeded(PwmConfig *state)
TriggerWaveform * triggerEmulatorWaveforms[NUM_EMULATOR_CHANNELS]

Referenced by enableExternalTriggerStimulator(), and enableTriggerStimulator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startTriggerEmulatorPins()

void startTriggerEmulatorPins ( )

Definition at line 249 of file trigger_emulator_algo.cpp.

249 {
250 hasStimPins = false;
251 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
252 for (size_t i = 0; i < efi::size(emulatorOutputs[channel]); i++) {
254
255#if EFI_PROD_CODE
257
258 pin_output_mode_e outputMode;
259 if (channel == 0) {
262 } else if (channel == 1 && i == 0) {
265 } else {
266 // todo: add pin configs for cam simulator channels
267 continue;
268 }
269
270 // Only bother trying to set output pins if they're configured
271 if (isBrainPinValid(pin)) {
272 hasStimPins = true;
273 }
274
275 if (isConfigurationChanged(triggerSimulatorPins[i])) {
276 triggerEmulatorSignals[channel].outputPins[i]->initPin("Trigger emulator", pin,
277 outputMode);
278 }
279#endif // EFI_PROD_CODE
280 }
281 }
282}
void initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e outputMode, bool forceInitWithFatalError=false)
Definition efi_gpio.cpp:711
OutputPin * outputPins[PWM_PHASE_MAX_WAVE_PER_PWM]
bool isBrainPinValid(brain_pin_e brainPin)
pin_output_mode_e
brain_pin_e pin
Definition stm32_adc.cpp:15
pin_output_mode_e triggerSimulatorPinModes[TRIGGER_SIMULATOR_PIN_COUNT]
static OutputPin emulatorOutputs[NUM_EMULATOR_CHANNELS][PWM_PHASE_MAX_WAVE_PER_PWM]

Referenced by applyNewHardwareSettings(), and initTriggerEmulator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stopTriggerEmulatorPins()

void stopTriggerEmulatorPins ( )

Definition at line 284 of file trigger_emulator_algo.cpp.

284 {
285#if EFI_PROD_CODE
286 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
287 // todo: add pin configs for cam simulator channels
288 if (channel != 0)
289 continue;
290 for (size_t i = 0; i < efi::size(emulatorOutputs[channel]); i++) {
291 if (isConfigurationChanged(triggerSimulatorPins[i])) {
293 }
294 }
295 }
296#endif // EFI_PROD_CODE
297}
void deInit()
Definition efi_gpio.cpp:802

Referenced by stopHardware().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateTriggerWaveformIfNeeded()

static void updateTriggerWaveformIfNeeded ( PwmConfig state)
static

Definition at line 120 of file trigger_emulator_algo.cpp.

120 {
121 for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
123 continue;
124
127 efiPrintf("Stimulator: updating trigger shape for ch%d: %d/%d %ld", channel, atTriggerVersions[channel],
129
131 state->safe.periodNt = -1; // this would cause loop re-initialization
132 }
133 }
134}
uint8_t version
int getGlobalConfigurationVersion() const
Definition engine.cpp:289
efitimems_t getTimeNowMs()
Returns the 32 bit number of milliseconds since the board initialization.
Definition efitime.cpp:34
void copyPwmParameters(PwmConfig *state, MultiChannelStateSequence const *seq)
static int atTriggerVersions[NUM_EMULATOR_CHANNELS]

Referenced by startSimulatedTriggerSignal().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ atTriggerVersions

int atTriggerVersions[NUM_EMULATOR_CHANNELS] = { 0 }
static

Definition at line 72 of file trigger_emulator_algo.cpp.

72{ 0 };

Referenced by updateTriggerWaveformIfNeeded().

◆ emulatorOutputs

OutputPin emulatorOutputs[NUM_EMULATOR_CHANNELS][PWM_PHASE_MAX_WAVE_PER_PWM]
static

Definition at line 44 of file trigger_emulator_algo.cpp.

Referenced by startTriggerEmulatorPins(), and stopTriggerEmulatorPins().

◆ hasInitTriggerEmulator

bool hasInitTriggerEmulator = false
static

◆ hasStimPins

bool hasStimPins = false
static

Definition at line 137 of file trigger_emulator_algo.cpp.

Referenced by emulatorApplyPinState(), and startTriggerEmulatorPins().

◆ helper

TriggerEmulatorHelper helper
static

Definition at line 136 of file trigger_emulator_algo.cpp.

Referenced by emulatorApplyPinState().

◆ triggerEmulatorSignals

PwmConfig triggerEmulatorSignals[NUM_EMULATOR_CHANNELS]

◆ triggerEmulatorWaveforms

TriggerWaveform* triggerEmulatorWaveforms[NUM_EMULATOR_CHANNELS]

Go to the source code of this file.