auto-sync

This commit is contained in:
rusEfi 2016-11-30 22:06:43 -05:00
parent f399233038
commit dd7b864492
11 changed files with 111 additions and 80 deletions

View File

@ -308,14 +308,16 @@ IgnitionEventList * Engine::ignitionList() {
return &engineConfiguration2->ignitionEvents;
}
void Engine::prepareFuelSchedule(DECLARE_ENGINE_PARAMETER_F) {
injection_mode_e Engine::getCurrentInjectionMode(DECLARE_ENGINE_PARAMETER_F) {
int rpm = rpmCalculator.rpmValue;
return isCrankingR(rpm) ? CONFIG(crankingInjectionMode) : CONFIG(injectionMode);
}
void Engine::prepareFuelSchedule(DECLARE_ENGINE_PARAMETER_F) {
efiAssertVoid(ENGINE(engineConfiguration2)->injectionEvents != ENGINE(engineConfiguration2)->processing, "fuel pointers");
ENGINE(m.beforeInjectonSch) = GET_TIMESTAMP();
injection_mode_e mode = isCrankingR(rpm) ? CONFIG(crankingInjectionMode) : CONFIG(injectionMode);
if (ENGINE(engineConfiguration2)->processing->usedAtEngineCycle != 0 &&
ENGINE(engineConfiguration2)->processing->usedAtEngineCycle == ENGINE(rpmCalculator).getRevolutionCounter()) {
// we are here if engine is still using this older fuel schedule, not yet time to override it
@ -323,8 +325,7 @@ void Engine::prepareFuelSchedule(DECLARE_ENGINE_PARAMETER_F) {
return;
}
ENGINE(engineConfiguration2)->processing->addFuelEvents(
mode PASS_ENGINE_PARAMETER);
ENGINE(engineConfiguration2)->processing->addFuelEvents(PASS_ENGINE_PARAMETER_F);
ENGINE(m.injectonSchTime) = GET_TIMESTAMP() - ENGINE(m.beforeInjectonSch);
/**

View File

@ -32,6 +32,8 @@ public:
int getMockAdcValue(int hwChannel);
};
#define MAX_INJECTION_OUTPUT_COUNT INJECTION_PIN_COUNT
/**
* This class knows about when to inject fuel
*/
@ -41,12 +43,13 @@ 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);
void addFuelEvents(DECLARE_ENGINE_PARAMETER_F);
void addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_S);
uint32_t usedAtEngineCycle;
InjectionEventList injectionEvents;
InjectionEvent elements[MAX_INJECTION_OUTPUT_COUNT];
bool isReady;
private:
void clear();
@ -244,6 +247,7 @@ public:
Engine(persistent_config_s *config);
void init(persistent_config_s *config);
void prepareFuelSchedule(DECLARE_ENGINE_PARAMETER_F);
injection_mode_e getCurrentInjectionMode(DECLARE_ENGINE_PARAMETER_F);
IgnitionEventList *ignitionList(); // todo: inline/rename/refactor
WallFuel wallFuel;

View File

@ -1041,8 +1041,7 @@ void prepareShapes(DECLARE_ENGINE_PARAMETER_F) {
engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2;
prepareOutputSignals(PASS_ENGINE_PARAMETER_F);
engineConfiguration2->injectionEvents->addFuelEvents(
engineConfiguration->crankingInjectionMode PASS_ENGINE_PARAMETER);
engineConfiguration2->injectionEvents->addFuelEvents(PASS_ENGINE_PARAMETER_F);
}
#endif

View File

@ -29,6 +29,8 @@ public:
angle_t angleOffset;
};
class Engine;
class InjectionEvent {
public:
InjectionEvent();
@ -39,7 +41,10 @@ public:
bool isSimultanious;
InjectorOutputPin *outputs[MAX_WIRES_COUNT];
bool isOverlapping;
int ownIndex;
#if EFI_UNIT_TEST
Engine *engine;
#endif
event_trigger_position_s injectionStart;
};
@ -69,17 +74,8 @@ public:
IgnitionOutputPin *getOutputForLoggins();
};
#define MAX_INJECTION_OUTPUT_COUNT INJECTION_PIN_COUNT
#define MAX_IGNITION_EVENT_COUNT IGNITION_PIN_COUNT
class InjectionEventList {
public:
InjectionEventList();
InjectionEvent elements[MAX_INJECTION_OUTPUT_COUNT];
bool isReady;
};
class IgnitionEventList {
public:
IgnitionEventList();

View File

@ -44,6 +44,7 @@ extern WaveChart waveChart;
OutputSignalPair::OutputSignalPair() {
isScheduled = false;
memset(outputs, 0, sizeof(outputs));
event = NULL;
}
void initSignalExecutor(void) {

View File

@ -26,6 +26,8 @@
#define MAX_WIRES_COUNT 2
class InjectionEvent;
class OutputSignalPair {
public:
OutputSignalPair();
@ -41,6 +43,7 @@ public:
*/
bool isScheduled;
InjectorOutputPin *outputs[MAX_WIRES_COUNT];
InjectionEvent *event;
};
/**

View File

@ -98,10 +98,11 @@ FuelSchedule::FuelSchedule() {
}
void FuelSchedule::clear() {
isReady = false;
usedAtEngineCycle = 0;
}
void FuelSchedule::addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) {
void FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_S) {
efiAssertVoid(engine!=NULL, "engine is NULL");
if (cisnan(engine->rpmCalculator.oneDegreeUs)) {
@ -122,6 +123,8 @@ void FuelSchedule::addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE
int index;
injection_mode_e mode = engine->getCurrentInjectionMode(PASS_ENGINE_PARAMETER_F);
if (mode == IM_SIMULTANEOUS) {
index = 0;
} else if (mode == IM_SEQUENTIAL) {
@ -157,7 +160,11 @@ void FuelSchedule::addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE
warning(CUSTOM_OBD_20, "no_pin_inj #%s", output->name);
}
InjectionEvent *ev = &injectionEvents.elements[i];
InjectionEvent *ev = &elements[i];
ev->ownIndex = i;
#if EFI_UNIT_TEST
ev->engine = engine;
#endif
fixAngle(angle);
ev->isOverlapping = angle < 720 && (angle + injectionDuration) > 720;
@ -174,12 +181,15 @@ void FuelSchedule::addFuelEventsForCylinder(int i, injection_mode_e mode DECLARE
#endif
}
void FuelSchedule::addFuelEvents(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) {
void FuelSchedule::addFuelEvents(DECLARE_ENGINE_PARAMETER_F) {
clear();
for (int i = 0; i < CONFIG(specs.cylindersCount); i++) {
addFuelEventsForCylinder(i, mode PASS_ENGINE_PARAMETER);
InjectionEvent *ev = &elements[i];
ev->ownIndex = i;
addFuelEventsForCylinder(i PASS_ENGINE_PARAMETER);
}
isReady = true;
}
#endif

View File

@ -75,16 +75,25 @@ static Logging *logger;
//#define RAM_METHOD_PREFIX
//#endif
static void startSimultaniousInjection(Engine *engine) {
static void startSimultaniousInjection(InjectionEvent *event) {
#if EFI_UNIT_TEST
Engine *engine = event->engine;
#endif
for (int i = 0; i < engine->engineConfiguration->specs.cylindersCount; i++) {
turnPinHigh(&enginePins.injectors[i]);
}
}
static void endSimultaniousInjection(Engine *engine) {
static void endSimultaniousInjection(InjectionEvent *event) {
#if EFI_UNIT_TEST
Engine *engine = event->engine;
EXPAND_Engine;
engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2;
#endif
for (int i = 0; i < engine->engineConfiguration->specs.cylindersCount; i++) {
turnPinLow(&enginePins.injectors[i]);
}
engineConfiguration2->injectionEvents->addFuelEventsForCylinder(event->ownIndex PASS_ENGINE_PARAMETER);
}
static void tempTurnPinHigh(InjectorOutputPin *output) {
@ -123,8 +132,9 @@ static void tempTurnPinHigh(InjectorOutputPin *output) {
void seTurnPinHigh(OutputSignalPair *pair) {
for (int i = 0;i<MAX_WIRES_COUNT;i++) {
InjectorOutputPin *output = pair->outputs[i];
if (output != NULL)
if (output != NULL) {
tempTurnPinHigh(output);
}
}
}
@ -171,9 +181,16 @@ void seTurnPinLow(OutputSignalPair *pair) {
pair->isScheduled = false;
for (int i = 0;i<MAX_WIRES_COUNT;i++) {
InjectorOutputPin *output = pair->outputs[i];
if (output != NULL)
tempTurnPinLow(output);
if (output != NULL) {
tempTurnPinLow(output);
}
}
#if EFI_UNIT_TEST
// Engine *engine = pair->event->engine;
// EXPAND_Engine;
// engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2;
#endif
// engineConfiguration2->injectionEvents->addFuelEventsForCylinder(pair->event->ownIndex PASS_ENGINE_PARAMETER);
}
static void seScheduleByTime(const char *prefix, scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, OutputSignalPair *pair) {
@ -221,6 +238,7 @@ static void scheduleFuelInjection(int rpm, OutputSignal *signal, efitimeus_t now
scheduling_s * sDown = &pair->signalTimerDown;
pair->isScheduled = true;
pair->event = event;
efitimeus_t turnOnTime = nowUs + (int) delayUs;
bool isSecondaryOverlapping = turnOnTime < output->overlappingScheduleOffTime;
@ -305,9 +323,9 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionE
// todo: sequential need this logic as well, just do not forget to clear flag pair->isScheduled = true;
scheduling_s * sDown = &pair->signalTimerDown;
scheduleTask(true, "out up s", sUp, (int) injectionStartDelayUs, (schfunc_t) &startSimultaniousInjection, engine);
scheduleTask(true, "out up s", sUp, (int) injectionStartDelayUs, (schfunc_t) &startSimultaniousInjection, event);
scheduleTask(true, "out down", sDown, (int) injectionStartDelayUs + MS2US(injectionDuration),
(schfunc_t) &endSimultaniousInjection, engine);
(schfunc_t) &endSimultaniousInjection, event);
} else {
#if EFI_UNIT_TEST || defined(__DOXYGEN__)
@ -356,7 +374,7 @@ static void scheduleOutput2(OutputSignalPair *pair, efitimeus_t nowUs, float del
#endif /* EFI_GPIO */
}
static void handleFuelScheduleOverlap(InjectionEventList *injectionEvents DECLARE_ENGINE_PARAMETER_S) {
static void handleFuelScheduleOverlap(FuelSchedule *fs DECLARE_ENGINE_PARAMETER_S) {
/**
* here we need to avoid a fuel miss due to changes between previous and current fuel schedule
* see https://sourceforge.net/p/rusefi/tickets/299/
@ -364,7 +382,7 @@ static void handleFuelScheduleOverlap(InjectionEventList *injectionEvents DECLAR
*/
//
for (int injEventIndex = 0; injEventIndex < CONFIG(specs.cylindersCount); injEventIndex++) {
InjectionEvent *event = &injectionEvents->elements[injEventIndex];
InjectionEvent *event = &fs->elements[injEventIndex];
if (!engine->engineConfiguration2->wasOverlapping[injEventIndex] && event->isOverlapping) {
// we are here if new fuel schedule is crossing engine cycle boundary with this event
@ -407,10 +425,12 @@ static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIn
* fueling strategy
*/
FuelSchedule *fs = engine->fuelScheduleForThisEngineCycle;
InjectionEventList *injectionEvents = &fs->injectionEvents;
if (!fs->isReady) {
fs->addFuelEvents(PASS_ENGINE_PARAMETER_F);
}
if (trgEventIndex == 0) {
handleFuelScheduleOverlap(injectionEvents PASS_ENGINE_PARAMETER);
handleFuelScheduleOverlap(fs PASS_ENGINE_PARAMETER);
}
#if FUEL_MATH_EXTREME_LOGGING || defined(__DOXYGEN__)
@ -423,7 +443,7 @@ static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIn
ENGINE(fuelMs) = getInjectionDuration(rpm PASS_ENGINE_PARAMETER) * CONFIG(globalFuelCorrection);
for (int injEventIndex = 0; injEventIndex < CONFIG(specs.cylindersCount); injEventIndex++) {
InjectionEvent *event = &injectionEvents->elements[injEventIndex];
InjectionEvent *event = &fs->elements[injEventIndex];
uint32_t eventIndex = event->injectionStart.eventIndex;
// right after trigger change we are still using old & invalid fuel schedule. good news is we do not change trigger on the fly in real life
// efiAssertVoid(eventIndex < ENGINE(triggerShape.getLength()), "handleFuel/event sch index");
@ -514,6 +534,7 @@ void mainTriggerCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex D
if (triggerVersion.isOld()) {
engine->ignitionList()->isReady = false; // we need to rebuild ignition schedule
engine->fuelScheduleForThisEngineCycle->isReady = false;
// todo: move 'triggerIndexByAngle' change into trigger initialization, why is it invoked from here if it's only about trigger shape & optimization?
prepareOutputSignals(PASS_ENGINE_PARAMETER_F);
// we need this to apply new 'triggerIndexByAngle' values

View File

@ -21,10 +21,6 @@ IgnitionEventList::IgnitionEventList() {
isReady = false;
}
InjectionEventList::InjectionEventList() {
isReady = false;
}
int isInjectionEnabled(engine_configuration_s *engineConfiguration) {
// todo: is this worth a method? should this be inlined?
return engineConfiguration->isInjectionEnabled;
@ -74,7 +70,7 @@ void turnSparkPinLow(IgnitionEvent *event) {
turnSparkPinLow2(event, output);
}
}
#if EFI_UNIT_TEST
#if EFI_UNIT_TEST || defined(__DOXYGEN__)
Engine *engine = event->engine;
EXPAND_Engine;
#endif
@ -84,7 +80,7 @@ void turnSparkPinLow(IgnitionEvent *event) {
static void turnSparkPinHigh2(IgnitionEvent *event, IgnitionOutputPin *output) {
#if ! EFI_UNIT_TEST
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
if (engine->rpmCalculator.rpmValue > 2 * engineConfiguration->cranking.rpm) {
const char *outputName = output->name;
if (prevSparkName == outputName) {

View File

@ -160,8 +160,6 @@ static void confgiureFordAspireTriggerShape(TriggerShape * s DECLARE_ENGINE_PARA
assertEqualsM("expecting 1", 1, s->wave.waveIndertionAngle(63.747 / 720.0, s->getSize()));
}
static InjectionEventList ae;
void testAngleResolver(void) {
printf("*************************************************** testAngleResolver\r\n");
@ -182,35 +180,37 @@ void testAngleResolver(void) {
assertEqualsM("shape size", 10, ts->getSize());
event_trigger_position_s injectionStart;
printf("*************************************************** testAngleResolver 0\r\n");
findTriggerPosition(&ae.elements[0].injectionStart, -122 PASS_ENGINE_PARAMETER);
assertEqualsM("eventIndex@0", 2, ae.elements[0].injectionStart.eventIndex);
assertEquals(0.24, ae.elements[0].injectionStart.angleOffset);
findTriggerPosition(&injectionStart, -122 PASS_ENGINE_PARAMETER);
assertEqualsM("eventIndex@0", 2, injectionStart.eventIndex);
assertEquals(0.24, injectionStart.angleOffset);
printf("*************************************************** testAngleResolver 0.1\r\n");
findTriggerPosition(&ae.elements[0].injectionStart, -80 PASS_ENGINE_PARAMETER);
assertEqualsM("eventIndex@0", 2, ae.elements[0].injectionStart.eventIndex);
assertEquals(42.24, ae.elements[0].injectionStart.angleOffset);
findTriggerPosition(&injectionStart, -80 PASS_ENGINE_PARAMETER);
assertEqualsM("eventIndex@0", 2, injectionStart.eventIndex);
assertEquals(42.24, injectionStart.angleOffset);
printf("*************************************************** testAngleResolver 0.2\r\n");
findTriggerPosition(&ae.elements[0].injectionStart, -54 PASS_ENGINE_PARAMETER);
assertEqualsM("eventIndex@0", 2, ae.elements[0].injectionStart.eventIndex);
assertEquals(68.2400, ae.elements[0].injectionStart.angleOffset);
findTriggerPosition(&injectionStart, -54 PASS_ENGINE_PARAMETER);
assertEqualsM("eventIndex@0", 2, injectionStart.eventIndex);
assertEquals(68.2400, injectionStart.angleOffset);
printf("*************************************************** testAngleResolver 0.3\r\n");
findTriggerPosition(&ae.elements[0].injectionStart, -53 PASS_ENGINE_PARAMETER);
assertEquals(2, ae.elements[0].injectionStart.eventIndex);
assertEquals(69.24, ae.elements[0].injectionStart.angleOffset);
findTriggerPosition(&injectionStart, -53 PASS_ENGINE_PARAMETER);
assertEquals(2, injectionStart.eventIndex);
assertEquals(69.24, injectionStart.angleOffset);
printf("*************************************************** testAngleResolver 1\r\n");
findTriggerPosition(&ae.elements[0].injectionStart, 0 PASS_ENGINE_PARAMETER);
assertEquals(2, ae.elements[0].injectionStart.eventIndex);
assertEquals(122.24, ae.elements[0].injectionStart.angleOffset);
findTriggerPosition(&injectionStart, 0 PASS_ENGINE_PARAMETER);
assertEquals(2, injectionStart.eventIndex);
assertEquals(122.24, injectionStart.angleOffset);
printf("*************************************************** testAngleResolver 2\r\n");
findTriggerPosition(&ae.elements[0].injectionStart, 56 PASS_ENGINE_PARAMETER);
assertEquals(2, ae.elements[0].injectionStart.eventIndex);
assertEquals(178.24, ae.elements[0].injectionStart.angleOffset);
findTriggerPosition(&injectionStart, 56 PASS_ENGINE_PARAMETER);
assertEquals(2, injectionStart.eventIndex);
assertEquals(178.24, injectionStart.angleOffset);
TriggerShape t;
confgiureFordAspireTriggerShape(&t PASS_ENGINE_PARAMETER);

View File

@ -345,7 +345,7 @@ void testRpmCalculator(void) {
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_F);
assertEqualsM("fuel #1", 4.5450, eth.engine.fuelMs);
InjectionEvent *ie0 = &eth.engine.engineConfiguration2->injectionEvents->injectionEvents.elements[0];
InjectionEvent *ie0 = &eth.engine.engineConfiguration2->injectionEvents->elements[0];
assertEqualsM("injection angle", 31.365, ie0->injectionStart.angleOffset);
eth.engine.triggerCentral.handleShaftSignal(SHAFT_PRIMARY_RISING PASS_ENGINE_PARAMETER);
@ -665,10 +665,10 @@ static void setTestBug299(EngineTestHelper *eth) {
FuelSchedule * t = ENGINE(engineConfiguration2)->injectionEvents;
assertInjectionEvent("#0", &t->injectionEvents.elements[0], 0, 1, 153, false);
assertInjectionEvent("#1", &t->injectionEvents.elements[1], 1, 1, 333, false);
assertInjectionEvent("#2", &t->injectionEvents.elements[2], 0, 0, 153, false);
assertInjectionEvent("#3", &t->injectionEvents.elements[3], 1, 0, 153 + 180, false);
assertInjectionEvent("#0", &t->elements[0], 0, 1, 153, false);
assertInjectionEvent("#1", &t->elements[1], 1, 1, 333, false);
assertInjectionEvent("#2", &t->elements[2], 0, 0, 153, false);
assertInjectionEvent("#3", &t->elements[3], 1, 0, 153 + 180, false);
/**
* Trigger down - no new events, executing some
@ -836,10 +836,10 @@ void testFuelSchedulerBug299smallAndMedium(void) {
t = ENGINE(engineConfiguration2)->injectionEvents;
assertInjectionEvent("#0", &t->injectionEvents.elements[0], 0, 0, 315, false);
assertInjectionEvent("#1", &t->injectionEvents.elements[1], 1, 1, 135, false);
assertInjectionEvent("#2", &t->injectionEvents.elements[2], 0, 1, 315, true);
assertInjectionEvent("#3", &t->injectionEvents.elements[3], 1, 0, 45 + 90, false);
assertInjectionEvent("#0", &t->elements[0], 0, 0, 315, false);
assertInjectionEvent("#1", &t->elements[1], 1, 1, 135, false);
assertInjectionEvent("#2", &t->elements[2], 0, 1, 315, true);
assertInjectionEvent("#3", &t->elements[3], 1, 0, 45 + 90, false);
timeNow += MS2US(20);
assertEqualsM("qs#02", 5, schedulingQueue.size());
@ -925,10 +925,10 @@ void testFuelSchedulerBug299smallAndMedium(void) {
t = ENGINE(engineConfiguration2)->injectionEvents;
assertInjectionEvent("#0#", &t->injectionEvents.elements[0], 0, 0, 315, false);
assertInjectionEvent("#1#", &t->injectionEvents.elements[1], 1, 1, 135, false);
assertInjectionEvent("#2#", &t->injectionEvents.elements[2], 0, 1, 315, true);
assertInjectionEvent("#3#", &t->injectionEvents.elements[3], 1, 0, 45 + 90, false);
assertInjectionEvent("#0#", &t->elements[0], 0, 0, 315, false);
assertInjectionEvent("#1#", &t->elements[1], 1, 1, 135, false);
assertInjectionEvent("#2#", &t->elements[2], 0, 1, 315, true);
assertInjectionEvent("#3#", &t->elements[3], 1, 0, 45 + 90, false);
setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35);
@ -939,7 +939,7 @@ void testFuelSchedulerBug299smallAndMedium(void) {
assertEqualsM("duty for maf=3", 87.5, getInjectorDutyCycle(eth.engine.rpmCalculator.getRpm(PASS_ENGINE_PARAMETER_F) PASS_ENGINE_PARAMETER));
assertInjectionEvent("#03", &t->injectionEvents.elements[0], 0, 0, 315, false);
assertInjectionEvent("#03", &t->elements[0], 0, 0, 315, false);
engine->periodicFastCallback(PASS_ENGINE_PARAMETER_F);
@ -976,10 +976,10 @@ void testFuelSchedulerBug299smallAndMedium(void) {
t = ENGINE(engineConfiguration2)->injectionEvents;
assertInjectionEvent("#00", &t->injectionEvents.elements[0], 0, 0, 225, false); // 87.5 duty cycle
assertInjectionEvent("#10", &t->injectionEvents.elements[1], 1, 1, 45, false);
assertInjectionEvent("#20", &t->injectionEvents.elements[2], 0, 1, 225, true);
assertInjectionEvent("#30", &t->injectionEvents.elements[3], 1, 0, 45, false);
assertInjectionEvent("#00", &t->elements[0], 0, 0, 225, false); // 87.5 duty cycle
assertInjectionEvent("#10", &t->elements[1], 1, 1, 45, false);
assertInjectionEvent("#20", &t->elements[2], 0, 1, 225, true);
assertInjectionEvent("#30", &t->elements[3], 1, 0, 45, false);
// todo: what's what? a mix of new something and old something?
assertEqualsM("qs#5", 6, schedulingQueue.size());