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:
Matthew Kennedy 2022-04-15 07:22:36 -07:00 committed by GitHub
parent 11cea53c36
commit 497e7ffe77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 29 deletions

View File

@ -2042,7 +2042,7 @@ typedef enum {
CUSTOM_ERR_6686 = 6686,
CUSTOM_FIRING_LENGTH = 6687,
CUSTOM_ADVANCE_SPARK = 6688,
CUSTOM_SPARK_ANGLE_9 = 6689,
CUSTOM_ERR_6689 = 6689,
CUSTOM_ERR_MAP_START_ASSERT = 6690,
CUSTOM_ERR_MAP_AVG_OFFSET = 6691,

View File

@ -706,4 +706,10 @@ enum class TransmissionControllerMode : uint8_t {
Gm4l6x = 2,
};
enum class InjectionTimingMode : uint8_t {
End = 0,
Start = 1,
Center = 2,
};
#endif // __cplusplus

View File

@ -11,8 +11,7 @@
FuelSchedule::FuelSchedule() {
for (int cylinderIndex = 0; cylinderIndex < MAX_CYLINDER_COUNT; cylinderIndex++) {
InjectionEvent *ev = &elements[cylinderIndex];
ev->ownIndex = cylinderIndex;
elements[cylinderIndex].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
*/
@ -37,26 +59,19 @@ bool FuelSchedule::addFuelEventsForCylinder(int i ) {
return false;
}
/**
* injection phase is scheduled by injection end, so we need to step the angle back
* for the duration of the injection
*
* todo: since this method is not invoked within trigger event handler and
* 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);
// injection phase may be scheduled by injection end, so we need to step the angle back
// for the duration of the injection
angle_t injectionDurationAngle = getInjectionAngleCorrection(engine->injectionDuration, oneDegreeUs);
// User configured offset - degrees after TDC combustion
floatus_t injectionOffset = engine->engineState.injectionOffset;
if (cisnan(injectionOffset)) {
// injection offset map not ready - we are not ready to schedule fuel events
return false;
}
angle_t baseAngle = injectionOffset - injectionDurationAngle;
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(baseAngle), "NaN baseAngle", false);
assertAngleRange(baseAngle, "baseAngle_r", CUSTOM_ERR_6554);
angle_t openingAngle = injectionOffset - injectionDurationAngle;
assertAngleRange(openingAngle, "openingAngle_r", CUSTOM_ERR_6554);
injection_mode_e mode = engine->getCurrentInjectionMode();
@ -102,7 +117,6 @@ bool FuelSchedule::addFuelEventsForCylinder(int i ) {
InjectionEvent *ev = &elements[i];
ev->ownIndex = i;
ev->outputs[0] = output;
ev->outputs[1] = secondOutput;
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);
}
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) {
warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform");
return false;
}
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "findAngle#3", false);
assertAngleRange(angle, "findAngle#a33", CUSTOM_ERR_6544);
ev->injectionStart.setAngle(angle);
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(openingAngle), "findAngle#3", false);
assertAngleRange(openingAngle, "findAngle#a33", CUSTOM_ERR_6544);
ev->injectionStart.setAngle(openingAngle);
#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
return true;
}
void FuelSchedule::addFuelEvents() {
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);
if (!result) {
invalidate();
return;

View File

@ -81,8 +81,6 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_
// Pull any extra timing for knock retard
+ engine->knockController.getKnockRetard();
efiAssertVoid(CUSTOM_SPARK_ANGLE_9, !cisnan(sparkAngle), "findAngle#9");
efiAssertVoid(CUSTOM_SPARK_ANGLE_1, !cisnan(sparkAngle), "sparkAngle#1");
const int index = engine->ignitionPin[event->cylinderIndex];
const int coilIndex = ID2INDEX(getCylinderId(index));

View File

@ -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;
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
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

View File

@ -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 = "Override VE table load axis", veOverrideMode, { isInjectionEnabled }
field = "Override AFR table load axis", afrOverrideMode, { isInjectionEnabled }
field = "Injection phase control mode", injectionTimingMode, { isInjectionEnabled }
dialog = ignitionOutputs, "Ignition Outputs"
field = "Ignition Pin Mode", ignitionPinMode, {isIgnitionEnabled == 1}