allow setting injection phase by start or center of injection (#4068)
* allow SOI/COI * other change * renames and simplify * clean up ownIndex * double check in spark logic
This commit is contained in:
parent
11cea53c36
commit
497e7ffe77
|
@ -2042,7 +2042,7 @@ typedef enum {
|
||||||
CUSTOM_ERR_6686 = 6686,
|
CUSTOM_ERR_6686 = 6686,
|
||||||
CUSTOM_FIRING_LENGTH = 6687,
|
CUSTOM_FIRING_LENGTH = 6687,
|
||||||
CUSTOM_ADVANCE_SPARK = 6688,
|
CUSTOM_ADVANCE_SPARK = 6688,
|
||||||
CUSTOM_SPARK_ANGLE_9 = 6689,
|
CUSTOM_ERR_6689 = 6689,
|
||||||
|
|
||||||
CUSTOM_ERR_MAP_START_ASSERT = 6690,
|
CUSTOM_ERR_MAP_START_ASSERT = 6690,
|
||||||
CUSTOM_ERR_MAP_AVG_OFFSET = 6691,
|
CUSTOM_ERR_MAP_AVG_OFFSET = 6691,
|
||||||
|
|
|
@ -706,4 +706,10 @@ enum class TransmissionControllerMode : uint8_t {
|
||||||
Gm4l6x = 2,
|
Gm4l6x = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class InjectionTimingMode : uint8_t {
|
||||||
|
End = 0,
|
||||||
|
Start = 1,
|
||||||
|
Center = 2,
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
FuelSchedule::FuelSchedule() {
|
FuelSchedule::FuelSchedule() {
|
||||||
for (int cylinderIndex = 0; cylinderIndex < MAX_CYLINDER_COUNT; cylinderIndex++) {
|
for (int cylinderIndex = 0; cylinderIndex < MAX_CYLINDER_COUNT; cylinderIndex++) {
|
||||||
InjectionEvent *ev = &elements[cylinderIndex];
|
elements[cylinderIndex].ownIndex = cylinderIndex;
|
||||||
ev->ownIndex = cylinderIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +25,29 @@ void FuelSchedule::resetOverlapping() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determines how much to adjust injection opening angle based on the injection's duration and the current phasing mode
|
||||||
|
static float getInjectionAngleCorrection(float fuelMs, float oneDegreeUs) {
|
||||||
|
auto mode = engineConfiguration->injectionTimingMode;
|
||||||
|
if (mode == InjectionTimingMode::Start) {
|
||||||
|
// Start of injection gets no correction for duration
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(fuelMs), "NaN fuelMs", false);
|
||||||
|
|
||||||
|
angle_t injectionDurationAngle = MS2US(fuelMs) / oneDegreeUs;
|
||||||
|
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(injectionDurationAngle), "NaN injectionDurationAngle", false);
|
||||||
|
assertAngleRange(injectionDurationAngle, "injectionDuration_r", CUSTOM_INJ_DURATION);
|
||||||
|
|
||||||
|
if (mode == InjectionTimingMode::Center) {
|
||||||
|
// Center of injection is half-corrected for duration
|
||||||
|
return injectionDurationAngle * 0.5f;
|
||||||
|
} else {
|
||||||
|
// End of injection gets "full correction" so we advance opening by the full duration
|
||||||
|
return injectionDurationAngle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns false in case of error, true if success
|
* @returns false in case of error, true if success
|
||||||
*/
|
*/
|
||||||
|
@ -37,26 +59,19 @@ bool FuelSchedule::addFuelEventsForCylinder(int i ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// injection phase may be scheduled by injection end, so we need to step the angle back
|
||||||
* injection phase is scheduled by injection end, so we need to step the angle back
|
// for the duration of the injection
|
||||||
* for the duration of the injection
|
angle_t injectionDurationAngle = getInjectionAngleCorrection(engine->injectionDuration, oneDegreeUs);
|
||||||
*
|
|
||||||
* todo: since this method is not invoked within trigger event handler and
|
// User configured offset - degrees after TDC combustion
|
||||||
* engineState.injectionOffset is calculated from the same utility timer should we more that logic here?
|
|
||||||
*/
|
|
||||||
floatms_t fuelMs = engine->injectionDuration;
|
|
||||||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(fuelMs), "NaN fuelMs", false);
|
|
||||||
angle_t injectionDurationAngle = MS2US(fuelMs) / oneDegreeUs;
|
|
||||||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(injectionDurationAngle), "NaN injectionDurationAngle", false);
|
|
||||||
assertAngleRange(injectionDurationAngle, "injectionDuration_r", CUSTOM_INJ_DURATION);
|
|
||||||
floatus_t injectionOffset = engine->engineState.injectionOffset;
|
floatus_t injectionOffset = engine->engineState.injectionOffset;
|
||||||
if (cisnan(injectionOffset)) {
|
if (cisnan(injectionOffset)) {
|
||||||
// injection offset map not ready - we are not ready to schedule fuel events
|
// injection offset map not ready - we are not ready to schedule fuel events
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
angle_t baseAngle = injectionOffset - injectionDurationAngle;
|
|
||||||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(baseAngle), "NaN baseAngle", false);
|
angle_t openingAngle = injectionOffset - injectionDurationAngle;
|
||||||
assertAngleRange(baseAngle, "baseAngle_r", CUSTOM_ERR_6554);
|
assertAngleRange(openingAngle, "openingAngle_r", CUSTOM_ERR_6554);
|
||||||
|
|
||||||
injection_mode_e mode = engine->getCurrentInjectionMode();
|
injection_mode_e mode = engine->getCurrentInjectionMode();
|
||||||
|
|
||||||
|
@ -102,7 +117,6 @@ bool FuelSchedule::addFuelEventsForCylinder(int i ) {
|
||||||
|
|
||||||
InjectionEvent *ev = &elements[i];
|
InjectionEvent *ev = &elements[i];
|
||||||
|
|
||||||
ev->ownIndex = i;
|
|
||||||
ev->outputs[0] = output;
|
ev->outputs[0] = output;
|
||||||
ev->outputs[1] = secondOutput;
|
ev->outputs[1] = secondOutput;
|
||||||
ev->isSimultanious = isSimultanious;
|
ev->isSimultanious = isSimultanious;
|
||||||
|
@ -114,27 +128,27 @@ bool FuelSchedule::addFuelEventsForCylinder(int i ) {
|
||||||
warning(CUSTOM_OBD_INJECTION_NO_PIN_ASSIGNED, "no_pin_inj #%s", output->name);
|
warning(CUSTOM_OBD_INJECTION_NO_PIN_ASSIGNED, "no_pin_inj #%s", output->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
float angle = baseAngle + getCylinderAngle(i, ev->cylinderNumber);
|
// Convert from cylinder-relative to cylinder-1-relative
|
||||||
|
openingAngle += getCylinderAngle(i, ev->cylinderNumber);
|
||||||
|
|
||||||
if (TRIGGER_WAVEFORM(getSize()) < 1) {
|
if (TRIGGER_WAVEFORM(getSize()) < 1) {
|
||||||
warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform");
|
warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "findAngle#3", false);
|
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(openingAngle), "findAngle#3", false);
|
||||||
assertAngleRange(angle, "findAngle#a33", CUSTOM_ERR_6544);
|
assertAngleRange(openingAngle, "findAngle#a33", CUSTOM_ERR_6544);
|
||||||
ev->injectionStart.setAngle(angle);
|
ev->injectionStart.setAngle(openingAngle);
|
||||||
#if EFI_UNIT_TEST
|
#if EFI_UNIT_TEST
|
||||||
printf("registerInjectionEvent angle=%.2f trgIndex=%d inj %d\r\n", angle, ev->injectionStart.triggerEventIndex, injectorIndex);
|
printf("registerInjectionEvent openingAngle=%.2f trgIndex=%d inj %d\r\n", openingAngle, ev->injectionStart.triggerEventIndex, injectorIndex);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuelSchedule::addFuelEvents() {
|
void FuelSchedule::addFuelEvents() {
|
||||||
for (size_t cylinderIndex = 0; cylinderIndex < engineConfiguration->specs.cylindersCount; cylinderIndex++) {
|
for (size_t cylinderIndex = 0; cylinderIndex < engineConfiguration->specs.cylindersCount; cylinderIndex++) {
|
||||||
InjectionEvent *ev = &elements[cylinderIndex];
|
|
||||||
ev->ownIndex = cylinderIndex; // todo: is this assignment needed here? we now initialize in constructor
|
|
||||||
bool result = addFuelEventsForCylinder(cylinderIndex);
|
bool result = addFuelEventsForCylinder(cylinderIndex);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
invalidate();
|
invalidate();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -81,8 +81,6 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_
|
||||||
// Pull any extra timing for knock retard
|
// Pull any extra timing for knock retard
|
||||||
+ engine->knockController.getKnockRetard();
|
+ engine->knockController.getKnockRetard();
|
||||||
|
|
||||||
efiAssertVoid(CUSTOM_SPARK_ANGLE_9, !cisnan(sparkAngle), "findAngle#9");
|
|
||||||
|
|
||||||
efiAssertVoid(CUSTOM_SPARK_ANGLE_1, !cisnan(sparkAngle), "sparkAngle#1");
|
efiAssertVoid(CUSTOM_SPARK_ANGLE_1, !cisnan(sparkAngle), "sparkAngle#1");
|
||||||
const int index = engine->ignitionPin[event->cylinderIndex];
|
const int index = engine->ignitionPin[event->cylinderIndex];
|
||||||
const int coilIndex = ID2INDEX(getCylinderId(index));
|
const int coilIndex = ID2INDEX(getCylinderId(index));
|
||||||
|
|
|
@ -1199,7 +1199,10 @@ int16_t tps2Max;Full throttle#2. tpsMax value as 10 bit ADC value. Not Voltage!\
|
||||||
|
|
||||||
brain_input_pin_e[2 iterate] auxSpeedSensorInputPin;
|
brain_input_pin_e[2 iterate] auxSpeedSensorInputPin;
|
||||||
uint8_t totalGearsCount;;"", 1, 0, 1, @@GEARS_COUNT@@, 0
|
uint8_t totalGearsCount;;"", 1, 0, 1, @@GEARS_COUNT@@, 0
|
||||||
uint8_t unused16962;;"", 1, 0, 0, 1, 0
|
|
||||||
|
custom InjectionTimingMode 1 bits, U08, @OFFSET@, [0:1], "End of injection", "Start of injection", "Center of injection"
|
||||||
|
InjectionTimingMode injectionTimingMode;Sets what part of injection's is controlled by the injection phase table.
|
||||||
|
|
||||||
uint32_t uartConsoleSerialSpeed;Band rate for primary TTL;"BPs", 1, 0, 0, 1000000, 0
|
uint32_t uartConsoleSerialSpeed;Band rate for primary TTL;"BPs", 1, 0, 0, 1000000, 0
|
||||||
float tpsDecelEnleanmentThreshold;For decel we simply multiply delta of TPS and tFor decel we do not use table?!;"roc", 1, 0, 0, 200, 1
|
float tpsDecelEnleanmentThreshold;For decel we simply multiply delta of TPS and tFor decel we do not use table?!;"roc", 1, 0, 0, 200, 1
|
||||||
float tpsDecelEnleanmentMultiplier;Magic multiplier, we multiply delta of TPS and get fuel squirt duration;"coeff", 1, 0, 0, 200, 2
|
float tpsDecelEnleanmentMultiplier;Magic multiplier, we multiply delta of TPS and get fuel squirt duration;"coeff", 1, 0, 0, 200, 2
|
||||||
|
|
|
@ -1881,6 +1881,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
|
||||||
field = "Individually wired Batch Fuel", twoWireBatchInjection, {isInjectionEnabled == 1 && injectionMode == @@injection_mode_e_IM_BATCH@@ }
|
field = "Individually wired Batch Fuel", twoWireBatchInjection, {isInjectionEnabled == 1 && injectionMode == @@injection_mode_e_IM_BATCH@@ }
|
||||||
field = "Override VE table load axis", veOverrideMode, { isInjectionEnabled }
|
field = "Override VE table load axis", veOverrideMode, { isInjectionEnabled }
|
||||||
field = "Override AFR table load axis", afrOverrideMode, { isInjectionEnabled }
|
field = "Override AFR table load axis", afrOverrideMode, { isInjectionEnabled }
|
||||||
|
field = "Injection phase control mode", injectionTimingMode, { isInjectionEnabled }
|
||||||
|
|
||||||
dialog = ignitionOutputs, "Ignition Outputs"
|
dialog = ignitionOutputs, "Ignition Outputs"
|
||||||
field = "Ignition Pin Mode", ignitionPinMode, {isIgnitionEnabled == 1}
|
field = "Ignition Pin Mode", ignitionPinMode, {isIgnitionEnabled == 1}
|
||||||
|
|
Loading…
Reference in New Issue