auto-sync

This commit is contained in:
rusEfi 2016-09-03 02:03:32 -04:00
parent f9d77c4d90
commit 4f5e4546aa
4 changed files with 78 additions and 45 deletions

View File

@ -90,6 +90,8 @@ public:
OutputSignal fuelActuators[MAX_INJECTION_OUTPUT_COUNT];
OutputSignal overlappingFuelActuator[MAX_NUMBER_OF_CYLINDERS];
bool wasOverlapping[MAX_INJECTION_OUTPUT_COUNT];
float fsioLastValue[LE_COMMAND_COUNT];
/**

View File

@ -962,6 +962,7 @@ void resetConfigurationExt(Logging * logger, engine_type_e engineType DECLARE_EN
engine_configuration2_s::engine_configuration2_s() {
injectionEvents = &injectionEvents0;
processing = &injectionEvents1;
memset(wasOverlapping, 0, sizeof(wasOverlapping));
}
void applyNonPersistentConfiguration(Logging * logger DECLARE_ENGINE_PARAMETER_S) {

View File

@ -150,6 +150,8 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int eventIndex, bool limitedF
OutputSignal *signal = &ENGINE(engineConfiguration2)->fuelActuators[eventIndex];
engine->engineConfiguration2->wasOverlapping[eventIndex] = event->isOverlapping;
if (event->isSimultanious) {
/**
* this is pretty much copy-paste of 'scheduleOutput'
@ -171,6 +173,7 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int eventIndex, bool limitedF
#endif
// we are in this branch of code only in case of NOT IM_SIMULTANEOUS injection
// we are ignoring low RPM in order not to handle "engine was stopped to engine now running" transition
if (rpm > 2 * engineConfiguration->cranking.rpm) {
const char *outputName = event->output->name;
if (prevOutputName == outputName) {
@ -197,6 +200,26 @@ static ALWAYS_INLINE void handleFuel(bool limitedFuel, uint32_t currentEventInde
InjectionEventList *injectionEvents = &fs->injectionEvents;
if (currentEventIndex == 0) {
// here we need to avoid a fuel miss due to changes between previous and current fuel schedule
for (int injEventIndex = 0; injEventIndex < injectionEvents->size; injEventIndex++) {
InjectionEvent *event = &injectionEvents->elements[injEventIndex];
if (!engine->engineConfiguration2->wasOverlapping[injEventIndex] &&
event->isOverlapping) {
// we are here if new fuel schedule is crossing engine cycle boundary with this event
OutputSignal *specialSignal = &ENGINE(engineConfiguration2)->overlappingFuelActuator[injEventIndex];
NamedOutputPin *output = &enginePins.injectors[event->injectorIndex];
// todo: recalc fuel? account for wetting?
floatms_t injectionDuration = ENGINE(fuelMs);
scheduleOutput(specialSignal, getTimeNowUs(), 0, MS2US(injectionDuration), output);
}
}
}
if (!fs->hasEvents[currentEventIndex])
return;

View File

@ -740,51 +740,54 @@ void testFuelSchedulerBug299(void) {
int engineLoadIndex = findIndex(config->fuelLoadBins, FUEL_LOAD_COUNT, testMafValue);
assertEquals(8, engineLoadIndex);
setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35);
setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 35);
setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 25);
setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 25);
engine->periodicFastCallback(PASS_ENGINE_PARAMETER_F);
assertEqualsM("fuel#2", 17.5, engine->fuelMs);
assertEqualsM("duty for maf=3", 87.5, getInjectorDutyCycle(eth.engine.rpmCalculator.getRpm(PASS_ENGINE_PARAMETER_F) PASS_ENGINE_PARAMETER));
assertEqualsM("fuel#2", 12.5, engine->fuelMs);
assertEqualsM("duty for maf=3", 62.5, getInjectorDutyCycle(eth.engine.rpmCalculator.getRpm(PASS_ENGINE_PARAMETER_F) PASS_ENGINE_PARAMETER));
assertEqualsM("qs#1", 0, schedulingQueue.size());
timeNow += MS2US(20);
eth.firePrimaryTriggerRise();
// time...|0.......|10......|20......|30......|40......|50......|60......|
// inj #0 |........|.#######|########|.#######|########|........|........|
// inj #1 |.#######|########|.#######|########|........|........|........|
assertInjectorUpEvent("04@0", 0, MS2US(2.5), 1);
assertInjectorUpEvent("04@1", 1, MS2US(12.5), 0);
assertInjectorDownEvent("04@2", 2, MS2US(20), 1);
assertInjectorUpEvent("04@3", 3, MS2US(22.5), 1);
assertInjectorDownEvent("04@4", 4, MS2US(30), 0);
assertInjectorUpEvent("04@5", 5, MS2US(32.5), 0);
assertInjectorDownEvent("04@6", 6, MS2US(40.0), 1);
assertInjectorDownEvent("04@7", 7, MS2US(50.0), 0);
// inj #0 |########|##...###|########|.....###|########|........|........|
// inj #1 |.....###|########|....####|########|........|........|........|
assertEqualsM("qs#4", 10, schedulingQueue.size());
assertInjectorUpEvent("04@0", 0, MS2US(0), 0);
assertInjectorUpEvent("04@1", 1, MS2US(7.5), 1);
assertInjectorDownEvent("04@2", 2, MS2US(12.5), 0);
assertInjectorUpEvent("04@3", 3, MS2US(17.5), 0);
assertInjectorDownEvent("04@4", 4, MS2US(20), 1);
assertInjectorUpEvent("04@5", 5, MS2US(27.5), 1);
assertInjectorDownEvent("04@6", 6, MS2US(30), 0);
assertInjectorUpEvent("04@7", 7, MS2US(37.5), 0);
assertInjectorDownEvent("04@8", 8, MS2US(40.0), 1);
assertInjectorDownEvent("04@9", 9, MS2US(50.0), 0);
assertEqualsM("qs#4", 8, schedulingQueue.size());
assertEqualsM("exec#4", 0, schedulingQueue.executeAll(timeNow));
assertEqualsM("exec#4", 1, schedulingQueue.executeAll(timeNow));
timeNow += MS2US(20);
eth.firePrimaryTriggerFall();
assertEqualsM("qs#2", 8, schedulingQueue.size());
assertEqualsM("qs#2", 9, schedulingQueue.size());
assertEqualsM("rev cnt#5", 5, engine->rpmCalculator.getRevolutionCounter());
// using old fuel schedule - but already wider pulses
// time...|-20.....|-10.....|0.......|10......|20......|30......|40......|
// inj #0 |........|..######|########|..######|########|........|........|
// inj #1 |..######|########|..######|########|........|........|........|
assertInjectorUpEvent("5@0", 0, MS2US(-17.5), 1);
assertInjectorUpEvent("5@1", 1, MS2US(-7.5), 0);
assertInjectorDownEvent("5@2", 2, MS2US(0), 1);
assertInjectorUpEvent("5@3", 3, MS2US(2.5), 1);
// inj #0 |........|.....###|########|.....###|########|........|........|
// inj #1 |.....###|########|.....###|########|........|........|........|
assertInjectorUpEvent("5@0", 0, MS2US(-12.5), 1);
assertInjectorDownEvent("5@1", 1, MS2US(-7.5), 0);
assertInjectorUpEvent("5@2", 2, MS2US(-2.5), 0);
assertInjectorDownEvent("5@3", 3, MS2US(0), 1);
assertInjectorUpEvent("5@4", 4, MS2US(7.5), 1);
assertInjectorDownEvent("5@4", 4, MS2US(10), 0);
assertInjectorUpEvent("5@5", 5, MS2US(12.5), 0);
assertInjectorDownEvent("5@6", 6, MS2US(20.0), 1);
assertInjectorDownEvent("5@7", 7, MS2US(30.0), 0);
assertEqualsM("exec#5", 3, schedulingQueue.executeAll(timeNow));
assertInjectorDownEvent("5@4", 5, MS2US(10), 0);
assertInjectorUpEvent("5@6", 6, MS2US(17.5), 0);
assertInjectorDownEvent("5@7", 7, MS2US(20.0), 1);
assertInjectorDownEvent("5@8", 8, MS2US(30.0), 0);
assertEqualsM("exec#5", 4, schedulingQueue.executeAll(timeNow));
/**
* one more revolution
@ -794,25 +797,25 @@ void testFuelSchedulerBug299(void) {
t = ENGINE(engineConfiguration2)->injectionEvents;
assertEqualsM("t.s", 4, t->injectionEvents.size);
assertInjectionEvent(&t->injectionEvents.elements[0], 0, 0, 225, false);
assertInjectionEvent(&t->injectionEvents.elements[1], 1, 0, 405, false);
assertInjectionEvent(&t->injectionEvents.elements[2], 0, 0, 585, true);
assertInjectionEvent(&t->injectionEvents.elements[3], 1, 0, 45, false);
assertInjectionEvent(&t->injectionEvents.elements[0], 0, 0, 315, false);
assertInjectionEvent(&t->injectionEvents.elements[1], 1, 0, 495, false);
assertInjectionEvent(&t->injectionEvents.elements[2], 0, 0, 675, true);
assertInjectionEvent(&t->injectionEvents.elements[3], 1, 0, 45 + 90, false);
timeNow += MS2US(20);
eth.firePrimaryTriggerRise();
assertEqualsM("qs#2", 8, schedulingQueue.size());
assertEqualsM("rev cnt6", 6, engine->rpmCalculator.getRevolutionCounter());
// time...|-20.....|-10.....|0.......|10......|20......|30......|40......|
// inj #0 |########|..######|########|..######|........|........|........|
// inj #1 |..######|########|..######|########|........|........|........|
assertInjectorUpEvent("6@0", 0, MS2US(-17.5), 1);
// inj #0 |########|.....###|########|....####|........|........|........|
// inj #1 |.....###|########|.....###|########|........|........|........|
assertInjectorUpEvent("6@0", 0, MS2US(-12.5), 1);
assertInjectorDownEvent("6@1", 1, MS2US(-10.0), 0);
assertInjectorUpEvent("6@2", 2, MS2US(-7.5), 0);
assertInjectorUpEvent("6@2", 2, MS2US(-2.5), 0);
assertInjectorDownEvent("6@3", 3, MS2US(0), 1);
assertInjectorUpEvent("6@4", 4, MS2US(2.5), 1);
assertInjectorUpEvent("6@4", 4, MS2US(7.5), 1);
assertInjectorDownEvent("6@5", 5, MS2US(10.0), 0);
assertInjectorUpEvent("6@6", 6, MS2US(12.5), 0);
assertInjectorUpEvent("6@6", 6, MS2US(17.5), 0);
assertInjectorDownEvent("6@7", 7, MS2US(20.0), 1);
assertEqualsM("exec#7", 4, schedulingQueue.executeAll(timeNow));
@ -825,10 +828,10 @@ void testFuelSchedulerBug299(void) {
assertEqualsM("rev cnt6", 6, engine->rpmCalculator.getRevolutionCounter());
// time...|-20.....|-10.....|0.......|10......|20......|30......|40......|
// inj #0 |........|##......|........|........|........|........|........|
// inj #1 |..######|########|........|........|........|........|........|
assertInjectorUpEvent("7@0", 0, MS2US(-17.5), 1);
// inj #1 |....####|########|........|........|........|........|........|
assertInjectorUpEvent("7@0", 0, MS2US(-12.5), 1);
assertInjectorDownEvent("7@1", 1, MS2US(-10.0), 0);
assertInjectorUpEvent("7@2", 2, MS2US(-7.5), 0);
assertInjectorUpEvent("7@2", 2, MS2US(-2.5), 0);
assertInjectorDownEvent("7@3", 3, MS2US(0), 1);
assertEqualsM("exec#6", 4, schedulingQueue.executeAll(timeNow));
@ -839,10 +842,14 @@ void testFuelSchedulerBug299(void) {
t = ENGINE(engineConfiguration2)->injectionEvents;
assertEqualsM("t.s", 4, t->injectionEvents.size);
assertInjectionEvent(&t->injectionEvents.elements[0], 0, 0, 225, false);
assertInjectionEvent(&t->injectionEvents.elements[1], 1, 0, 405, false);
assertInjectionEvent(&t->injectionEvents.elements[2], 0, 0, 585, true);
assertInjectionEvent(&t->injectionEvents.elements[3], 1, 0, 45, false);
assertInjectionEvent(&t->injectionEvents.elements[0], 0, 0, 315, false);
assertInjectionEvent(&t->injectionEvents.elements[1], 1, 0, 495, false);
assertInjectionEvent(&t->injectionEvents.elements[2], 0, 0, 675, true);
assertInjectionEvent(&t->injectionEvents.elements[3], 1, 0, 45 + 90, false);
setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35);
setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 35);
unitTestValue = 0;