Drop SingleChannelStateSequence in favor of MultiChannelStateSequenceWithData (#3519)

* Drop SingleChannelStateSequence in favor of MultiChannelStateSequenceWithData

Most all the users were Multi* anyways, so just improve that:
1. Allow up to 8 waveforms to share one byte per timestamp.  It could be better but this is simple
   and gets most of the benefit.
2. Use a wrapper structure to handle reserving space for the arrays.  Makes the interface simpler
   and more rigid.  Also saves 4 bytes per Multi*.  Downside is access is now via -> and *,
   not . and (nothing).

Saves 224 bytes of BSS, 1832 bytes of RAM4/CCM, 952 bytes of TEXT, and 103 bytes of RODATA

* Instantiate a base_t to make debugging easier.
Also fixes crash on real firmware by using &m_base instead - LTO optimization issue?

* No magical templated StaticAlloc thingy.  Just virtual functions.
This commit is contained in:
Scott Smith 2021-11-21 01:56:07 -08:00 committed by GitHub
parent 9a28e8d938
commit ba4a00d3bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 137 additions and 245 deletions

View File

@ -9,86 +9,24 @@
#include "state_sequence.h"
#include "trigger_structure.h"
SingleChannelStateSequence::SingleChannelStateSequence() {
init(NULL);
}
SingleChannelStateSequence::SingleChannelStateSequence(pin_state_t *ps) {
init(ps);
}
void SingleChannelStateSequence::init(pin_state_t *pinStates) {
this->pinStates = pinStates;
}
pin_state_t SingleChannelStateSequence::getState(int switchIndex) const {
pin_state_t state = pinStates[switchIndex];
efiAssert(OBD_PCM_Processor_Fault, state == 0 || state == 1, "wave state get", TV_FALL);
return state;
}
void SingleChannelStateSequence::setState(int switchIndex, pin_state_t state) {
efiAssertVoid(OBD_PCM_Processor_Fault, state == 0 || state == 1, "wave state set");
pinStates[switchIndex] = state;
}
MultiChannelStateSequence::MultiChannelStateSequence() {
reset();
}
MultiChannelStateSequence::MultiChannelStateSequence(float *switchTimes, SingleChannelStateSequence *waves) : MultiChannelStateSequence() {
init(switchTimes, waves);
}
void MultiChannelStateSequence::init(float *switchTimes, SingleChannelStateSequence *channels) {
this->switchTimes = switchTimes;
this->channels = channels;
}
void MultiChannelStateSequence::reset(void) {
waveCount = 0;
}
float MultiChannelStateSequence::getSwitchTime(const int index) const {
return switchTimes[index];
}
void MultiChannelStateSequence::checkSwitchTimes(const float scale) const {
if (switchTimes[phaseCount - 1] != 1) {
firmwareError(CUSTOM_ERR_WAVE_1, "last switch time has to be 1/%f not %.2f/%f", scale,
switchTimes[phaseCount - 1], scale * switchTimes[phaseCount - 1]);
if (getSwitchTime(phaseCount - 1) != 1) {
firmwareError(CUSTOM_ERR_WAVE_1, "last switch time has to be 1/%f not %.2f/%f",
scale, getSwitchTime(phaseCount - 1),
scale * getSwitchTime(phaseCount - 1));
return;
}
for (int i = 0; i < phaseCount - 1; i++) {
if (switchTimes[i] >= switchTimes[i + 1]) {
firmwareError(CUSTOM_ERR_WAVE_2, "invalid switchTimes @%d: %.2f/%.2f", i, switchTimes[i], switchTimes[i + 1]);
if (getSwitchTime(i) >= getSwitchTime(i + 1)) {
firmwareError(CUSTOM_ERR_WAVE_2, "invalid switchTimes @%d: %.2f/%.2f",
i, getSwitchTime(i), getSwitchTime(i + 1));
}
}
}
pin_state_t MultiChannelStateSequence::getChannelState(const int channelIndex, const int phaseIndex) const {
if (channelIndex >= waveCount) {
// todo: would be nice to get this asserting working
//firmwareError(OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount);
}
return channels[channelIndex].pinStates[phaseIndex];
}
void MultiChannelStateSequence::setChannelState(const int channelIndex, const int phaseIndex,
pin_state_t state) {
if (channelIndex >= waveCount) {
// todo: would be nice to get this asserting working
//firmwareError(OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount);
}
channels[channelIndex].pinStates[phaseIndex] = state;
}
/**
* returns the index at which given value would need to be inserted into sorted array
*/
int MultiChannelStateSequence::findInsertionAngle(const float angle) const {
for (int i = phaseCount - 1; i >= 0; i--) {
if (angle > switchTimes[i])
if (angle > getSwitchTime(i))
return i + 1;
}
return 0;
@ -96,13 +34,8 @@ int MultiChannelStateSequence::findInsertionAngle(const float angle) const {
int MultiChannelStateSequence::findAngleMatch(const float angle) const {
for (int i = 0; i < phaseCount; i++) {
if (isSameF(switchTimes[i], angle))
if (isSameF(getSwitchTime(i), angle))
return i;
}
return EFI_ERROR_CODE;
}
void MultiChannelStateSequence::setSwitchTime(const int index, const float value) {
efiAssertVoid(CUSTOM_ERR_PWM_SWITCH_ASSERT, switchTimes != NULL, "switchTimes");
switchTimes[index] = value;
}

View File

@ -26,72 +26,72 @@
#endif /* PWM_PHASE_MAX_COUNT */
#define PWM_PHASE_MAX_WAVE_PER_PWM 3
/**
* int8_t is probably less efficient then int32_t but we need
* to reduce memory footprint
*
* todo: migrate to bit-array to save memory?
* this would cost some CPU cycles. see std::vector<bool>
*/
typedef trigger_value_e pin_state_t;
/**
* This class represents one channel of a digital signal state sequence
* Each element represents either a HIGH or LOW state - while at the moment this
* is not implemented using a bit array, it could absolutely be a bit array
*
* This sequence does not know anything about signal lengths - only signal state at a given index
* This sequence can have consecutive zeros and ones since these sequences work as a group within MultiChannelStateSequence
*
* @brief PWM configuration for the specific output pin
*/
class SingleChannelStateSequence {
public:
SingleChannelStateSequence();
explicit SingleChannelStateSequence(pin_state_t *pinStates);
void init(pin_state_t *pinStates);
/**
* todo: confirm that we only deal with two states here, no magic '-1'?
* @return HIGH or LOW state at given index
*/
pin_state_t getState(int switchIndex) const;
void setState(int switchIndex, pin_state_t state);
// todo: make this private by using 'getState' and 'setState' methods
pin_state_t *pinStates;
};
/**
* This class represents multi-channel logical signals with shared time axis
*
* This is a semi-abstract interface so that implementations can exist for either regularized
* patterns (60-2, etc) or completely arbitrary patterns stored in arrays.
*/
class MultiChannelStateSequence {
public:
MultiChannelStateSequence();
MultiChannelStateSequence(float *switchTimes, SingleChannelStateSequence *waves);
void init(float *switchTimes, SingleChannelStateSequence *waves);
void reset(void);
float getSwitchTime(const int phaseIndex) const;
void setSwitchTime(const int phaseIndex, const float value);
void checkSwitchTimes(const float scale) const;
pin_state_t getChannelState(const int channelIndex, const int phaseIndex) const;
void setChannelState(const int channelIndex, const int phaseIndex, pin_state_t state);
int findAngleMatch(const float angle) const;
int findInsertionAngle(const float angle) const;
/**
* Number of signal channels
* values in the (0..1] range which refer to points within the period at at which pin state
* should be changed So, in the simplest case we turn pin off at 0.3 and turn it on at 1 -
* that would give us a 70% duty cycle PWM
*/
uint16_t phaseCount;
uint16_t waveCount;
SingleChannelStateSequence *channels = nullptr;
//private:
/**
* values in the (0..1] range which refer to points within the period at at which pin state should be changed
* So, in the simplest case we turn pin off at 0.3 and turn it on at 1 - that would give us a 70% duty cycle PWM
*/
float *switchTimes = nullptr;
virtual float getSwitchTime(int phaseIndex) const = 0;
virtual pin_state_t getChannelState(int channelIndex, int phaseIndex) const = 0;
// Make sure the switch times are in order and end at the very end.
void checkSwitchTimes(float scale) const;
// Find the exact angle, or EFI_ERROR_CODE if it doesn't exist
int findAngleMatch(float angle) const;
// returns the index at which given value would need to be inserted into sorted array
int findInsertionAngle(float angle) const;
uint16_t phaseCount = 0; // Number of timestamps
uint16_t waveCount = 0; // Number of waveforms
};
template<unsigned max_phase>
class MultiChannelStateSequenceWithData : public MultiChannelStateSequence {
public:
float getSwitchTime(int phaseIndex) const override {
return switchTimes[phaseIndex];
}
pin_state_t getChannelState(int channelIndex, int phaseIndex) const override {
if (channelIndex >= waveCount) {
// todo: would be nice to get this asserting working
//firmwareError(OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount);
}
return ((waveForm[phaseIndex] >> channelIndex) & 1) ? TV_RISE : TV_FALL;
}
void reset() {
waveCount = 0;
}
void setSwitchTime(const int phaseIndex, const float value) {
efiAssertVoid(CUSTOM_ERR_PWM_SWITCH_ASSERT, switchTimes != nullptr, "switchTimes");
switchTimes[phaseIndex] = value;
}
void setChannelState(const int channelIndex, const int phaseIndex, pin_state_t state) {
if (channelIndex >= waveCount) {
// todo: would be nice to get this asserting working
//firmwareError(OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount);
}
uint8_t & ref = waveForm[phaseIndex];
ref = (ref & ~(1U << channelIndex)) | ((state == TV_RISE ? 1 : 0) << channelIndex);
}
private:
float switchTimes[max_phase];
uint8_t waveForm[max_phase];
};

View File

@ -19,8 +19,6 @@
#define ZERO_PWM_THRESHOLD 0.01
SimplePwm::SimplePwm()
: sr(pinStates)
, seq(_switchTimes, &sr)
{
seq.waveCount = 1;
seq.phaseCount = 2;
@ -87,7 +85,7 @@ void SimplePwm::setSimplePwmDutyCycle(float dutyCycle) {
mode = PM_FULL;
} else {
mode = PM_NORMAL;
_switchTimes[0] = dutyCycle;
seq.setSwitchTime(0, dutyCycle);
}
}
@ -316,15 +314,15 @@ void startSimplePwm(SimplePwm *state, const char *msg, ExecutorInterface *execut
return;
}
state->_switchTimes[0] = dutyCycle;
state->_switchTimes[1] = 1;
state->pinStates[0] = TV_FALL;
state->pinStates[1] = TV_RISE;
state->seq.setSwitchTime(0, dutyCycle);
state->seq.setSwitchTime(1, 1);
state->seq.setChannelState(0, 0, TV_FALL);
state->seq.setChannelState(0, 1, TV_RISE);
state->outputPins[0] = output;
state->setFrequency(frequency);
state->setSimplePwmDutyCycle(dutyCycle); // TODO: DUP ABOVE?
state->setSimplePwmDutyCycle(dutyCycle);
state->weComplexInit(msg, executor, &state->seq, NULL, (pwm_gen_callback*)applyPinState);
}

View File

@ -120,10 +120,7 @@ public:
SimplePwm();
explicit SimplePwm(const char *name);
void setSimplePwmDutyCycle(float dutyCycle) override;
pin_state_t pinStates[2];
SingleChannelStateSequence sr;
float _switchTimes[2];
MultiChannelStateSequence seq;
MultiChannelStateSequenceWithData<2> seq;
hardware_pwm* hardPwm = nullptr;
};

View File

@ -49,18 +49,8 @@ void event_trigger_position_s::setAngle(angle_t angle) {
this, angle);
}
trigger_shape_helper::trigger_shape_helper() {
memset(&pinStates, 0, sizeof(pinStates));
for (int channelIndex = 0; channelIndex < TRIGGER_CHANNEL_COUNT; channelIndex++) {
channels[channelIndex].init(pinStates[channelIndex]);
}
}
TriggerWaveform::TriggerWaveform()
: waveStorage(switchTimesBuffer, NULL)
, wave(&waveStorage) {
TriggerWaveform::TriggerWaveform() {
initialize(OM_NONE);
wave->channels = h.channels;
}
void TriggerWaveform::initialize(operation_mode_e operationMode) {
@ -85,11 +75,10 @@ void TriggerWaveform::initialize(operation_mode_e operationMode) {
this->operationMode = operationMode;
triggerShapeSynchPointIndex = 0;
memset(initialState, 0, sizeof(initialState));
memset(switchTimesBuffer, 0, sizeof(switchTimesBuffer));
memset(expectedEventCount, 0, sizeof(expectedEventCount));
wave->reset();
wave->waveCount = TRIGGER_CHANNEL_COUNT;
wave->phaseCount = 0;
wave.reset();
wave.waveCount = TRIGGER_CHANNEL_COUNT;
wave.phaseCount = 0;
previousAngle = 0;
memset(isRiseEvent, 0, sizeof(isRiseEvent));
#if EFI_UNIT_TEST
@ -99,7 +88,7 @@ void TriggerWaveform::initialize(operation_mode_e operationMode) {
}
size_t TriggerWaveform::getSize() const {
return wave->phaseCount;
return wave.phaseCount;
}
int TriggerWaveform::getTriggerWaveformSynchPointIndex() const {
@ -149,9 +138,9 @@ angle_t TriggerWaveform::getAngle(int index) const {
* See also trigger_central.cpp
* See also getEngineCycleEventCount()
*/
efiAssert(CUSTOM_ERR_ASSERT, wave->phaseCount != 0, "shapeSize=0", NAN);
int crankCycle = index / wave->phaseCount;
int remainder = index % wave->phaseCount;
efiAssert(CUSTOM_ERR_ASSERT, wave.phaseCount != 0, "shapeSize=0", NAN);
int crankCycle = index / wave.phaseCount;
int remainder = index % wave.phaseCount;
auto cycleStartAngle = getCycleDuration() * crankCycle;
auto positionWithinCycle = getSwitchAngle(remainder);
@ -235,9 +224,9 @@ void TriggerWaveform::addEvent(angle_t angle, trigger_wheel_e const channelIndex
#endif
#if EFI_UNIT_TEST
assertIsInBounds(wave->phaseCount, triggerSignalIndeces, "trigger shape overflow");
triggerSignalIndeces[wave->phaseCount] = channelIndex;
triggerSignalStates[wave->phaseCount] = state;
assertIsInBounds(wave.phaseCount, triggerSignalIndeces, "trigger shape overflow");
triggerSignalIndeces[wave.phaseCount] = channelIndex;
triggerSignalStates[wave.phaseCount] = state;
#endif // EFI_UNIT_TEST
@ -249,46 +238,39 @@ void TriggerWaveform::addEvent(angle_t angle, trigger_wheel_e const channelIndex
}
efiAssertVoid(CUSTOM_ERR_6599, angle > 0 && angle <= 1, "angle should be positive not above 1");
if (wave->phaseCount > 0) {
if (wave.phaseCount > 0) {
if (angle <= previousAngle) {
warning(CUSTOM_ERR_TRG_ANGLE_ORDER, "invalid angle order %s %s: new=%.2f/%f and prev=%.2f/%f, size=%d",
getTrigger_wheel_e(channelIndex),
getTrigger_value_e(state),
angle, angle * getCycleDuration(),
previousAngle, previousAngle * getCycleDuration(),
wave->phaseCount);
wave.phaseCount);
setShapeDefinitionError(true);
return;
}
}
previousAngle = angle;
if (wave->phaseCount == 0) {
wave->phaseCount = 1;
if (wave.phaseCount == 0) {
wave.phaseCount = 1;
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
SingleChannelStateSequence *swave = &wave->channels[i];
if (swave->pinStates == nullptr) {
warning(CUSTOM_ERR_STATE_NULL, "wave pinStates is NULL");
setShapeDefinitionError(true);
return;
}
wave->setChannelState(i, /* switchIndex */ 0, /* value */ initialState[i]);
wave.setChannelState(i, /* switchIndex */ 0, /* value */ initialState[i]);
}
isRiseEvent[0] = TV_RISE == state;
wave->setSwitchTime(0, angle);
wave->setChannelState(channelIndex, /* channelIndex */ 0, /* value */ state);
wave.setSwitchTime(0, angle);
wave.setChannelState(channelIndex, /* channelIndex */ 0, /* value */ state);
return;
}
int exactMatch = wave->findAngleMatch(angle);
int exactMatch = wave.findAngleMatch(angle);
if (exactMatch != (int)EFI_ERROR_CODE) {
warning(CUSTOM_ERR_SAME_ANGLE, "same angle: not supported");
setShapeDefinitionError(true);
return;
}
int index = wave->findInsertionAngle(angle);
int index = wave.findInsertionAngle(angle);
/**
* todo: it would be nice to be able to provide trigger angles without sorting them externally
@ -298,29 +280,29 @@ void TriggerWaveform::addEvent(angle_t angle, trigger_wheel_e const channelIndex
/*
for (int i = size - 1; i >= index; i--) {
for (int j = 0; j < PWM_PHASE_MAX_WAVE_PER_PWM; j++) {
wave->waves[j].pinStates[i + 1] = wave->getChannelState(j, index);
wave.waves[j].pinStates[i + 1] = wave.getChannelState(j, index);
}
wave->setSwitchTime(i + 1, wave->getSwitchTime(i));
wave.setSwitchTime(i + 1, wave.getSwitchTime(i));
}
*/
isRiseEvent[index] = TV_RISE == state;
if ((unsigned)index != wave->phaseCount) {
if ((unsigned)index != wave.phaseCount) {
firmwareError(ERROR_TRIGGER_DRAMA, "are we ever here?");
}
wave->phaseCount++;
wave.phaseCount++;
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
pin_state_t value = wave->getChannelState(/* channelIndex */i, index - 1);
wave->setChannelState(i, index, value);
pin_state_t value = wave.getChannelState(/* channelIndex */i, index - 1);
wave.setChannelState(i, index, value);
}
wave->setSwitchTime(index, angle);
wave->setChannelState(channelIndex, index, state);
wave.setSwitchTime(index, angle);
wave.setChannelState(channelIndex, index, state);
}
angle_t TriggerWaveform::getSwitchAngle(int index) const {
return getCycleDuration() * wave->getSwitchTime(index);
return getCycleDuration() * wave.getSwitchTime(index);
}
void setToothedWheelConfiguration(TriggerWaveform *s, int total, int skipped,
@ -761,7 +743,7 @@ void TriggerWaveform::initializeTriggerWaveform(operation_mode_e ambiguousOperat
version++;
if (!shapeDefinitionError) {
wave->checkSwitchTimes(getCycleDuration());
wave.checkSwitchTimes(getCycleDuration());
}
if (bothFrontsRequired && useOnlyRisingEdgeForTrigger) {

View File

@ -60,15 +60,6 @@ public:
#define TRIGGER_CHANNEL_COUNT 3
class trigger_shape_helper {
public:
trigger_shape_helper();
SingleChannelStateSequence channels[TRIGGER_CHANNEL_COUNT];
private:
pin_state_t pinStates[TRIGGER_CHANNEL_COUNT][PWM_PHASE_MAX_COUNT];
};
class Engine;
class TriggerState;
class TriggerFormDetails;
@ -199,8 +190,7 @@ public:
* but name is supposed to hint at the fact that decoders should not be assigning to it
* Please use "getTriggerSize()" macro or "getSize()" method to read this value
*/
MultiChannelStateSequence waveStorage; // DON'T USE - WILL BE REMOVED LATER
MultiChannelStateSequence * const wave;
MultiChannelStateSequenceWithData<PWM_PHASE_MAX_COUNT> wave;
// todo: add a runtime validation which would verify that this field was set properly
// todo: maybe even automate this flag calculation?
@ -276,14 +266,6 @@ public:
uint16_t findAngleIndex(TriggerFormDetails *details, angle_t angle) const;
private:
trigger_shape_helper h;
/**
* Working buffer for 'wave' instance
* Values are in the 0..1 range
*/
float switchTimesBuffer[PWM_PHASE_MAX_COUNT];
/**
* These angles are in trigger DESCRIPTION coordinates - i.e. the way you add events while declaring trigger shape
*/
@ -326,4 +308,4 @@ void setToothedWheelConfiguration(TriggerWaveform *s, int total, int skipped, op
#define TRIGGER_WAVEFORM(x) engine->triggerCentral.triggerShape.x
#define getTriggerSize() TRIGGER_WAVEFORM(wave->phaseCount)
#define getTriggerSize() TRIGGER_WAVEFORM(wave.phaseCount)

View File

@ -20,7 +20,7 @@ int getPreviousIndex(const int currentIndex, const int size) {
return (currentIndex + size - 1) % size;
}
bool needEvent(const int currentIndex, const MultiChannelStateSequence& mcss, int channelIndex) {
bool needEvent(const int currentIndex, const MultiChannelStateSequence & mcss, int channelIndex) {
int prevIndex = getPreviousIndex(currentIndex, mcss.phaseCount);
pin_state_t previousValue = mcss.getChannelState(channelIndex, /*phaseIndex*/prevIndex);
pin_state_t currentValue = mcss.getChannelState(channelIndex, /*phaseIndex*/currentIndex);
@ -106,7 +106,7 @@ static void updateTriggerWaveformIfNeeded(PwmConfig *state) {
TriggerWaveform *s = &engine->triggerCentral.triggerShape;
copyPwmParameters(state, s->wave);
copyPwmParameters(state, &s->wave);
state->safe.periodNt = -1; // this would cause loop re-initialization
}
}
@ -146,7 +146,7 @@ static void initTriggerPwm() {
setTriggerEmulatorRPM(engineConfiguration->triggerSimulatorFrequency);
triggerSignal.weComplexInit("position sensor",
&engine->executor,
s->wave,
&s->wave,
updateTriggerWaveformIfNeeded, (pwm_gen_callback*)emulatorApplyPinState);
hasInitTriggerEmulator = true;

View File

@ -33,7 +33,7 @@ int getSimulatedEventTime(const TriggerWaveform& shape, int i) {
int stateIndex = i % shape.getSize();
int loopIndex = i / shape.getSize();
return (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape.wave->getSwitchTime(stateIndex)));
return (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape.wave.getSwitchTime(stateIndex)));
}
void TriggerStimulatorHelper::feedSimulatedEvent(
@ -48,7 +48,7 @@ void TriggerStimulatorHelper::feedSimulatedEvent(
int time = getSimulatedEventTime(shape, i);
const MultiChannelStateSequence& multiChannelStateSequence = *shape.wave;
const auto & multiChannelStateSequence = shape.wave;
#if EFI_UNIT_TEST
int prevIndex = getPreviousIndex(stateIndex, shape.getSize());

View File

@ -103,31 +103,31 @@ static void configureFordAspireTriggerWaveform(TriggerWaveform * s) {
s->addEvent720(657.03, T_SECONDARY, TV_FALL);
s->addEvent720(720, T_PRIMARY, TV_FALL);
ASSERT_FLOAT_EQ(53.747 / 720, s->wave->getSwitchTime(0));
ASSERT_EQ( 1, s->wave->getChannelState(1, 0)) << "@0";
ASSERT_EQ( 1, s->wave->getChannelState(1, 0)) << "@0";
ASSERT_FLOAT_EQ(53.747 / 720, s->wave.getSwitchTime(0));
ASSERT_EQ( 1, s->wave.getChannelState(1, 0)) << "@0";
ASSERT_EQ( 1, s->wave.getChannelState(1, 0)) << "@0";
ASSERT_EQ( 0, s->wave->getChannelState(0, 1)) << "@1";
ASSERT_EQ( 0, s->wave->getChannelState(1, 1)) << "@1";
ASSERT_EQ( 0, s->wave.getChannelState(0, 1)) << "@1";
ASSERT_EQ( 0, s->wave.getChannelState(1, 1)) << "@1";
ASSERT_EQ( 0, s->wave->getChannelState(0, 2)) << "@2";
ASSERT_EQ( 1, s->wave->getChannelState(1, 2)) << "@2";
ASSERT_EQ( 0, s->wave.getChannelState(0, 2)) << "@2";
ASSERT_EQ( 1, s->wave.getChannelState(1, 2)) << "@2";
ASSERT_EQ( 0, s->wave->getChannelState(0, 3)) << "@3";
ASSERT_EQ( 0, s->wave->getChannelState(1, 3)) << "@3";
ASSERT_EQ( 0, s->wave.getChannelState(0, 3)) << "@3";
ASSERT_EQ( 0, s->wave.getChannelState(1, 3)) << "@3";
ASSERT_EQ( 1, s->wave->getChannelState(0, 4)) << "@4";
ASSERT_EQ( 1, s->wave->getChannelState(1, 5)) << "@5";
ASSERT_EQ( 0, s->wave->getChannelState(1, 8)) << "@8";
ASSERT_FLOAT_EQ(121.90 / 720, s->wave->getSwitchTime(1));
ASSERT_FLOAT_EQ(657.03 / 720, s->wave->getSwitchTime(8));
ASSERT_EQ( 1, s->wave.getChannelState(0, 4)) << "@4";
ASSERT_EQ( 1, s->wave.getChannelState(1, 5)) << "@5";
ASSERT_EQ( 0, s->wave.getChannelState(1, 8)) << "@8";
ASSERT_FLOAT_EQ(121.90 / 720, s->wave.getSwitchTime(1));
ASSERT_FLOAT_EQ(657.03 / 720, s->wave.getSwitchTime(8));
ASSERT_EQ( 0, s->wave->findAngleMatch(53.747 / 720.0)) << "expecting 0";
assertEqualsM("expecting not found", -1, s->wave->findAngleMatch(53 / 720.0));
ASSERT_EQ(7, s->wave->findAngleMatch(588.045 / 720.0));
ASSERT_EQ( 0, s->wave.findAngleMatch(53.747 / 720.0)) << "expecting 0";
assertEqualsM("expecting not found", -1, s->wave.findAngleMatch(53 / 720.0));
ASSERT_EQ(7, s->wave.findAngleMatch(588.045 / 720.0));
ASSERT_EQ( 0, s->wave->findInsertionAngle(23.747 / 720.0)) << "expecting 0";
ASSERT_EQ( 1, s->wave->findInsertionAngle(63.747 / 720.0)) << "expecting 1";
ASSERT_EQ( 0, s->wave.findInsertionAngle(23.747 / 720.0)) << "expecting 0";
ASSERT_EQ( 1, s->wave.findInsertionAngle(63.747 / 720.0)) << "expecting 1";
}
TEST(misc, testAngleResolver) {
@ -142,9 +142,9 @@ TEST(misc, testAngleResolver) {
engine->initializeTriggerWaveform();
assertEqualsM("index 2", 52.76, triggerFormDetails->eventAngles[3]); // this angle is relation to synch point
assertEqualsM("time 2", 0.3233, ts->wave->getSwitchTime(2));
assertEqualsM("time 2", 0.3233, ts->wave.getSwitchTime(2));
assertEqualsM("index 5", 412.76, triggerFormDetails->eventAngles[6]);
assertEqualsM("time 5", 0.5733, ts->wave->getSwitchTime(5));
assertEqualsM("time 5", 0.5733, ts->wave.getSwitchTime(5));
ASSERT_EQ(4, ts->getTriggerWaveformSynchPointIndex());

View File

@ -21,7 +21,7 @@ TEST(miata, miata_na_tdc) {
eth.setTimeAndInvokeEventsUs(time);
emulatorHelper.handleEmulatorCallback(
*shape.wave,
shape.wave,
i % shape.getSize());
}

View File

@ -22,9 +22,9 @@ public:
static void func(TriggerCallback *callback) {
int formIndex = callback->toothIndex % callback->form->getSize();
Engine *engine = callback->engine;
int value = callback->form->wave->getChannelState(0, formIndex);
int value = callback->form->wave.getChannelState(0, formIndex);
efitick_t nowNt = getTimeNowNt();
if (callback->isVvt) {
trigger_value_e v = value ? TV_RISE : TV_FALL;

View File

@ -466,10 +466,10 @@ TEST(misc, testTriggerDecoder) {
s->useOnlyRisingEdgeForTriggerTemp = false;
initializeSkippedToothTriggerWaveformExt(s, 2, 0, FOUR_STROKE_CAM_SENSOR);
assertEqualsM("shape size", s->getSize(), 4);
ASSERT_EQ(s->wave->getSwitchTime(0), 0.25);
ASSERT_EQ(s->wave->getSwitchTime(1), 0.5);
ASSERT_EQ(s->wave->getSwitchTime(2), 0.75);
ASSERT_EQ(s->wave->getSwitchTime(3), 1);
ASSERT_EQ(s->wave.getSwitchTime(0), 0.25);
ASSERT_EQ(s->wave.getSwitchTime(1), 0.5);
ASSERT_EQ(s->wave.getSwitchTime(2), 0.75);
ASSERT_EQ(s->wave.getSwitchTime(3), 1);
}