auto-sync

This commit is contained in:
rusEfi 2016-11-30 20:02:41 -05:00
parent 0fe292a6ac
commit 2a7d260437
5 changed files with 97 additions and 99 deletions

View File

@ -42,6 +42,7 @@ public:
* this method schedules all fuel events for an engine cycle
*/
void addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S);
void addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE_ENGINE_PARAMETER_S);
uint32_t usedAtEngineCycle;
@ -58,7 +59,6 @@ public:
int eventsCount;
private:
void clear();
void registerInjectionEvent(InjectorOutputPin *output, InjectorOutputPin *secondOutput, float angle, angle_t injectionDuration, bool isSimultanious DECLARE_ENGINE_PARAMETER_S);
};
/**

View File

@ -93,40 +93,6 @@ void setSingleCoilDwell(engine_configuration_s *engineConfiguration) {
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
void FuelSchedule::registerInjectionEvent(InjectorOutputPin *output, InjectorOutputPin *secondOutput, float angle, angle_t injectionDuration,
bool isSimultanious DECLARE_ENGINE_PARAMETER_S) {
if (!isSimultanious && !isPinAssigned(output)) {
// todo: extract method for this index math
warning(CUSTOM_OBD_20, "no_pin_inj #%s", output->name);
}
InjectionEvent *ev = injectionEvents.add();
if (ev == NULL) {
// error already reported
return;
}
fixAngle(angle);
ev->isOverlapping = angle < 720 && (angle + injectionDuration) > 720;
ev->outputs[0] = output;
ev->isSimultanious = isSimultanious;
efiAssertVoid(TRIGGER_SHAPE(getSize()) > 0, "uninitialized TriggerShape");
findTriggerPosition(&ev->injectionStart, angle PASS_ENGINE_PARAMETER);
#if EFI_UNIT_TEST
printf("registerInjectionEvent angle=%f index=%d\r\n", angle, ev->injectionStart.eventIndex);
#endif
if (!hasEvents[ev->injectionStart.eventIndex]) {
hasEvents[ev->injectionStart.eventIndex] = true;
eventsCount++;
}
}
FuelSchedule::FuelSchedule() {
clear();
}
@ -137,12 +103,7 @@ void FuelSchedule::clear() {
usedAtEngineCycle = 0;
}
void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) {
clear(); // this method is relatively heavy
// sourceList->reset();
injectionEvents.reset();
void FuelSchedule::addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) {
efiAssertVoid(engine!=NULL, "engine is NULL");
if (cisnan(engine->rpmCalculator.oneDegreeUs)) {
@ -161,46 +122,77 @@ void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_
angle_t injectionDuration = MS2US(ENGINE(fuelMs)) / ENGINE(rpmCalculator.oneDegreeUs);
angle_t baseAngle = ENGINE(engineState.injectionOffset) - injectionDuration;
switch (mode) {
case IM_SEQUENTIAL:
for (int i = 0; i < CONFIG(specs.cylindersCount); i++) {
int index = getCylinderId(engineConfiguration->specs.firingOrder, i) - 1;
float angle = baseAngle
+ ENGINE(engineCycle) * i / CONFIG(specs.cylindersCount);
registerInjectionEvent(&enginePins.injectors[index], NULL, angle, injectionDuration, false PASS_ENGINE_PARAMETER);
}
break;
case IM_SIMULTANEOUS:
for (int i = 0; i < CONFIG(specs.cylindersCount); i++) {
float angle = baseAngle
+ ENGINE(engineCycle) * i / CONFIG(specs.cylindersCount);
int index;
/**
* We do not need injector pin here because we will control all injectors
* simultaneously
*/
registerInjectionEvent(&enginePins.injectors[0], NULL, angle, injectionDuration, true PASS_ENGINE_PARAMETER);
}
break;
case IM_BATCH:
for (int i = 0; i < CONFIG(specs.cylindersCount); i++) {
int index = i % (engineConfiguration->specs.cylindersCount / 2);
float angle = baseAngle
+ i * ENGINE(engineCycle) / CONFIG(specs.cylindersCount);
registerInjectionEvent(&enginePins.injectors[index], NULL, angle, injectionDuration, false PASS_ENGINE_PARAMETER);
if (CONFIG(twoWireBatchInjection)) {
/**
* also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires
*/
index = index + (CONFIG(specs.cylindersCount) / 2);
registerInjectionEvent(&enginePins.injectors[index], NULL, angle, injectionDuration, false PASS_ENGINE_PARAMETER);
}
}
break;
default:
if (mode == IM_SIMULTANEOUS) {
index = 0;
} else if (mode == IM_SEQUENTIAL) {
index = getCylinderId(engineConfiguration->specs.firingOrder, i) - 1;
} else if (mode == IM_BATCH) {
// does not look exactly right, not too consistent with IM_SEQUENTIAL
index = i % (engineConfiguration->specs.cylindersCount / 2);
} else {
warning(CUSTOM_OBD_21, "Unexpected injection mode %d", mode);
index = 0;
}
bool isSimultanious = mode == IM_SIMULTANEOUS;
float angle = baseAngle
+ i * ENGINE(engineCycle) / CONFIG(specs.cylindersCount);
InjectorOutputPin *secondOutput;
if (mode == IM_BATCH && CONFIG(twoWireBatchInjection)) {
/**
* also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires
*/
int secondIndex = index + (CONFIG(specs.cylindersCount) / 2);
secondOutput = &enginePins.injectors[secondIndex];
} else {
secondOutput = NULL;
}
InjectorOutputPin *output = &enginePins.injectors[index];
if (!isSimultanious && !isPinAssigned(output)) {
// todo: extract method for this index math
warning(CUSTOM_OBD_20, "no_pin_inj #%s", output->name);
}
InjectionEvent *ev = injectionEvents.add();
if (ev == NULL) {
// error already reported
return;
}
fixAngle(angle);
ev->isOverlapping = angle < 720 && (angle + injectionDuration) > 720;
ev->outputs[0] = output;
ev->outputs[1] = secondOutput;
ev->isSimultanious = isSimultanious;
efiAssertVoid(TRIGGER_SHAPE(getSize()) > 0, "uninitialized TriggerShape");
findTriggerPosition(&ev->injectionStart, angle PASS_ENGINE_PARAMETER);
#if EFI_UNIT_TEST
printf("registerInjectionEvent angle=%f index=%d\r\n", angle, ev->injectionStart.eventIndex);
#endif
if (!hasEvents[ev->injectionStart.eventIndex]) {
hasEvents[ev->injectionStart.eventIndex] = true;
eventsCount++;
}
}
void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) {
clear(); // this method is relatively heavy
// sourceList->reset();
injectionEvents.reset();
for (int i = 0; i < CONFIG(specs.cylindersCount); i++) {
addFuelEventsForCylinder(i, mode PASS_ENGINE_PARAMETER);
}
}

