rusEFI
The most advanced open source ECU
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)
 
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 211 of file trigger_emulator_algo.cpp.

211  {
213  for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
214  triggerEmulatorSignals[channel].stop();
215  }
216  hasInitTriggerEmulator = false;
218 }
TriggerCentral triggerCentral
Definition: engine.h:286
bool directSelfStimulation
void incrementGlobalConfigurationVersion(const char *msg)
Engine * engine
PwmConfig triggerEmulatorSignals[NUM_EMULATOR_CHANNELS]
static bool hasInitTriggerEmulator

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

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 143 of file trigger_emulator_algo.cpp.

143  {
144  assertStackVoid("emulator", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK);
146  /**
147  * this callback would invoke the input signal handlers directly
148  */
149  for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
150  if (state != &triggerEmulatorSignals[channel])
151  continue;
153  *state->multiChannelStateSequence,
154  stateIndex);
155  }
156  }
157 
158 #if EFI_PROD_CODE
159  // Only set pins if they're configured - no need to waste the cycles otherwise
160  else if (hasStimPins) {
161  applyPinState(stateIndex, state);
162  }
163 #endif /* EFI_PROD_CODE */
164 }
void handleEmulatorCallback(int channel, const MultiChannelStateSequence &mcss, int stateIndex)
@ STACK_USAGE_MISC
void applyPinState(int stateIndex, PwmConfig *state)
static ScState state
static bool hasStimPins
static TriggerEmulatorHelper helper

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 205 of file trigger_emulator_algo.cpp.

205  {
209 }
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 194 of file trigger_emulator_algo.cpp.

194  {
198  if (incGlobalConfiguration) {
200  }
201 }
RpmCalculator rpmCalculator
Definition: engine.h:273
bool Register()
Definition: sensor.cpp:131

Referenced by commonEarlyInit(), 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
Definition: rusefi_enums.h:270
@ FOUR_STROKE_TWELVE_TIMES_CRANK_SENSOR
Definition: rusefi_enums.h:280
@ FOUR_STROKE_THREE_TIMES_CRANK_SENSOR
Definition: rusefi_enums.h:275
@ FOUR_STROKE_CRANK_SENSOR
Definition: rusefi_enums.h:256
@ OM_NONE
Definition: rusefi_enums.h:250
@ FOUR_STROKE_CAM_SENSOR
Definition: rusefi_enums.h:260
@ TWO_STROKE
Definition: rusefi_enums.h:264
@ FOUR_STROKE_SIX_TIMES_CRANK_SENSOR
Definition: rusefi_enums.h:285
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 228 of file trigger_emulator_algo.cpp.

228  {
229  efiPrintf("Emulating %s", getEngine_type_e(engineConfiguration->engineType));
230 
232 
234 }
const char * getEngine_type_e(engine_type_e value)
void addConsoleActionI(const char *token, VoidInt callback)
Register a console command with one Integer parameter.
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 220 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:

◆ 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  }
112  triggerEmulatorSignals[channel].setFrequency(rPerSecond);
113  }
114 
116 
117  efiPrintf("Emulating position sensor(s). RPM=%d", rpm);
118 }
void resetEngineSnifferIfInTestMode()
Definition: engine.cpp:56
virtual operation_mode_e getOperationMode() const =0
void setFrequency(float frequency)
EngineRotationState * getEngineRotationState()
Definition: engine.cpp:574
static float getRpmMultiplier(operation_mode_e mode)

Referenced by configureRusefiLuaHooks(), initTriggerEmulator(), onConfigurationChangeRpmEmulatorCallback(), Engine::periodicSlowCallback(), 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 166 of file trigger_emulator_algo.cpp.

166  {
167  // No need to start more than once
169  return;
170  }
171 
172  // store the crank+cam waveforms
174  for (int cami = 0; cami < CAMS_PER_BANK; cami++) {
176  }
177 
179 
180  for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
182  if (s->getSize() == 0)
183  continue;
185  &engine->executor,
186  &s->wave,
188  }
189  hasInitTriggerEmulator = true;
190 }
SingleTimerExecutor executor
Definition: engine.h:241
void weComplexInit(ExecutorInterface *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 238 of file trigger_emulator_algo.cpp.

238  {
239  hasStimPins = false;
240  for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
241  for (size_t i = 0; i < efi::size(emulatorOutputs[channel]); i++) {
242  triggerEmulatorSignals[channel].outputPins[i] = &emulatorOutputs[channel][i];
243 
244 #if EFI_PROD_CODE
246 
247  pin_output_mode_e outputMode;
248  if (channel == 0) {
251  } else if (channel == 1 && i == 0) {
254  } else {
255  // todo: add pin configs for cam simulator channels
256  continue;
257  }
258 
259  // Only bother trying to set output pins if they're configured
260  if (isBrainPinValid(pin)) {
261  hasStimPins = true;
262  }
263 
264  if (isConfigurationChanged(triggerSimulatorPins[i])) {
265  triggerEmulatorSignals[channel].outputPins[i]->initPin("Trigger emulator", pin,
266  outputMode);
267  }
268 #endif // EFI_PROD_CODE
269  }
270  }
271 }
void initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e outputMode, bool forceInitWithFatalError=false)
Definition: efi_gpio.cpp:690
OutputPin * outputPins[PWM_PHASE_MAX_WAVE_PER_PWM]
Gpio
bool isBrainPinValid(brain_pin_e brainPin)
pin_output_mode_e
Definition: rusefi_enums.h:236
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 273 of file trigger_emulator_algo.cpp.

273  {
274 #if EFI_PROD_CODE
275  for (int channel = 0; channel < NUM_EMULATOR_CHANNELS; channel++) {
276  // todo: add pin configs for cam simulator channels
277  if (channel != 0)
278  continue;
279  for (size_t i = 0; i < efi::size(emulatorOutputs[channel]); i++) {
280  if (isConfigurationChanged(triggerSimulatorPins[i])) {
282  }
283  }
284  }
285 #endif // EFI_PROD_CODE
286 }
void deInit()
Definition: efi_gpio.cpp:781

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++) {
122  if (state != &triggerEmulatorSignals[channel])
123  continue;
124 
125  if (atTriggerVersions[channel] < triggerEmulatorWaveforms[channel]->version) {
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(void) const
Definition: engine.cpp:302
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.

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.