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_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,

View File

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

View File

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

View File

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

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

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 = "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}