View File

@ -121,8 +121,11 @@ static void tempTurnPinHigh(InjectorOutputPin *output) {
// todo: make these macro? kind of a penny optimization if compiler is not smart to inline
void seTurnPinHigh(OutputSignalPair *pair) {
InjectorOutputPin *output = pair->outputs[0];
tempTurnPinHigh(output);
for (int i = 0;i<MAX_WIRES_COUNT;i++) {
InjectorOutputPin *output = pair->outputs[i];
if (output != NULL)
tempTurnPinHigh(output);
}
}
static void tempTurnPinLow(InjectorOutputPin *output) {
@ -166,8 +169,11 @@ static void tempTurnPinLow(InjectorOutputPin *output) {
void seTurnPinLow(OutputSignalPair *pair) {
pair->isScheduled = false;
InjectorOutputPin *output = pair->outputs[0];
tempTurnPinLow(output);
for (int i = 0;i<MAX_WIRES_COUNT;i++) {
InjectorOutputPin *output = pair->outputs[i];
if (output != NULL)
tempTurnPinLow(output);
}
}
static void seScheduleByTime(const char *prefix, scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, OutputSignalPair *pair) {
@ -185,7 +191,7 @@ static void seScheduleByTime(const char *prefix, scheduling_s *scheduling, efiti
scheduleByTime(true, prefix, scheduling, time, callback, pair);
}
static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t nowUs, floatus_t delayUs, floatus_t durationUs, InjectorOutputPin *output DECLARE_ENGINE_PARAMETER_S) {
static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t nowUs, floatus_t delayUs, floatus_t durationUs, InjectionEvent *event DECLARE_ENGINE_PARAMETER_S) {
if (durationUs < 0) {
warning(CUSTOM_OBD_3, "duration cannot be negative: %d", durationUs);
return;
@ -194,6 +200,7 @@ static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t now
warning(CUSTOM_NAN_DURACTION, "NaN in scheduleFuelInjection", durationUs);
return;
}
InjectorOutputPin *output = event->outputs[0];
#if EFI_PRINTF_FUEL_DETAILS || defined(__DOXYGEN__)
printf("fuelout %s duration %d total=%d\t\n", output->name, (int)durationUs,
(int)MS2US(getCrankshaftRevolutionTimeMs(rpm)));
@ -209,6 +216,7 @@ static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t now
return; // this OutputSignalPair is still needed for an extremely long injection scheduled previously
}
pair->outputs[0] = output;
pair->outputs[1] = event->outputs[1];
scheduling_s * sUp = &pair->signalTimerUp;
scheduling_s * sDown = &pair->signalTimerDown;
@ -316,7 +324,7 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionE
prevOutputName = outputName;
}
scheduleFuelInjection(rpm, signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event->outputs[0] PASS_ENGINE_PARAMETER);
scheduleFuelInjection(rpm, signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event PASS_ENGINE_PARAMETER);
}
}

