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

150 lines
4.8 KiB
C++
Raw Normal View History

2014-08-29 07:52:33 -07:00
/**
* @file trigger_emulator_algo.cpp
*
* @date Mar 3, 2014
2015-01-12 15:04:10 -08:00
* @author Andrey Belomutskiy, (c) 2012-2015
2014-08-29 07:52:33 -07:00
*/
#include "main.h"
2014-12-23 22:03:26 -08:00
#if EFI_EMULATE_POSITION_SENSORS || defined(__DOXYGEN__)
2014-08-29 07:52:33 -07:00
#include "trigger_emulator_algo.h"
#include "engine_configuration.h"
#include "LocalVersionHolder.h"
2014-09-25 21:05:11 -07:00
#include "trigger_central.h"
#if EFI_PROD_CODE
#include "pwm_generator.h"
#endif
TriggerEmulatorHelper::TriggerEmulatorHelper() {
primaryWheelState = false;
secondaryWheelState = false;
thirdWheelState = false;
}
void TriggerEmulatorHelper::handleEmulatorCallback(PwmConfig *state, int stateIndex) {
int newPrimaryWheelState = state->multiWave.waves[0].pinStates[stateIndex];
int newSecondaryWheelState = state->multiWave.waves[1].pinStates[stateIndex];
int new3rdWheelState = state->multiWave.waves[2].pinStates[stateIndex];
if (primaryWheelState != newPrimaryWheelState) {
primaryWheelState = newPrimaryWheelState;
hwHandleShaftSignal(primaryWheelState ? SHAFT_PRIMARY_UP : SHAFT_PRIMARY_DOWN);
}
if (secondaryWheelState != newSecondaryWheelState) {
secondaryWheelState = newSecondaryWheelState;
hwHandleShaftSignal(secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN);
}
if (thirdWheelState != new3rdWheelState) {
thirdWheelState = new3rdWheelState;
hwHandleShaftSignal(thirdWheelState ? SHAFT_3RD_UP : SHAFT_3RD_DOWN);
}
// print("hello %d\r\n", chTimeNow());
}
2014-08-29 07:52:33 -07:00
2015-01-01 15:04:13 -08:00
EXTERN_ENGINE;
2014-08-29 07:52:33 -07:00
/*
* todo: should we simply re-use instances used by trigger_decoder?
* todo: since we are emulating same shape we are decoding
*/
static int pinStates1[PWM_PHASE_MAX_COUNT];
static int pinStates2[PWM_PHASE_MAX_COUNT];
static int pinStates3[PWM_PHASE_MAX_COUNT];
2014-09-25 21:05:11 -07:00
static single_wave_s waves[PWM_PHASE_MAX_WAVE_PER_PWM] = { single_wave_s(pinStates1), single_wave_s(pinStates2),
single_wave_s(pinStates3) };
static single_wave_s sr[PWM_PHASE_MAX_WAVE_PER_PWM] = { waves[0], waves[1], waves[2] };
2014-08-29 07:52:33 -07:00
static float swtchTms[PWM_PHASE_MAX_COUNT];
PwmConfig triggerSignal(swtchTms, sr);
2014-09-25 21:05:11 -07:00
#define DO_NOT_STOP 999999999
static int stopEmulationAtIndex = DO_NOT_STOP;
static bool isEmulating = true;
2014-08-29 07:52:33 -07:00
static Logging logger;
static LocalVersionHolder localVersion;
2014-11-07 19:04:45 -08:00
EXTERN_ENGINE;
2014-10-31 13:03:07 -07:00
2014-11-07 18:03:15 -08:00
void setTriggerEmulatorRPM(int rpm, Engine *engine) {
2014-09-12 18:05:24 -07:00
engineConfiguration->bc.triggerSimulatorFrequency = rpm;
2014-08-29 07:52:33 -07:00
/**
* All we need to do here is to change the periodMs
* togglePwmState() would see that the periodMs has changed and act accordingly
*/
if (rpm == 0) {
2014-09-12 21:02:43 -07:00
triggerSignal.periodNt = NAN;
2014-08-29 07:52:33 -07:00
} else {
float gRpm = rpm * engineConfiguration->rpmMultiplier / 60.0; // per minute converted to per second
2014-09-12 21:02:43 -07:00
triggerSignal.periodNt = US2NT(frequency2periodUs(gRpm));
2014-08-29 07:52:33 -07:00
}
scheduleMsg(&logger, "Emulating position sensor(s). RPM=%d", rpm);
}
static void updateTriggerShapeIfNeeded(PwmConfig *state) {
if (localVersion.isOld()) {
2014-09-25 21:05:11 -07:00
scheduleMsg(&logger, "Stimulator: updating trigger shape: %d/%d %d", localVersion.getVersion(),
getGlobalConfigurationVersion(), currentTimeMillis());
2014-08-29 07:52:33 -07:00
2014-11-07 19:04:45 -08:00
applyNonPersistentConfiguration(&logger, engine);
2014-08-29 07:52:33 -07:00
2015-01-13 05:04:00 -08:00
TriggerShape *s = &engine->triggerShape;
2014-09-25 21:05:11 -07:00
int *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates,
s->wave.waves[2].pinStates };
2014-08-29 07:52:33 -07:00
copyPwmParameters(state, s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM, pinStates);
2014-09-12 21:02:43 -07:00
state->safe.periodNt = -1; // this would cause loop re-initialization
2014-08-29 07:52:33 -07:00
}
}
2014-09-25 21:05:11 -07:00
static TriggerEmulatorHelper helper;
2014-08-29 07:52:33 -07:00
2014-09-25 21:05:11 -07:00
static void emulatorApplyPinState(PwmConfig *state, int stateIndex) {
if (stopEmulationAtIndex == stateIndex) {
isEmulating = false;
}
if (!isEmulating) {
return;
}
2014-11-15 09:03:07 -08:00
#if EFI_PROD_CODE || defined(__DOXYGEN__)
2014-09-25 21:05:11 -07:00
applyPinState(state, stateIndex);
#endif /* EFI_PROD_CODE */
if (engineConfiguration->directSelfStimulation) {
/**
* this callback would invoke the input signal handlers directly
*/
helper.handleEmulatorCallback(state, stateIndex);
}
}
2014-11-07 18:03:15 -08:00
static void setEmulatorAtIndex(int index, Engine *engine) {
2014-09-25 21:05:11 -07:00
stopEmulationAtIndex = index;
}
2014-11-07 18:03:15 -08:00
static void resumeStimulator(Engine *engine) {
2014-09-25 21:05:11 -07:00
isEmulating = true;
stopEmulationAtIndex = DO_NOT_STOP;
}
2014-11-05 09:03:15 -08:00
void initTriggerEmulatorLogic(Engine *engine) {
2014-09-25 21:05:11 -07:00
initLogging(&logger, "position sensor(s) emulator");
2014-08-29 07:52:33 -07:00
2015-01-13 05:04:00 -08:00
TriggerShape *s = &engine->triggerShape;
2014-11-07 18:03:15 -08:00
setTriggerEmulatorRPM(engineConfiguration->bc.triggerSimulatorFrequency, engine);
2014-09-25 21:05:11 -07:00
int *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates,
s->wave.waves[2].pinStates };
2015-01-08 07:03:44 -08:00
triggerSignal.weComplexInit("position sensor", s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM,
2014-09-25 21:05:11 -07:00
pinStates, updateTriggerShapeIfNeeded, emulatorApplyPinState);
2014-08-29 07:52:33 -07:00
2014-11-07 18:03:15 -08:00
addConsoleActionIP("rpm", (VoidIntVoidPtr)setTriggerEmulatorRPM, engine);
addConsoleActionIP("stop_stimulator_at_index", (VoidIntVoidPtr)setEmulatorAtIndex, engine);
addConsoleActionP("resume_stimulator", (VoidPtr) resumeStimulator, engine);
2014-08-29 07:52:33 -07:00
}
2014-12-23 20:03:31 -08:00
#endif