auto-sync
This commit is contained in:
parent
6d1245799d
commit
d153fc390e
|
@ -7,6 +7,7 @@ TRIGGER_DECODERS_SRC_CPP = \
|
||||||
$(PROJECT_DIR)/controllers/trigger/trigger_chrysler.cpp \
|
$(PROJECT_DIR)/controllers/trigger/trigger_chrysler.cpp \
|
||||||
$(PROJECT_DIR)/controllers/trigger/trigger_structure.cpp \
|
$(PROJECT_DIR)/controllers/trigger/trigger_structure.cpp \
|
||||||
$(PROJECT_DIR)/controllers/trigger/trigger_decoder.cpp \
|
$(PROJECT_DIR)/controllers/trigger/trigger_decoder.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/trigger/trigger_simulator.cpp \
|
||||||
$(PROJECT_DIR)/controllers/trigger/trigger_mitsubishi.cpp \
|
$(PROJECT_DIR)/controllers/trigger/trigger_mitsubishi.cpp \
|
||||||
$(PROJECT_DIR)/controllers/trigger/trigger_nissan.cpp \
|
$(PROJECT_DIR)/controllers/trigger/trigger_nissan.cpp \
|
||||||
$(PROJECT_DIR)/controllers/trigger/trigger_subaru.cpp \
|
$(PROJECT_DIR)/controllers/trigger/trigger_subaru.cpp \
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "engine_math.h"
|
#include "engine_math.h"
|
||||||
#include "trigger_central.h"
|
#include "trigger_central.h"
|
||||||
|
#include "trigger_simulator.h"
|
||||||
|
|
||||||
#if EFI_SENSOR_CHART || defined(__DOXYGEN__)
|
#if EFI_SENSOR_CHART || defined(__DOXYGEN__)
|
||||||
#include "sensor_chart.h"
|
#include "sensor_chart.h"
|
||||||
|
@ -48,9 +49,6 @@ static OutputPin triggerDecoderErrorPin;
|
||||||
EXTERN_ENGINE
|
EXTERN_ENGINE
|
||||||
;
|
;
|
||||||
|
|
||||||
// todo: better name for this constant
|
|
||||||
#define HELPER_PERIOD 720000
|
|
||||||
|
|
||||||
static cyclic_buffer<int> errorDetection;
|
static cyclic_buffer<int> errorDetection;
|
||||||
|
|
||||||
#if ! EFI_PROD_CODE || defined(__DOXYGEN__)
|
#if ! EFI_PROD_CODE || defined(__DOXYGEN__)
|
||||||
|
@ -503,47 +501,6 @@ void TriggerShape::initializeTriggerShape(Logging *logger DECLARE_ENGINE_PARAMET
|
||||||
calculateTriggerSynchPoint(&engine->triggerCentral.triggerState PASS_ENGINE_PARAMETER);
|
calculateTriggerSynchPoint(&engine->triggerCentral.triggerState PASS_ENGINE_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerStimulatorHelper::TriggerStimulatorHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void TriggerStimulatorHelper::nextStep(TriggerState *state, TriggerShape * shape, int i,
|
|
||||||
trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_S) {
|
|
||||||
int stateIndex = i % shape->getSize();
|
|
||||||
int prevIndex = (stateIndex + shape->getSize() - 1 ) % shape->getSize();
|
|
||||||
|
|
||||||
|
|
||||||
int loopIndex = i / shape->getSize();
|
|
||||||
|
|
||||||
int time = (int) (HELPER_PERIOD * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
|
|
||||||
|
|
||||||
bool_t primaryWheelState = shape->wave.getChannelState(0, prevIndex);
|
|
||||||
bool_t newPrimaryWheelState = shape->wave.getChannelState(0, stateIndex);
|
|
||||||
|
|
||||||
bool_t secondaryWheelState = shape->wave.getChannelState(1, prevIndex);
|
|
||||||
bool_t newSecondaryWheelState = shape->wave.getChannelState(1, stateIndex);
|
|
||||||
|
|
||||||
bool_t thirdWheelState = shape->wave.getChannelState(2, prevIndex);
|
|
||||||
bool_t new3rdWheelState = shape->wave.getChannelState(2, stateIndex);
|
|
||||||
|
|
||||||
if (primaryWheelState != newPrimaryWheelState) {
|
|
||||||
primaryWheelState = newPrimaryWheelState;
|
|
||||||
trigger_event_e s = primaryWheelState ? SHAFT_PRIMARY_UP : SHAFT_PRIMARY_DOWN;
|
|
||||||
state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondaryWheelState != newSecondaryWheelState) {
|
|
||||||
secondaryWheelState = newSecondaryWheelState;
|
|
||||||
trigger_event_e s = secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN;
|
|
||||||
state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thirdWheelState != new3rdWheelState) {
|
|
||||||
thirdWheelState = new3rdWheelState;
|
|
||||||
trigger_event_e s = thirdWheelState ? SHAFT_3RD_UP : SHAFT_3RD_DOWN;
|
|
||||||
state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onFindIndex(TriggerState *state) {
|
static void onFindIndex(TriggerState *state) {
|
||||||
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
|
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
|
||||||
// todo: that's not the best place for this intermediate data storage, fix it!
|
// todo: that's not the best place for this intermediate data storage, fix it!
|
||||||
|
@ -551,18 +508,6 @@ static void onFindIndex(TriggerState *state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t doFindTrigger(TriggerStimulatorHelper *helper, TriggerShape * shape,
|
|
||||||
trigger_config_s const*triggerConfig, TriggerState *state DECLARE_ENGINE_PARAMETER_S) {
|
|
||||||
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
|
|
||||||
helper->nextStep(state, shape, i, triggerConfig PASS_ENGINE_PARAMETER);
|
|
||||||
|
|
||||||
if (state->shaft_is_synchronized)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
firmwareError("findTriggerZeroEventIndex() failed");
|
|
||||||
return EFI_ERROR_CODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger shape is defined in a way which is convenient for trigger shape definition
|
* Trigger shape is defined in a way which is convenient for trigger shape definition
|
||||||
* On the other hand, trigger decoder indexing begins from synchronization event.
|
* On the other hand, trigger decoder indexing begins from synchronization event.
|
||||||
|
@ -582,7 +527,7 @@ DECLARE_ENGINE_PARAMETER_S) {
|
||||||
// todo: should this variable be declared 'static' to reduce stack usage?
|
// todo: should this variable be declared 'static' to reduce stack usage?
|
||||||
TriggerStimulatorHelper helper;
|
TriggerStimulatorHelper helper;
|
||||||
|
|
||||||
uint32_t index = doFindTrigger(&helper, shape, triggerConfig, state PASS_ENGINE_PARAMETER);
|
uint32_t index = helper.doFindTrigger(shape, triggerConfig, state PASS_ENGINE_PARAMETER);
|
||||||
if (index == EFI_ERROR_CODE) {
|
if (index == EFI_ERROR_CODE) {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -596,18 +541,7 @@ DECLARE_ENGINE_PARAMETER_S) {
|
||||||
*/
|
*/
|
||||||
state->cycleCallback = onFindIndex;
|
state->cycleCallback = onFindIndex;
|
||||||
|
|
||||||
int startIndex = engineConfiguration->useOnlyFrontForTrigger ? index + 2 : index + 1;
|
helper.assertSyncPositionAndSetDutyCycle(index, state, shape,triggerConfig PASS_ENGINE_PARAMETER);
|
||||||
|
|
||||||
for (uint32_t i = startIndex; i <= index + 2 * shape->getSize(); i++) {
|
|
||||||
helper.nextStep(state, shape, i, triggerConfig PASS_ENGINE_PARAMETER);
|
|
||||||
if (engineConfiguration->useOnlyFrontForTrigger)
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
efiAssert(state->getTotalRevolutionCounter() == 3, "totalRevolutionCounter2 expected 3", EFI_ERROR_CODE);
|
|
||||||
|
|
||||||
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
|
|
||||||
shape->dutyCycle[i] = 1.0 * state->expectedTotalTime[i] / HELPER_PERIOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
return index % shape->getSize();
|
return index % shape->getSize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,12 +104,6 @@ private:
|
||||||
efitick_t startOfCycleNt;
|
efitick_t startOfCycleNt;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TriggerStimulatorHelper {
|
|
||||||
public:
|
|
||||||
TriggerStimulatorHelper();
|
|
||||||
void nextStep(TriggerState *state, TriggerShape * shape, int i, trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_S);
|
|
||||||
};
|
|
||||||
|
|
||||||
float getEngineCycle(operation_mode_e operationMode);
|
float getEngineCycle(operation_mode_e operationMode);
|
||||||
void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerShape *s,
|
void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerShape *s,
|
||||||
int totalTeethCount, int skippedCount,
|
int totalTeethCount, int skippedCount,
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* @file trigger_emulator_algo.cpp
|
* @file trigger_emulator_algo.cpp
|
||||||
*
|
*
|
||||||
|
* This file is about producing real electrical signals which emulate trigger signal based on
|
||||||
|
* a known TriggerShape.
|
||||||
|
*
|
||||||
|
* 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
|
* @date Mar 3, 2014
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2015
|
* @author Andrey Belomutskiy, (c) 2012-2015
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* @file trigger_simulator.cpp
|
||||||
|
*
|
||||||
|
* @date Sep 23, 2015
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2015
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "engine.h"
|
||||||
|
#include "trigger_simulator.h"
|
||||||
|
|
||||||
|
#define SIMULATION_CYCLE_PERIOD 720000
|
||||||
|
|
||||||
|
EXTERN_ENGINE;
|
||||||
|
|
||||||
|
TriggerStimulatorHelper::TriggerStimulatorHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriggerStimulatorHelper::nextStep(TriggerState *state, TriggerShape * shape, int i,
|
||||||
|
trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_S) {
|
||||||
|
int stateIndex = i % shape->getSize();
|
||||||
|
int prevIndex = (stateIndex + shape->getSize() - 1 ) % shape->getSize();
|
||||||
|
|
||||||
|
|
||||||
|
int loopIndex = i / shape->getSize();
|
||||||
|
|
||||||
|
int time = (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
|
||||||
|
|
||||||
|
bool_t primaryWheelState = shape->wave.getChannelState(0, prevIndex);
|
||||||
|
bool_t newPrimaryWheelState = shape->wave.getChannelState(0, stateIndex);
|
||||||
|
|
||||||
|
bool_t secondaryWheelState = shape->wave.getChannelState(1, prevIndex);
|
||||||
|
bool_t newSecondaryWheelState = shape->wave.getChannelState(1, stateIndex);
|
||||||
|
|
||||||
|
bool_t thirdWheelState = shape->wave.getChannelState(2, prevIndex);
|
||||||
|
bool_t new3rdWheelState = shape->wave.getChannelState(2, stateIndex);
|
||||||
|
|
||||||
|
if (primaryWheelState != newPrimaryWheelState) {
|
||||||
|
primaryWheelState = newPrimaryWheelState;
|
||||||
|
trigger_event_e s = primaryWheelState ? SHAFT_PRIMARY_UP : SHAFT_PRIMARY_DOWN;
|
||||||
|
state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondaryWheelState != newSecondaryWheelState) {
|
||||||
|
secondaryWheelState = newSecondaryWheelState;
|
||||||
|
trigger_event_e s = secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN;
|
||||||
|
state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thirdWheelState != new3rdWheelState) {
|
||||||
|
thirdWheelState = new3rdWheelState;
|
||||||
|
trigger_event_e s = thirdWheelState ? SHAFT_3RD_UP : SHAFT_3RD_DOWN;
|
||||||
|
state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriggerStimulatorHelper::assertSyncPositionAndSetDutyCycle(uint32_t index, TriggerState *state, TriggerShape * shape,
|
||||||
|
trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_S) {
|
||||||
|
int startIndex = engineConfiguration->useOnlyFrontForTrigger ? index + 2 : index + 1;
|
||||||
|
|
||||||
|
for (uint32_t i = startIndex; i <= index + 2 * shape->getSize(); i++) {
|
||||||
|
nextStep(state, shape, i, triggerConfig PASS_ENGINE_PARAMETER);
|
||||||
|
if (engineConfiguration->useOnlyFrontForTrigger)
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// todo: nicer error handling?
|
||||||
|
efiAssertVoid(state->getTotalRevolutionCounter() == 3, "totalRevolutionCounter2 expected 3");
|
||||||
|
|
||||||
|
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
|
||||||
|
shape->dutyCycle[i] = 1.0 * state->expectedTotalTime[i] / SIMULATION_CYCLE_PERIOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TriggerStimulatorHelper::doFindTrigger(TriggerShape * shape,
|
||||||
|
trigger_config_s const*triggerConfig, TriggerState *state DECLARE_ENGINE_PARAMETER_S) {
|
||||||
|
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
|
||||||
|
nextStep(state, shape, i, triggerConfig PASS_ENGINE_PARAMETER);
|
||||||
|
|
||||||
|
if (state->shaft_is_synchronized)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
firmwareError("findTriggerZeroEventIndex() failed");
|
||||||
|
return EFI_ERROR_CODE;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* @file trigger_simulator.h
|
||||||
|
* @brief This class knows how to produce synthetic shaft signals based on triggerShape
|
||||||
|
*
|
||||||
|
* @date Sep 23, 2015
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2015
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONTROLLERS_TRIGGER_TRIGGER_SIMULATOR_H_
|
||||||
|
#define CONTROLLERS_TRIGGER_TRIGGER_SIMULATOR_H_
|
||||||
|
|
||||||
|
#include "trigger_decoder.h"
|
||||||
|
|
||||||
|
class TriggerStimulatorHelper {
|
||||||
|
public:
|
||||||
|
TriggerStimulatorHelper();
|
||||||
|
|
||||||
|
uint32_t doFindTrigger(TriggerShape * shape,
|
||||||
|
trigger_config_s const*triggerConfig, TriggerState *state DECLARE_ENGINE_PARAMETER_S);
|
||||||
|
|
||||||
|
void nextStep(TriggerState *state, TriggerShape * shape, int i, trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_S);
|
||||||
|
|
||||||
|
void assertSyncPositionAndSetDutyCycle(uint32_t index, TriggerState *state, TriggerShape * shape,
|
||||||
|
trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_S);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CONTROLLERS_TRIGGER_TRIGGER_SIMULATOR_H_ */
|
Loading…
Reference in New Issue