auto-sync
This commit is contained in:
parent
a0ffdbb60b
commit
a63ac8d829
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue