diff --git a/firmware/controllers/algo/engine_configuration_generated_structures.h b/firmware/controllers/algo/engine_configuration_generated_structures.h index d150062d0e..d6841f0762 100644 --- a/firmware/controllers/algo/engine_configuration_generated_structures.h +++ b/firmware/controllers/algo/engine_configuration_generated_structures.h @@ -1,4 +1,4 @@ -// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue Jul 25 20:21:45 EDT 2017 +// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Mon Jul 31 14:44:23 EDT 2017 // begin #ifndef ENGINE_CONFIGURATION_GENERATED_H_ #define ENGINE_CONFIGURATION_GENERATED_H_ @@ -1583,7 +1583,15 @@ typedef struct { /** * offset 2168 */ - float unusedalternatorControl[4]; + int16_t afterCrankingIACtaperDuration; + /** + * offset 2170 + */ + int16_t unusedShortHere; + /** + * offset 2172 + */ + float unusedalternatorControl[3]; /** * offset 2184 */ @@ -2131,4 +2139,4 @@ typedef struct { #endif // end -// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue Jul 25 20:21:45 EDT 2017 +// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Mon Jul 31 14:44:23 EDT 2017 diff --git a/firmware/controllers/algo/rusefi_generated.h b/firmware/controllers/algo/rusefi_generated.h index 9092c4c6ea..5b02898174 100644 --- a/firmware/controllers/algo/rusefi_generated.h +++ b/firmware/controllers/algo/rusefi_generated.h @@ -1116,8 +1116,12 @@ #define alternatorOffAboveTps_offset_hex 870 #define startOfCrankingPrimingPulse_offset 2164 #define startOfCrankingPrimingPulse_offset_hex 874 -#define unusedalternatorControl_offset 2168 -#define unusedalternatorControl_offset_hex 878 +#define afterCrankingIACtaperDuration_offset 2168 +#define afterCrankingIACtaperDuration_offset_hex 878 +#define unusedShortHere_offset 2170 +#define unusedShortHere_offset_hex 87a +#define unusedalternatorControl_offset 2172 +#define unusedalternatorControl_offset_hex 87c #define tpsAccelLength_offset 2184 #define tpsAccelLength_offset_hex 888 #define tpsAccelEnrichmentThreshold_offset 2188 diff --git a/firmware/controllers/core/interpolation.cpp b/firmware/controllers/core/interpolation.cpp index c606bb6591..90223b0ec7 100644 --- a/firmware/controllers/core/interpolation.cpp +++ b/firmware/controllers/core/interpolation.cpp @@ -129,6 +129,17 @@ float interpolate(float x1, float y1, float x2, float y2, float x) { return interpolateMsg("", x1, y1, x2, y2, x); } +float interpolateClamped(float x1, float y1, float x2, float y2, float x) { + if (x <= x1) + return y1; + if (x >= x2) + return y2; + + float a = INTERPOLATION_A(x1, y1, x2, y2); + float b = y1 - a * x1; + return a * x + b; +} + /** * Another implementation, which one is faster? */ diff --git a/firmware/controllers/core/interpolation.h b/firmware/controllers/core/interpolation.h index ae85c8d5f7..71ff04579a 100644 --- a/firmware/controllers/core/interpolation.h +++ b/firmware/controllers/core/interpolation.h @@ -25,6 +25,7 @@ int findIndexMsg(const char *msg, const float array[], int size, float value); void ensureArrayIsAscending(const char *msg, const float array[], int size); int findIndex2(const float array[], unsigned size, float value); float interpolate(float x1, float y1, float x2, float y2, float x); +float interpolateClamped(float x1, float y1, float x2, float y2, float x); float interpolateMsg(const char *msg, float x1, float y1, float x2, float y2, float x); float interpolate2d(const char *msg, float value, float bin[], float values[], int size); diff --git a/firmware/controllers/idle_thread.cpp b/firmware/controllers/idle_thread.cpp index 1f38371cca..6e5fac9baa 100644 --- a/firmware/controllers/idle_thread.cpp +++ b/firmware/controllers/idle_thread.cpp @@ -54,6 +54,9 @@ static StepperMotor iacMotor; static int adjustedTargetRpm; +static uint32_t lastCrankingCyclesCounter = 0; +static float lastCrankingIacPosition; + /** * that's current position with CLT and IAT corrections */ @@ -154,8 +157,10 @@ percent_t getIdlePosition(void) { } static float autoIdle(float cltCorrection) { - if (getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) > boardConfiguration->idlePidDeactivationTpsThreshold) + if (getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) > boardConfiguration->idlePidDeactivationTpsThreshold) { + // just leave IAC position as is return currentIdlePosition; + } adjustedTargetRpm = engineConfiguration->targetIdleRpm * cltCorrection; @@ -211,11 +216,21 @@ static msg_t ivThread(int param) { } else if (!engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE)) { // during cranking it's always manual mode, PID would make no sence during cranking iacPosition = cltCorrection * engineConfiguration->crankingIACposition; - } else if (engineConfiguration->idleMode == IM_MANUAL) { - // let's re-apply CLT correction - iacPosition = manualIdleController(cltCorrection); + // save cranking position & cycles counter for taper transition + lastCrankingIacPosition = iacPosition; + lastCrankingCyclesCounter = engine->rpmCalculator.getRevolutionCounterSinceStart(); } else { - iacPosition = autoIdle(cltCorrection); + if (engineConfiguration->idleMode == IM_MANUAL) { + // let's re-apply CLT correction + iacPosition = manualIdleController(cltCorrection); + } else { + iacPosition = autoIdle(cltCorrection); + } + // taper transition from cranking to running (uint32_t to float conversion is safe here) + if (engineConfiguration->afterCrankingIACtaperDuration > 0) + iacPosition = interpolateClamped(lastCrankingCyclesCounter, lastCrankingIacPosition, + lastCrankingCyclesCounter + engineConfiguration->afterCrankingIACtaperDuration, iacPosition, + engine->rpmCalculator.getRevolutionCounterSinceStart()); } if (absF(iacPosition - currentIdlePosition) < 1) { diff --git a/firmware/hw_layer/rtc_helper.cpp b/firmware/hw_layer/rtc_helper.cpp index 99a0839ad6..8e70ea08bc 100644 --- a/firmware/hw_layer/rtc_helper.cpp +++ b/firmware/hw_layer/rtc_helper.cpp @@ -13,7 +13,6 @@ #include "rtc_helper.h" #if EFI_RTC || defined(__DOXYGEN__) -#include "rtc.h" static LoggingWithStorage logger("RTC"); static RTCDateTime timespec; diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 335f1d7eda..e0434c04c6 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -721,7 +721,10 @@ custom pin_mode_e 4 bits, U32, @OFFSET@, [0:5], @@pin_mode_e_enum@@ float targetVBatt;set targetvbatt VOLTS;"Volts", 1, 0, 0,30, 1 float alternatorOffAboveTps;Turn off alternator output above specified TPS;"%", 1, 0, 0, 200, 2 float startOfCrankingPrimingPulse;;"ms", 1, 0, 0, 200, 1 - float[4] unusedalternatorControl; + int16_t afterCrankingIACtaperDuration;;"cycles", 1, 0, 0, 5000, 0 + int16_t unusedShortHere;;"seconds", 1, 0, 0, 6000, 0 + + float[3] unusedalternatorControl; int tpsAccelLength;;"cycles", 1, 0, 1, 200, 0 float tpsAccelEnrichmentThreshold;;"roc", 1, 0, 0, 200, 3 diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index e7e313a58c..0bfed7c499 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -1621,6 +1621,7 @@ cmd_stop_engine = "w\x00\x99\x00\x00" field = "" field = "enable Cylinder Cleanup", isCylinderCleanupEnabled field = "Startup fuel prime duration", startUpFuelPumpDuration + field = "After cranking IAC taper duration", afterCrankingIACtaperDuration dialog = EngineLoadAccelPanel, "Engine Load" diff --git a/java_console/models/src/com/rusefi/config/Fields.java b/java_console/models/src/com/rusefi/config/Fields.java index cea846a461..8684d3ac38 100644 --- a/java_console/models/src/com/rusefi/config/Fields.java +++ b/java_console/models/src/com/rusefi/config/Fields.java @@ -811,8 +811,10 @@ public class Fields { public static final int alternatorOffAboveTps_offset_hex = 870; public static final int startOfCrankingPrimingPulse_offset = 2164; public static final int startOfCrankingPrimingPulse_offset_hex = 874; - public static final int unusedalternatorControl_offset = 2168; - public static final int unusedalternatorControl_offset_hex = 878; + public static final int afterCrankingIACtaperDuration_offset = 2168; + public static final int afterCrankingIACtaperDuration_offset_hex = 878; + public static final int unusedShortHere_offset = 2170; + public static final int unusedalternatorControl_offset = 2172; public static final int tpsAccelLength_offset = 2184; public static final int tpsAccelLength_offset_hex = 888; public static final int tpsAccelEnrichmentThreshold_offset = 2188; @@ -1612,6 +1614,8 @@ public class Fields { public static final Field TARGETVBATT = Field.create("TARGETVBATT", 2156, FieldType.FLOAT); public static final Field ALTERNATOROFFABOVETPS = Field.create("ALTERNATOROFFABOVETPS", 2160, FieldType.FLOAT); public static final Field STARTOFCRANKINGPRIMINGPULSE = Field.create("STARTOFCRANKINGPRIMINGPULSE", 2164, FieldType.FLOAT); + public static final Field AFTERCRANKINGIACTAPERDURATION = Field.create("AFTERCRANKINGIACTAPERDURATION", 2168, FieldType.INT); + public static final Field UNUSEDSHORTHERE = Field.create("UNUSEDSHORTHERE", 2170, FieldType.INT); public static final Field TPSACCELLENGTH = Field.create("TPSACCELLENGTH", 2184, FieldType.INT); public static final Field TPSACCELENRICHMENTTHRESHOLD = Field.create("TPSACCELENRICHMENTTHRESHOLD", 2188, FieldType.FLOAT); public static final Field VVTOFFSET = Field.create("VVTOFFSET", 2192, FieldType.FLOAT);