View File

@ -281,7 +281,7 @@ void firmwareError(obd_code_e code, const char *errorMsg, ...) {
}
}
static char UNUSED_RAM_SIZE[1300];
static char UNUSED_RAM_SIZE[1100];
static char UNUSED_CCM_SIZE[8500] CCM_OPTIONAL;

View File

@ -383,11 +383,10 @@ void testRpmCalculator(void) {
timeNow += 5000;
eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_FALLING PASS_ENGINE_PARAMETER);
assertEqualsM("index #3", 3, eth.engine.triggerCentral.triggerState.getCurrentIndex());
assertEqualsM("queue size 3", 6, schedulingQueue.size());
assertEqualsM("queue size 3", 4, schedulingQueue.size());
assertEqualsM("ev 3", st + 13333 - 1515, schedulingQueue.getForUnitText(0)->momentX);
assertEqualsM("ev 4", st + 13333 - 1515, schedulingQueue.getForUnitText(1)->momentX);
assertEqualsM2("ev 5", st + 14277, schedulingQueue.getForUnitText(2)->momentX, 2);
assertEqualsM("3/3", st + 14777, schedulingQueue.getForUnitText(3)->momentX);
assertEqualsM2("ev 5", st + 14277, schedulingQueue.getForUnitText(1)->momentX, 2);
assertEqualsM("3/3", st + 14777, schedulingQueue.getForUnitText(2)->momentX);
schedulingQueue.clear();
assertEquals(5, engine->triggerShape.triggerIndexByAngle[240]);
@ -401,26 +400,26 @@ void testRpmCalculator(void) {
timeNow += 5000; // 5ms
eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER);
assertEqualsM("queue size 4.2", 6, schedulingQueue.size());
assertEqualsM("queue size 4.2", 4, schedulingQueue.size());
timeNow += 5000; // 5ms
eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER);
assertEqualsM("queue size 4.3", 6, schedulingQueue.size());
assertEqualsM("queue size 4.3", 4, schedulingQueue.size());
assertEqualsM("dwell", 4.5, eth.engine.engineState.dwellAngle);
assertEqualsM("fuel #3", 4.5450, eth.engine.fuelMs);
assertEquals(1500, eth.engine.rpmCalculator.rpmValue);
assertInjectorUpEvent("ev 0/2", 0, -4849, 2);
assertInjectorUpEvent("ev 1/2", 1, -4849, 5);
assertEqualsM("index #4", 6, eth.engine.triggerCentral.triggerState.getCurrentIndex());
assertEqualsM("queue size 4", 6, schedulingQueue.size());
assertEqualsM("queue size 4", 4, schedulingQueue.size());
schedulingQueue.clear();
timeNow += 5000;
eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_FALLING PASS_ENGINE_PARAMETER);
assertEqualsM("queue size 5", 4, schedulingQueue.size());
assertEqualsM("queue size 5", 2, schedulingQueue.size());
// todo: assert queue elements
schedulingQueue.clear();
@ -438,12 +437,11 @@ void testRpmCalculator(void) {
timeNow += 5000; // 5ms
eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER);
assertEqualsM("queue size 8", 6, schedulingQueue.size());
assertEqualsM("queue size 8", 4, schedulingQueue.size());
// todo: assert queue elements completely
assertEqualsM("8/0", st + 53333 - 1515, schedulingQueue.getForUnitText(0)->momentX);
assertEqualsM("8/1", st + 53333 - 1515, schedulingQueue.getForUnitText(1)->momentX);
assertEqualsM2("8/2", st + 54277, schedulingQueue.getForUnitText(2)->momentX, 0);
assertEqualsM2("8/3", st + 54777, schedulingQueue.getForUnitText(3)->momentX, 0);
assertEqualsM2("8/1", st + 54277, schedulingQueue.getForUnitText(1)->momentX, 0);
assertEqualsM2("8/2", st + 54777, schedulingQueue.getForUnitText(2)->momentX, 0);
schedulingQueue.clear();
timeNow += 5000;