Merge remote-tracking branch 'upstream/master' into reset-overlap
This commit is contained in:
commit
8b0d6a26cf
|
@ -28,7 +28,7 @@ typedef struct __attribute__ ((packed)) {
|
||||||
// unfortunately all these fields are required by TS...
|
// unfortunately all these fields are required by TS...
|
||||||
bool priLevel : 1;
|
bool priLevel : 1;
|
||||||
bool secLevel : 1;
|
bool secLevel : 1;
|
||||||
bool trigger : 1;
|
bool isTDC : 1;
|
||||||
bool sync : 1;
|
bool sync : 1;
|
||||||
bool coil : 1;
|
bool coil : 1;
|
||||||
bool injector : 1;
|
bool injector : 1;
|
||||||
|
@ -61,10 +61,10 @@ int getCompositeRecordCount() {
|
||||||
int copyCompositeEvents(CompositeEvent *events) {
|
int copyCompositeEvents(CompositeEvent *events) {
|
||||||
for (int i = 0;i < NextIdx;i++) {
|
for (int i = 0;i < NextIdx;i++) {
|
||||||
CompositeEvent *event = &events[i];
|
CompositeEvent *event = &events[i];
|
||||||
event->timestamp = buffer[i].timestamp;
|
event->timestamp = SWAP_UINT32(buffer[i].timestamp);
|
||||||
event->primaryTrigger = buffer[i].priLevel;
|
event->primaryTrigger = buffer[i].priLevel;
|
||||||
event->secondaryTrigger = buffer[i].secLevel;
|
event->secondaryTrigger = buffer[i].secLevel;
|
||||||
event->trg = buffer[i].trigger;
|
event->isTDC = buffer[i].isTDC;
|
||||||
event->sync = buffer[i].sync;
|
event->sync = buffer[i].sync;
|
||||||
event->coil = buffer[i].coil;
|
event->coil = buffer[i].coil;
|
||||||
event->injector = buffer[i].injector;
|
event->injector = buffer[i].injector;
|
||||||
|
@ -81,7 +81,7 @@ static void SetNextCompositeEntry(efitick_t timestamp, bool trigger1, bool trigg
|
||||||
buffer[NextIdx].timestamp = SWAP_UINT32(nowUs);
|
buffer[NextIdx].timestamp = SWAP_UINT32(nowUs);
|
||||||
buffer[NextIdx].priLevel = trigger1;
|
buffer[NextIdx].priLevel = trigger1;
|
||||||
buffer[NextIdx].secLevel = trigger2;
|
buffer[NextIdx].secLevel = trigger2;
|
||||||
buffer[NextIdx].trigger = isTDC;
|
buffer[NextIdx].isTDC = isTDC;
|
||||||
buffer[NextIdx].sync = engine->triggerCentral.triggerState.shaft_is_synchronized;
|
buffer[NextIdx].sync = engine->triggerCentral.triggerState.shaft_is_synchronized;
|
||||||
buffer[NextIdx].coil = coil;
|
buffer[NextIdx].coil = coil;
|
||||||
buffer[NextIdx].injector = injector;
|
buffer[NextIdx].injector = injector;
|
||||||
|
@ -144,6 +144,7 @@ void LogTriggerTopDeadCenter(efitick_t timestamp DECLARE_ENGINE_PARAMETER_SUFFIX
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetNextCompositeEntry(timestamp, trigger1, trigger2, true PASS_ENGINE_PARAMETER_SUFFIX);
|
SetNextCompositeEntry(timestamp, trigger1, trigger2, true PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
SetNextCompositeEntry(timestamp + 10, trigger1, trigger2, false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogTriggerCoilState(efitick_t timestamp, bool state DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
void LogTriggerCoilState(efitick_t timestamp, bool state DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
|
|
|
@ -276,7 +276,7 @@ static const void * getStructAddr(int structId) {
|
||||||
case LDS_ENGINE_STATE_INDEX:
|
case LDS_ENGINE_STATE_INDEX:
|
||||||
return static_cast<engine_state2_s*>(&engine->engineState);
|
return static_cast<engine_state2_s*>(&engine->engineState);
|
||||||
case LDS_FUEL_TRIM_STATE_INDEX:
|
case LDS_FUEL_TRIM_STATE_INDEX:
|
||||||
return static_cast<wall_fuel_state*>(&engine->wallFuel[0]);
|
return static_cast<wall_fuel_state*>(&engine->injectionEvents.elements[0].wallFuel);
|
||||||
case LDS_TRIGGER_CENTRAL_STATE_INDEX:
|
case LDS_TRIGGER_CENTRAL_STATE_INDEX:
|
||||||
return static_cast<trigger_central_s*>(&engine->triggerCentral);
|
return static_cast<trigger_central_s*>(&engine->triggerCentral);
|
||||||
case LDS_TRIGGER_STATE_STATE_INDEX:
|
case LDS_TRIGGER_STATE_STATE_INDEX:
|
||||||
|
|
|
@ -562,11 +562,13 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
|
||||||
// 148
|
// 148
|
||||||
tsOutputChannels->fuelTankLevel = engine->sensors.fuelTankLevel;
|
tsOutputChannels->fuelTankLevel = engine->sensors.fuelTankLevel;
|
||||||
// 160
|
// 160
|
||||||
tsOutputChannels->wallFuelAmount = ENGINE(wallFuel[0]).getWallFuel();
|
const auto& wallFuel = ENGINE(injectionEvents.elements[0].wallFuel);
|
||||||
|
tsOutputChannels->wallFuelAmount = wallFuel.getWallFuel();
|
||||||
|
// 168
|
||||||
|
tsOutputChannels->wallFuelCorrection = wallFuel.wallFuelCorrection;
|
||||||
|
|
||||||
// 164
|
// 164
|
||||||
tsOutputChannels->iatCorrection = ENGINE(engineState.running.intakeTemperatureCoefficient);
|
tsOutputChannels->iatCorrection = ENGINE(engineState.running.intakeTemperatureCoefficient);
|
||||||
// 168
|
|
||||||
tsOutputChannels->wallFuelCorrection = ENGINE(wallFuel[0]).wallFuelCorrection;
|
|
||||||
// 184
|
// 184
|
||||||
tsOutputChannels->cltCorrection = ENGINE(engineState.running.coolantTemperatureCoefficient);
|
tsOutputChannels->cltCorrection = ENGINE(engineState.running.coolantTemperatureCoefficient);
|
||||||
// 188
|
// 188
|
||||||
|
|
|
@ -140,7 +140,6 @@ public:
|
||||||
IgnitionEventList ignitionEvents;
|
IgnitionEventList ignitionEvents;
|
||||||
#endif /* EFI_ENGINE_CONTROL */
|
#endif /* EFI_ENGINE_CONTROL */
|
||||||
|
|
||||||
WallFuel wallFuel[INJECTION_PIN_COUNT];
|
|
||||||
bool needToStopEngine(efitick_t nowNt) const;
|
bool needToStopEngine(efitick_t nowNt) const;
|
||||||
bool etbAutoTune = false;
|
bool etbAutoTune = false;
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "fl_stack.h"
|
#include "fl_stack.h"
|
||||||
#include "trigger_structure.h"
|
#include "trigger_structure.h"
|
||||||
|
#include "accel_enrichment.h"
|
||||||
|
|
||||||
#define MAX_INJECTION_OUTPUT_COUNT INJECTION_PIN_COUNT
|
#define MAX_INJECTION_OUTPUT_COUNT INJECTION_PIN_COUNT
|
||||||
#define MAX_WIRES_COUNT 2
|
#define MAX_WIRES_COUNT 2
|
||||||
|
@ -42,6 +43,8 @@ public:
|
||||||
* TODO: make watchdog decrement relevant counter
|
* TODO: make watchdog decrement relevant counter
|
||||||
*/
|
*/
|
||||||
bool isScheduled = false;
|
bool isScheduled = false;
|
||||||
|
|
||||||
|
WallFuel wallFuel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
EXTERN_ENGINE;
|
EXTERN_ENGINE;
|
||||||
|
|
||||||
fuel_Map3D_t fuelMap("fuel");
|
fuel_Map3D_t fuelMap("fuel");
|
||||||
static fuel_Map3D_t fuelPhaseMap("fl ph");
|
fuel_Map3D_t fuelPhaseMap("fl ph");
|
||||||
extern fuel_Map3D_t veMap;
|
extern fuel_Map3D_t veMap;
|
||||||
extern afr_Map3D_t afrMap;
|
extern afr_Map3D_t afrMap;
|
||||||
extern baroCorr_Map3D_t baroCorrMap;
|
extern baroCorr_Map3D_t baroCorrMap;
|
||||||
|
|
|
@ -208,9 +208,9 @@ static void resetAccel(void) {
|
||||||
engine->engineLoadAccelEnrichment.resetAE();
|
engine->engineLoadAccelEnrichment.resetAE();
|
||||||
engine->tpsAccelEnrichment.resetAE();
|
engine->tpsAccelEnrichment.resetAE();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(engine->wallFuel) / sizeof(engine->wallFuel[0]); i++)
|
for (unsigned int i = 0; i < efi::size(engine->injectionEvents.elements); i++)
|
||||||
{
|
{
|
||||||
engine->wallFuel[i].resetWF();
|
engine->injectionEvents.elements[i].wallFuel.resetWF();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,9 @@ void InjectorOutputPin::open() {
|
||||||
overlappingCounter++;
|
overlappingCounter++;
|
||||||
|
|
||||||
#if FUEL_MATH_EXTREME_LOGGING
|
#if FUEL_MATH_EXTREME_LOGGING
|
||||||
|
if (printFuelDebug) {
|
||||||
printf("turnInjectionPinHigh %s %d %d\r\n", name, overlappingCounter, (int)getTimeNowUs());
|
printf("turnInjectionPinHigh %s %d %d\r\n", name, overlappingCounter, (int)getTimeNowUs());
|
||||||
|
}
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||||
|
|
||||||
if (overlappingCounter > 1) {
|
if (overlappingCounter > 1) {
|
||||||
|
@ -106,7 +108,9 @@ void InjectorOutputPin::open() {
|
||||||
// * this is another kind of overlap which happens in case of a small duty cycle after a large duty cycle
|
// * this is another kind of overlap which happens in case of a small duty cycle after a large duty cycle
|
||||||
// */
|
// */
|
||||||
#if FUEL_MATH_EXTREME_LOGGING
|
#if FUEL_MATH_EXTREME_LOGGING
|
||||||
|
if (printFuelDebug) {
|
||||||
printf("overlapping, no need to touch pin %s %d\r\n", name, (int)getTimeNowUs());
|
printf("overlapping, no need to touch pin %s %d\r\n", name, (int)getTimeNowUs());
|
||||||
|
}
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||||
} else {
|
} else {
|
||||||
setHigh();
|
setHigh();
|
||||||
|
@ -135,13 +139,17 @@ void turnInjectionPinHigh(InjectionEvent *event) {
|
||||||
|
|
||||||
void InjectorOutputPin::close() {
|
void InjectorOutputPin::close() {
|
||||||
#if FUEL_MATH_EXTREME_LOGGING
|
#if FUEL_MATH_EXTREME_LOGGING
|
||||||
|
if (printFuelDebug) {
|
||||||
printf("InjectorOutputPin::close %s %d %d\r\n", name, overlappingCounter, (int)getTimeNowUs());
|
printf("InjectorOutputPin::close %s %d %d\r\n", name, overlappingCounter, (int)getTimeNowUs());
|
||||||
|
}
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||||
|
|
||||||
overlappingCounter--;
|
overlappingCounter--;
|
||||||
if (overlappingCounter > 0) {
|
if (overlappingCounter > 0) {
|
||||||
#if FUEL_MATH_EXTREME_LOGGING
|
#if FUEL_MATH_EXTREME_LOGGING
|
||||||
|
if (printFuelDebug) {
|
||||||
printf("was overlapping, no need to touch pin %s %d\r\n", name, (int)getTimeNowUs());
|
printf("was overlapping, no need to touch pin %s %d\r\n", name, (int)getTimeNowUs());
|
||||||
|
}
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||||
} else {
|
} else {
|
||||||
setLow();
|
setLow();
|
||||||
|
@ -185,8 +193,7 @@ void handleFuelInjectionEvent(int injEventIndex, InjectionEvent *event,
|
||||||
* x2 or /2?
|
* x2 or /2?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t injectorIndex = event->outputs[0]->injectorIndex;
|
const floatms_t injectionDuration = event->wallFuel.adjust(ENGINE(injectionDuration) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
const floatms_t injectionDuration = ENGINE(wallFuel[injectorIndex]).adjust(ENGINE(injectionDuration) PASS_ENGINE_PARAMETER_SUFFIX);
|
|
||||||
#if EFI_PRINTF_FUEL_DETAILS
|
#if EFI_PRINTF_FUEL_DETAILS
|
||||||
if (printFuelDebug) {
|
if (printFuelDebug) {
|
||||||
printf("fuel index=%d injectionDuration=%.2fms adjusted=%.2fms\n",
|
printf("fuel index=%d injectionDuration=%.2fms adjusted=%.2fms\n",
|
||||||
|
@ -320,7 +327,9 @@ static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIn
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FUEL_MATH_EXTREME_LOGGING
|
#if FUEL_MATH_EXTREME_LOGGING
|
||||||
|
if (printFuelDebug) {
|
||||||
scheduleMsg(logger, "handleFuel ind=%d %d", trgEventIndex, getRevolutionCounter());
|
scheduleMsg(logger, "handleFuel ind=%d %d", trgEventIndex, getRevolutionCounter());
|
||||||
|
}
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||||
|
|
||||||
ENGINE(tpsAccelEnrichment.onNewValue(Sensor::get(SensorType::Tps1).value_or(0) PASS_ENGINE_PARAMETER_SUFFIX));
|
ENGINE(tpsAccelEnrichment.onNewValue(Sensor::get(SensorType::Tps1).value_or(0) PASS_ENGINE_PARAMETER_SUFFIX));
|
||||||
|
|
|
@ -25,6 +25,10 @@ EXTERN_ENGINE;
|
||||||
extern bool verboseMode;
|
extern bool verboseMode;
|
||||||
#endif /* EFI_UNIT_TEST */
|
#endif /* EFI_UNIT_TEST */
|
||||||
|
|
||||||
|
#if EFI_PRINTF_FUEL_DETAILS || FUEL_MATH_EXTREME_LOGGING
|
||||||
|
extern bool printFuelDebug;
|
||||||
|
#endif // EFI_PRINTF_FUEL_DETAILS
|
||||||
|
|
||||||
static cyclic_buffer<int> ignitionErrorDetection;
|
static cyclic_buffer<int> ignitionErrorDetection;
|
||||||
static Logging *logger;
|
static Logging *logger;
|
||||||
|
|
||||||
|
@ -47,7 +51,7 @@ static void fireSparkBySettingPinLow(IgnitionEvent *event, IgnitionOutputPin *ou
|
||||||
#if SPARK_EXTREME_LOGGING
|
#if SPARK_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "spark goes low %d %s %d current=%d cnt=%d id=%d", getRevolutionCounter(), output->name, (int)getTimeNowUs(),
|
scheduleMsg(logger, "spark goes low %d %s %d current=%d cnt=%d id=%d", getRevolutionCounter(), output->name, (int)getTimeNowUs(),
|
||||||
output->currentLogicValue, output->outOfOrder, event->sparkId);
|
output->currentLogicValue, output->outOfOrder, event->sparkId);
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* SPARK_EXTREME_LOGGING */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* there are two kinds of 'out-of-order'
|
* there are two kinds of 'out-of-order'
|
||||||
|
@ -119,7 +123,9 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_
|
||||||
event->dwellPosition.setAngle(dwellStartAngle PASS_ENGINE_PARAMETER_SUFFIX);
|
event->dwellPosition.setAngle(dwellStartAngle PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
|
||||||
#if FUEL_MATH_EXTREME_LOGGING
|
#if FUEL_MATH_EXTREME_LOGGING
|
||||||
|
if (printFuelDebug) {
|
||||||
printf("addIgnitionEvent %s ind=%d\n", output->name, event->dwellPosition.triggerEventIndex);
|
printf("addIgnitionEvent %s ind=%d\n", output->name, event->dwellPosition.triggerEventIndex);
|
||||||
|
}
|
||||||
// scheduleMsg(logger, "addIgnitionEvent %s ind=%d", output->name, event->dwellPosition->eventIndex);
|
// scheduleMsg(logger, "addIgnitionEvent %s ind=%d", output->name, event->dwellPosition->eventIndex);
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||||
}
|
}
|
||||||
|
@ -223,7 +229,7 @@ static void startDwellByTurningSparkPinHigh(IgnitionEvent *event, IgnitionOutput
|
||||||
#if SPARK_EXTREME_LOGGING
|
#if SPARK_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "spark goes high %d %s %d current=%d cnt=%d id=%d", getRevolutionCounter(), output->name, (int)getTimeNowUs(),
|
scheduleMsg(logger, "spark goes high %d %s %d current=%d cnt=%d id=%d", getRevolutionCounter(), output->name, (int)getTimeNowUs(),
|
||||||
output->currentLogicValue, output->outOfOrder, event->sparkId);
|
output->currentLogicValue, output->outOfOrder, event->sparkId);
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* SPARK_EXTREME_LOGGING */
|
||||||
|
|
||||||
if (output->outOfOrder) {
|
if (output->outOfOrder) {
|
||||||
output->outOfOrder = false;
|
output->outOfOrder = false;
|
||||||
|
@ -308,7 +314,7 @@ bool scheduleOrQueue(AngleBasedEvent *event,
|
||||||
if (isPending) {
|
if (isPending) {
|
||||||
#if SPARK_EXTREME_LOGGING
|
#if SPARK_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "isPending thus not adding to queue index=%d rev=%d now=%d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs());
|
scheduleMsg(logger, "isPending thus not adding to queue index=%d rev=%d now=%d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs());
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* SPARK_EXTREME_LOGGING */
|
||||||
} else {
|
} else {
|
||||||
LL_APPEND2(ENGINE(angleBasedEventsHead), event, nextToothEvent);
|
LL_APPEND2(ENGINE(angleBasedEventsHead), event, nextToothEvent);
|
||||||
}
|
}
|
||||||
|
@ -350,7 +356,7 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI
|
||||||
#if SPARK_EXTREME_LOGGING
|
#if SPARK_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "scheduling sparkUp ind=%d %d %s now=%d %d later id=%d", trgEventIndex, getRevolutionCounter(), event->getOutputForLoggins()->name, (int)getTimeNowUs(), (int)chargeDelayUs,
|
scheduleMsg(logger, "scheduling sparkUp ind=%d %d %s now=%d %d later id=%d", trgEventIndex, getRevolutionCounter(), event->getOutputForLoggins()->name, (int)getTimeNowUs(), (int)chargeDelayUs,
|
||||||
event->sparkId);
|
event->sparkId);
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* SPARK_EXTREME_LOGGING */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -382,7 +388,7 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI
|
||||||
} else {
|
} else {
|
||||||
#if SPARK_EXTREME_LOGGING
|
#if SPARK_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "to queue sparkDown ind=%d %d %s now=%d for id=%d", trgEventIndex, getRevolutionCounter(), event->getOutputForLoggins()->name, (int)getTimeNowUs(), event->sparkEvent.position.triggerEventIndex);
|
scheduleMsg(logger, "to queue sparkDown ind=%d %d %s now=%d for id=%d", trgEventIndex, getRevolutionCounter(), event->getOutputForLoggins()->name, (int)getTimeNowUs(), event->sparkEvent.position.triggerEventIndex);
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* SPARK_EXTREME_LOGGING */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -461,7 +467,7 @@ static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex,
|
||||||
|
|
||||||
#if SPARK_EXTREME_LOGGING
|
#if SPARK_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "time to invoke ind=%d %d %d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs());
|
scheduleMsg(logger, "time to invoke ind=%d %d %d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs());
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* SPARK_EXTREME_LOGGING */
|
||||||
|
|
||||||
scheduleByAngle(
|
scheduleByAngle(
|
||||||
sDown,
|
sDown,
|
||||||
|
|
|
@ -111,6 +111,8 @@ public:
|
||||||
void open();
|
void open();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
int8_t getOverlappingCounter() const { return overlappingCounter; }
|
||||||
|
|
||||||
// todo: re-implement this injectorIndex via address manipulation to reduce memory usage?
|
// todo: re-implement this injectorIndex via address manipulation to reduce memory usage?
|
||||||
int8_t injectorIndex;
|
int8_t injectorIndex;
|
||||||
|
|
||||||
|
|
|
@ -480,7 +480,7 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
|
||||||
|
|
||||||
#if TRIGGER_EXTREME_LOGGING
|
#if TRIGGER_EXTREME_LOGGING
|
||||||
scheduleMsg(logger, "trigger %d %d %d", triggerIndexForListeners, getRevolutionCounter(), (int)getTimeNowUs());
|
scheduleMsg(logger, "trigger %d %d %d", triggerIndexForListeners, getRevolutionCounter(), (int)getTimeNowUs());
|
||||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
#endif /* TRIGGER_EXTREME_LOGGING */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here we invoke all the listeners - the main engine control logic is inside these listeners
|
* Here we invoke all the listeners - the main engine control logic is inside these listeners
|
||||||
|
|
|
@ -3,3 +3,4 @@ build/
|
||||||
gcov_working_area
|
gcov_working_area
|
||||||
triggers
|
triggers
|
||||||
triggers.txt
|
triggers.txt
|
||||||
|
*.logicdata
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
#define EFI_GPIO_HARDWARE TRUE
|
#define EFI_GPIO_HARDWARE TRUE
|
||||||
|
|
||||||
#define FUEL_MATH_EXTREME_LOGGING FALSE
|
#define FUEL_MATH_EXTREME_LOGGING TRUE
|
||||||
|
|
||||||
#define EFI_DEFAILED_LOGGING FALSE
|
#define EFI_DEFAILED_LOGGING FALSE
|
||||||
|
|
||||||
|
|
|
@ -103,12 +103,28 @@ void EngineTestHelper::writeEvents(const char *fileName) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mock a change of time and fire single RISE front event
|
* mock a change of time and fire single RISE front event
|
||||||
|
* DEPRECATED many usages should be migrated to
|
||||||
*/
|
*/
|
||||||
void EngineTestHelper::fireRise(float delayMs) {
|
void EngineTestHelper::fireRise(float delayMs) {
|
||||||
moveTimeForwardUs(MS2US(delayMs));
|
moveTimeForwardUs(MS2US(delayMs));
|
||||||
firePrimaryTriggerRise();
|
firePrimaryTriggerRise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EngineTestHelper::smartFireRise(float delayMs) {
|
||||||
|
smartMoveTimeForwardUs(MS2US(delayMs));
|
||||||
|
firePrimaryTriggerRise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EngineTestHelper::fireFall(float delayMs) {
|
||||||
|
moveTimeForwardUs(MS2US(delayMs));
|
||||||
|
firePrimaryTriggerFall();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EngineTestHelper::smartFireFall(float delayMs) {
|
||||||
|
smartMoveTimeForwardUs(MS2US(delayMs));
|
||||||
|
firePrimaryTriggerFall();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fire single RISE front event
|
* fire single RISE front event
|
||||||
*/
|
*/
|
||||||
|
@ -120,11 +136,6 @@ void EngineTestHelper::firePrimaryTriggerRise() {
|
||||||
engine->triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING, nowNt, engine, engine->engineConfigurationPtr, &persistentConfig);
|
engine->triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING, nowNt, engine, engine->engineConfigurationPtr, &persistentConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineTestHelper::fireFall(float delayMs) {
|
|
||||||
moveTimeForwardUs(MS2US(delayMs));
|
|
||||||
firePrimaryTriggerFall();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EngineTestHelper::firePrimaryTriggerFall() {
|
void EngineTestHelper::firePrimaryTriggerFall() {
|
||||||
efitick_t nowNt = getTimeNowNt();
|
efitick_t nowNt = getTimeNowNt();
|
||||||
Engine *engine = &this->engine;
|
Engine *engine = &this->engine;
|
||||||
|
@ -149,6 +160,13 @@ void EngineTestHelper::fireTriggerEvents2(int count, float durationMs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EngineTestHelper::smartFireTriggerEvents2(int count, float durationMs) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
smartFireRise(durationMs);
|
||||||
|
smartFireFall(durationMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EngineTestHelper::clearQueue() {
|
void EngineTestHelper::clearQueue() {
|
||||||
engine.executor.executeAll(99999999); // this is needed to clear 'isScheduled' flag
|
engine.executor.executeAll(99999999); // this is needed to clear 'isScheduled' flag
|
||||||
ASSERT_EQ( 0, engine.executor.size()) << "Failed to clearQueue";
|
ASSERT_EQ( 0, engine.executor.size()) << "Failed to clearQueue";
|
||||||
|
@ -169,6 +187,33 @@ void EngineTestHelper::moveTimeForwardUs(int deltaTimeUs) {
|
||||||
timeNowUs += deltaTimeUs;
|
timeNowUs += deltaTimeUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method executed all pending events wile
|
||||||
|
*/
|
||||||
|
void EngineTestHelper::smartMoveTimeForwardUs(int deltaTimeUs) {
|
||||||
|
if (printTriggerDebug || printFuelDebug) {
|
||||||
|
printf("smartMoveTimeForwardUs %.1fms\r\n", deltaTimeUs / 1000.0);
|
||||||
|
}
|
||||||
|
int targetTime = timeNowUs + deltaTimeUs;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
scheduling_s* nextScheduledEvent = engine.executor.getHead();
|
||||||
|
if (nextScheduledEvent == nullptr) {
|
||||||
|
// nothing pending - we are done here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int nextEventTime = nextScheduledEvent->momentX;
|
||||||
|
if (nextEventTime > targetTime) {
|
||||||
|
// next event is too far in the future
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timeNowUs = nextEventTime;
|
||||||
|
engine.executor.executeAll(timeNowUs);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeNowUs = targetTime;
|
||||||
|
}
|
||||||
|
|
||||||
efitimeus_t EngineTestHelper::getTimeNowUs(void) {
|
efitimeus_t EngineTestHelper::getTimeNowUs(void) {
|
||||||
return timeNowUs;
|
return timeNowUs;
|
||||||
}
|
}
|
||||||
|
@ -208,9 +253,9 @@ static AngleBasedEvent * getElementAtIndexForUnitText(int index, Engine *engine)
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
#if EFI_UNIT_TEST
|
#if EFI_UNIT_TEST
|
||||||
firmwareError(OBD_PCM_Processor_Fault, "getForUnitText: null");
|
firmwareError(OBD_PCM_Processor_Fault, "getElementAtIndexForUnitText: null");
|
||||||
#endif /* EFI_UNIT_TEST */
|
#endif /* EFI_UNIT_TEST */
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
AngleBasedEvent * EngineTestHelper::assertTriggerEvent(const char *msg,
|
AngleBasedEvent * EngineTestHelper::assertTriggerEvent(const char *msg,
|
||||||
|
|
|
@ -36,8 +36,22 @@ public:
|
||||||
|
|
||||||
void applyTriggerWaveform();
|
void applyTriggerWaveform();
|
||||||
void setTriggerType(trigger_type_e trigger DECLARE_ENGINE_PARAMETER_SUFFIX);
|
void setTriggerType(trigger_type_e trigger DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
/**
|
||||||
|
* DEPRECATED these methods do not execute events on the queue
|
||||||
|
*/
|
||||||
void fireRise(float delayMs);
|
void fireRise(float delayMs);
|
||||||
void fireFall(float delayMs);
|
void fireFall(float delayMs);
|
||||||
|
void moveTimeForwardUs(int deltaTimeUs);
|
||||||
|
void fireTriggerEvents2(int count, float delayMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these methods execute events while moving time forward
|
||||||
|
* todo: better naming convention?
|
||||||
|
*/
|
||||||
|
void smartFireRise(float delayMs);
|
||||||
|
void smartFireFall(float delayMs);
|
||||||
|
void smartMoveTimeForwardUs(int deltaTimeUs);
|
||||||
|
void smartFireTriggerEvents2(int count, float delayMs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See also #fireRise() which would also move time forward
|
* See also #fireRise() which would also move time forward
|
||||||
|
@ -49,7 +63,6 @@ public:
|
||||||
void firePrimaryTriggerFall();
|
void firePrimaryTriggerFall();
|
||||||
void fireTriggerEvents(int count);
|
void fireTriggerEvents(int count);
|
||||||
void fireTriggerEventsWithDuration(float delayMs);
|
void fireTriggerEventsWithDuration(float delayMs);
|
||||||
void fireTriggerEvents2(int count, float delayMs);
|
|
||||||
void clearQueue();
|
void clearQueue();
|
||||||
|
|
||||||
scheduling_s * assertEvent5(const char *msg, int index, void *callback, efitime_t expectedTimestamp);
|
scheduling_s * assertEvent5(const char *msg, int index, void *callback, efitime_t expectedTimestamp);
|
||||||
|
@ -65,7 +78,6 @@ public:
|
||||||
|
|
||||||
int executeActions();
|
int executeActions();
|
||||||
void moveTimeForwardMs(float deltaTimeMs);
|
void moveTimeForwardMs(float deltaTimeMs);
|
||||||
void moveTimeForwardUs(int deltaTimeUs);
|
|
||||||
efitimeus_t getTimeNowUs(void);
|
efitimeus_t getTimeNowUs(void);
|
||||||
|
|
||||||
void writeEvents(const char *fileName);
|
void writeEvents(const char *fileName);
|
||||||
|
|
|
@ -35,6 +35,10 @@ int TestExecutor::size() {
|
||||||
return schedulingQueue.size();
|
return schedulingQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduling_s* TestExecutor::getHead() {
|
||||||
|
return schedulingQueue.getHead();
|
||||||
|
}
|
||||||
|
|
||||||
scheduling_s* TestExecutor::getForUnitTest(int index) {
|
scheduling_s* TestExecutor::getForUnitTest(int index) {
|
||||||
return schedulingQueue.getElementAtIndexForUnitText(index);
|
return schedulingQueue.getElementAtIndexForUnitText(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@ public:
|
||||||
void clear();
|
void clear();
|
||||||
int executeAll(efitime_t now);
|
int executeAll(efitime_t now);
|
||||||
int size();
|
int size();
|
||||||
scheduling_s* getForUnitTest(int index);
|
scheduling_s * getHead();
|
||||||
|
scheduling_s * getForUnitTest(int index);
|
||||||
|
|
||||||
void setMockExecutor(ExecutorInterface* exec);
|
void setMockExecutor(ExecutorInterface* exec);
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#define MAX_STRING_SIZE 40
|
#define MAX_STRING_SIZE 40
|
||||||
|
|
||||||
static char channelNames[][MAX_STRING_SIZE] = { "Primary", "Secondary", "Trg",
|
static char channelNames[][MAX_STRING_SIZE] = { "Primary", "Secondary", "TDC",
|
||||||
"Sync", "Coil", "Injector", "Channel 6", "Channel 7" };
|
"Sync", "Coil", "Injector", "Channel 6", "Channel 7" };
|
||||||
|
|
||||||
static int CHANNEL_FLAGS[] = { 0x13458b, 0x0000ff, 0x00a0f9, 0x00ffff, 0x00ff00,
|
static int CHANNEL_FLAGS[] = { 0x13458b, 0x0000ff, 0x00a0f9, 0x00ffff, 0x00ff00,
|
||||||
|
@ -378,7 +378,7 @@ static int getChannelState(int ch, CompositeEvent *event) {
|
||||||
case 1:
|
case 1:
|
||||||
return event->secondaryTrigger;
|
return event->secondaryTrigger;
|
||||||
case 2:
|
case 2:
|
||||||
return event->trg;
|
return event->isTDC;
|
||||||
case 3:
|
case 3:
|
||||||
return event->sync;
|
return event->sync;
|
||||||
case 4:
|
case 4:
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct CompositeEvent {
|
||||||
int timestamp;
|
int timestamp;
|
||||||
bool primaryTrigger;
|
bool primaryTrigger;
|
||||||
bool secondaryTrigger;
|
bool secondaryTrigger;
|
||||||
bool trg;
|
bool isTDC;
|
||||||
bool sync;
|
bool sync;
|
||||||
bool coil;
|
bool coil;
|
||||||
bool injector;
|
bool injector;
|
||||||
|
|
|
@ -8,13 +8,12 @@
|
||||||
|
|
||||||
static CompositeEvent events[100];
|
static CompositeEvent events[100];
|
||||||
|
|
||||||
|
static void setEvent(CompositeEvent *events, int index,
|
||||||
void setEvent(CompositeEvent *events, int index,
|
int timestamp, bool primaryTrigger, bool secondaryTrigger, bool isTDC, bool sync, bool coil, bool injector) {
|
||||||
int timestamp, bool primaryTrigger, bool secondaryTrigger, bool trg, bool sync, bool coil, bool injector) {
|
|
||||||
events[index].timestamp = timestamp;
|
events[index].timestamp = timestamp;
|
||||||
events[index].primaryTrigger = primaryTrigger;
|
events[index].primaryTrigger = primaryTrigger;
|
||||||
events[index].secondaryTrigger = secondaryTrigger;
|
events[index].secondaryTrigger = secondaryTrigger;
|
||||||
events[index].trg = trg;
|
events[index].isTDC = isTDC;
|
||||||
events[index].sync = sync;
|
events[index].sync = sync;
|
||||||
events[index].coil = coil;
|
events[index].coil = coil;
|
||||||
events[index].injector = injector;
|
events[index].injector = injector;
|
||||||
|
@ -23,7 +22,6 @@ void setEvent(CompositeEvent *events, int index,
|
||||||
void runLogicdataSandbox() {
|
void runLogicdataSandbox() {
|
||||||
printf(".logicdata Sandbox 20200719\n");
|
printf(".logicdata Sandbox 20200719\n");
|
||||||
|
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
setEvent(events, index++, 10, false, false, false, false, false, false);
|
setEvent(events, index++, 10, false, false, false, false, false, false);
|
||||||
setEvent(events, index++, 20, true, false, true, false, false, false);
|
setEvent(events, index++, 20, true, false, true, false, false, false);
|
||||||
|
|
|
@ -7,37 +7,106 @@
|
||||||
|
|
||||||
#include "engine_test_helper.h"
|
#include "engine_test_helper.h"
|
||||||
|
|
||||||
|
static void doRevolution(EngineTestHelper& eth, int periodMs) {
|
||||||
|
float halfToothTime = (periodMs / 6.0f) / 2;
|
||||||
|
|
||||||
|
eth.fireRise(halfToothTime);
|
||||||
|
eth.fireFall(halfToothTime);
|
||||||
|
eth.fireRise(halfToothTime);
|
||||||
|
eth.fireFall(halfToothTime);
|
||||||
|
eth.fireRise(halfToothTime);
|
||||||
|
eth.fireFall(halfToothTime);
|
||||||
|
|
||||||
|
// now missing tooth
|
||||||
|
eth.fireRise(halfToothTime);
|
||||||
|
eth.fireFall(3 * halfToothTime);
|
||||||
|
|
||||||
|
// This tooth is the sync point!
|
||||||
|
eth.fireRise(halfToothTime);
|
||||||
|
eth.fireFall(halfToothTime);
|
||||||
|
}
|
||||||
|
|
||||||
// https://github.com/rusefi/rusefi/issues/1592
|
// https://github.com/rusefi/rusefi/issues/1592
|
||||||
TEST(fuelControl, transitionIssue1592) {
|
TEST(fuelControl, transitionIssue1592) {
|
||||||
|
|
||||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||||
setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð, IM_SEQUENTIAL);
|
setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð, IM_SEQUENTIAL);
|
||||||
|
|
||||||
eth.fireTriggerEvents2(4 /* count */ , 600 /* ms */);
|
// This is easiest to trip on a wheel that requires sync
|
||||||
|
engineConfiguration->trigger.customTotalToothCount = 6;
|
||||||
|
engineConfiguration->trigger.customSkippedToothCount = 1;
|
||||||
|
eth.setTriggerType(TT_TOOTHED_WHEEL PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
engineConfiguration->ambiguousOperationMode = FOUR_STROKE_CAM_SENSOR;
|
||||||
|
engineConfiguration->isFasterEngineSpinUpEnabled = true;
|
||||||
|
|
||||||
ASSERT_EQ(CRANKING, engine->rpmCalculator.getState());
|
engineConfiguration->fuelAlgorithm = LM_ALPHA_N;
|
||||||
ASSERT_EQ( 100, GET_RPM()) << "spinning-RPM#1";
|
|
||||||
|
|
||||||
ASSERT_EQ(IM_SIMULTANEOUS, ENGINE(getCurrentInjectionMode(PASS_ENGINE_PARAMETER_SIGNATURE)));
|
extern fuel_Map3D_t fuelMap;
|
||||||
|
fuelMap.setAll(13);
|
||||||
|
extern fuel_Map3D_t fuelPhaseMap;
|
||||||
|
fuelPhaseMap.setAll(0);
|
||||||
|
|
||||||
|
engineConfiguration->globalTriggerAngleOffset = 20;
|
||||||
|
|
||||||
|
// Yes, this is a ton of fuel but it makes the repro easier
|
||||||
|
engineConfiguration->cranking.baseFuel = 89;
|
||||||
|
engineConfiguration->cranking.rpm = 500;
|
||||||
|
|
||||||
|
// Test the transition from batch cranking to sequential running
|
||||||
|
engineConfiguration->crankingInjectionMode = IM_BATCH;
|
||||||
|
engineConfiguration->twoWireBatchInjection = true;
|
||||||
|
|
||||||
|
|
||||||
eth.fireRise(150);
|
// First sync point will schedule cranking pulse since we're in "faster spin up" mode
|
||||||
eth.fireFall(150);
|
doRevolution(eth, 150);
|
||||||
|
|
||||||
eth.fireRise(150);
|
{
|
||||||
eth.fireFall(150);
|
// Injector 2 should be scheduled to open then close
|
||||||
|
void* inj2 = reinterpret_cast<void*>(&engine->injectionEvents.elements[1]);
|
||||||
|
|
||||||
eth.fireRise(150);
|
ASSERT_EQ(engine->executor.size(), 2);
|
||||||
eth.fireFall(150);
|
|
||||||
|
|
||||||
ASSERT_EQ( 400, GET_RPM()) << "running-RPM#1";
|
// Check that the action is correct - we don't care about the timing necessarily
|
||||||
|
auto sched_open = engine->executor.getForUnitTest(0);
|
||||||
|
ASSERT_EQ(sched_open->action.getArgument(), inj2);
|
||||||
|
ASSERT_EQ(sched_open->action.getCallback(), &turnInjectionPinHigh);
|
||||||
|
|
||||||
ASSERT_EQ(IM_SIMULTANEOUS, ENGINE(getCurrentInjectionMode(PASS_ENGINE_PARAMETER_SIGNATURE)));
|
auto sched_close = engine->executor.getForUnitTest(1);
|
||||||
|
// Next action should be closing the same injector
|
||||||
|
ASSERT_EQ(sched_close->action.getArgument(), inj2);
|
||||||
|
ASSERT_EQ(sched_close->action.getCallback(), &turnInjectionPinLow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the first of those two events - the injector opens, but doesn't yet close.
|
||||||
|
engine->executor.executeAll(getTimeNowUs() + MS2US(35));
|
||||||
|
|
||||||
|
// Check that queue got shorter, and overlap counters were incremented on injectors 2/3 (batch mode, remember?)
|
||||||
|
{
|
||||||
|
// Check that it was exec'd
|
||||||
|
ASSERT_EQ(engine->executor.size(), 1);
|
||||||
|
|
||||||
|
// Injectors 2/3 should currently be open
|
||||||
|
EXPECT_EQ(enginePins.injectors[0].getOverlappingCounter(), 0);
|
||||||
|
EXPECT_EQ(enginePins.injectors[1].getOverlappingCounter(), 1);
|
||||||
|
EXPECT_EQ(enginePins.injectors[2].getOverlappingCounter(), 1);
|
||||||
|
EXPECT_EQ(enginePins.injectors[3].getOverlappingCounter(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second sync point will transition to running
|
||||||
|
// This needs to reset overlapping state as it may reschedule injector openings
|
||||||
|
doRevolution(eth, 150);
|
||||||
|
|
||||||
|
// Injectors should all be closed immediately after mode change
|
||||||
|
EXPECT_EQ(enginePins.injectors[0].getOverlappingCounter(), 0);
|
||||||
|
|
||||||
|
// !!!!!!!!! BUG !!!!!!!!!!!!!!!
|
||||||
|
// These next two should be equal to 0, not 1
|
||||||
|
EXPECT_EQ(enginePins.injectors[1].getOverlappingCounter(), 1);
|
||||||
|
EXPECT_EQ(enginePins.injectors[2].getOverlappingCounter(), 1);
|
||||||
|
// !!!!!!!!! BUG !!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
EXPECT_EQ(enginePins.injectors[3].getOverlappingCounter(), 0);
|
||||||
|
|
||||||
|
|
||||||
eth.writeEvents("transitionIssue1592.logicdata");
|
|
||||||
|
|
||||||
|
eth.writeEvents("fuel_schedule_transition_issue_1592.logicdata");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,12 @@ TEST(scheduler, dwellIssue796) {
|
||||||
ASSERT_EQ(300000, ENGINE(rpmCalculator.oneDegreeUs) * 180);
|
ASSERT_EQ(300000, ENGINE(rpmCalculator.oneDegreeUs) * 180);
|
||||||
|
|
||||||
// with just a bit much time between events integer RPM goes down one full percent
|
// with just a bit much time between events integer RPM goes down one full percent
|
||||||
eth.fireRise(601);
|
eth.smartFireRise(601);
|
||||||
eth.fireFall(600);
|
eth.smartFireFall(600);
|
||||||
ASSERT_NEAR( 99, GET_RPM(), EPS3D) << "spinning-RPM#2";
|
ASSERT_NEAR( 99, GET_RPM(), EPS3D) << "spinning-RPM#2";
|
||||||
// while integer RPM value is 1% away from rpm=100, below oneDegreeUs is much closer to RPM=100 value
|
// while integer RPM value is 1% away from rpm=100, below oneDegreeUs is much closer to RPM=100 value
|
||||||
ASSERT_EQ(300250, (int)(ENGINE(rpmCalculator.oneDegreeUs) * 180));
|
ASSERT_EQ(300250, (int)(ENGINE(rpmCalculator.oneDegreeUs) * 180));
|
||||||
|
|
||||||
|
eth.writeEvents("dwell_issue_1592.logicdata");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,11 @@ TEST(fuel, testWallWettingEnrichmentMath) {
|
||||||
|
|
||||||
engine->rpmCalculator.setRpmValue(3000 PASS_ENGINE_PARAMETER_SUFFIX);
|
engine->rpmCalculator.setRpmValue(3000 PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
|
||||||
|
WallFuel wallFuel;
|
||||||
|
|
||||||
// each invocation of 'adjust' changes WallWetting internal state
|
// each invocation of 'adjust' changes WallWetting internal state
|
||||||
ASSERT_NEAR(16.6666, ENGINE(wallFuel[0]).adjust(10.0 PASS_ENGINE_PARAMETER_SUFFIX), EPS4D);
|
ASSERT_NEAR(16.6666, wallFuel.adjust(10.0 PASS_ENGINE_PARAMETER_SUFFIX), EPS4D);
|
||||||
ASSERT_NEAR(16.198, ENGINE(wallFuel[0]).adjust(10.0 PASS_ENGINE_PARAMETER_SUFFIX), EPS4D);
|
ASSERT_NEAR(16.198, wallFuel.adjust(10.0 PASS_ENGINE_PARAMETER_SUFFIX), EPS4D);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(fuel, testWallWettingEnrichmentScheduling) {
|
TEST(fuel, testWallWettingEnrichmentScheduling) {
|
||||||
|
@ -38,11 +40,11 @@ TEST(fuel, testWallWettingEnrichmentScheduling) {
|
||||||
int expectedInvocationCounter = 1;
|
int expectedInvocationCounter = 1;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ASSERT_EQ(expectedInvocationCounter, ENGINE(wallFuel[i]).invocationCounter);
|
ASSERT_EQ(expectedInvocationCounter, ENGINE(injectionEvents.elements[i]).wallFuel.invocationCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cylinder 5 doesn't exist - shouldn't have been called!
|
// Cylinder 5 doesn't exist - shouldn't have been called!
|
||||||
ASSERT_EQ(0, ENGINE(wallFuel[5]).invocationCounter);
|
ASSERT_EQ(0, ENGINE(injectionEvents.elements[5]).wallFuel.invocationCounter);
|
||||||
|
|
||||||
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||||
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||||
|
@ -50,9 +52,9 @@ TEST(fuel, testWallWettingEnrichmentScheduling) {
|
||||||
|
|
||||||
// still same 1 per cylinder - wall wetting is NOT invoked from 'periodicFastCallback'
|
// still same 1 per cylinder - wall wetting is NOT invoked from 'periodicFastCallback'
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ASSERT_EQ(expectedInvocationCounter, ENGINE(wallFuel[i]).invocationCounter);
|
ASSERT_EQ(expectedInvocationCounter, ENGINE(injectionEvents.elements[i]).wallFuel.invocationCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cylinder 5 doesn't exist - shouldn't have been called!
|
// Cylinder 5 doesn't exist - shouldn't have been called!
|
||||||
ASSERT_EQ(0, ENGINE(wallFuel[5]).invocationCounter);
|
ASSERT_EQ(0, ENGINE(injectionEvents.elements[5]).wallFuel.invocationCounter);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue