diff --git a/firmware/controllers/actuators/idle_thread.cpp b/firmware/controllers/actuators/idle_thread.cpp index e9662e6db8..60054e9c92 100644 --- a/firmware/controllers/actuators/idle_thread.cpp +++ b/firmware/controllers/actuators/idle_thread.cpp @@ -79,7 +79,14 @@ IIdleController::Phase IdleController::determinePhase(float rpm, IIdleController } looksLikeCrankToIdle = crankingTaperFraction < 1; - if (looksLikeCoasting && !looksLikeCrankToIdle) { + + // if car is gear, disable closed loop idle + // this applies to cars like NA/NB miatas where the clutch up switch only returns true if also in gear + bool transmissionInGear = engineConfiguration->disableIdleClutchUp + && isBrainPinValid(engineConfiguration->clutchUpPin) + && engine->engineState.clutchUpState; + + if ( (looksLikeCoasting || transmissionInGear) && !looksLikeCrankToIdle) { return Phase::Coasting; } diff --git a/firmware/controllers/actuators/idle_thread_io.cpp b/firmware/controllers/actuators/idle_thread_io.cpp index a87362b797..8de88f65bc 100644 --- a/firmware/controllers/actuators/idle_thread_io.cpp +++ b/firmware/controllers/actuators/idle_thread_io.cpp @@ -58,10 +58,9 @@ percent_t getIdlePosition() { void startPedalPins() { #if EFI_PROD_CODE - // this is neutral/no gear switch input. on Miata it's wired both to clutch pedal and neutral in gearbox - // this switch is not used yet startInputPinIfValid("clutch down switch", engineConfiguration->clutchDownPin, engineConfiguration->clutchDownPinMode); + // this is neutral/no gear switch input. on Miata it's wired both to clutch pedal and neutral in gearbox startInputPinIfValid("clutch up switch", engineConfiguration->clutchUpPin, engineConfiguration->clutchUpPinMode); startInputPinIfValid("brake pedal switch", engineConfiguration->brakePedalPin, engineConfiguration->brakePedalPinMode); diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 6e3d03d606..6d7ea6fe9c 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -940,7 +940,7 @@ bit useFixedBaroCorrFromMap bit useSeparateAdvanceForCranking,"Table","Fixed (auto taper)";In Constant mode, timing is automatically tapered to running as RPM increases.\nIn Table mode, the "Cranking ignition advance" table is used directly. bit useAdvanceCorrectionsForCranking;This enables the various ignition corrections during cranking (IAT, CLT, FSIO and PID idle).\nYou probably don't need this. bit flexCranking;Enable a second cranking table to use for E100 flex fuel, interpolating between the two based on flex fuel sensor. -bit unused1200b19 +bit disableIdleClutchUp;Disable closed loop idle if ClutchUp is true. Only works for vehicles where the signal is only present when in gear, like NA/NB miatas. This helps prevent integral saturation while coasting at low RPM bit isBoostControlEnabled bit launchSmoothRetard;Interpolates the Ignition Retard from 0 to 100% within the RPM Range bit isPhaseSyncRequiredForIgnition;Some engines are OK running semi-random sequential while other engine require phase synchronization diff --git a/firmware/tunerstudio/tunerstudio.template.ini b/firmware/tunerstudio/tunerstudio.template.ini index 3013dd5899..9e29f742da 100644 --- a/firmware/tunerstudio/tunerstudio.template.ini +++ b/firmware/tunerstudio/tunerstudio.template.ini @@ -3436,6 +3436,7 @@ dialog = launch_control_stateDialog, "launch_control_state" field = "TPS threshold", idlePidDeactivationTpsThreshold field = "RPM upper limit", idlePidRpmUpperLimit field = "Max vehicle speed", maxIdleVss + field = "Disable Idle in Gear", disableIdleClutchUp, {clutchUpPin != @@ADC_CHANNEL_NONE@@} dialog = idleExtra, "Extra Idle Features" field = "Use idle ignition table", useSeparateAdvanceForIdle diff --git a/unit_tests/tests/test_idle_controller.cpp b/unit_tests/tests/test_idle_controller.cpp index b047330900..fa4bd3edb3 100644 --- a/unit_tests/tests/test_idle_controller.cpp +++ b/unit_tests/tests/test_idle_controller.cpp @@ -113,6 +113,27 @@ TEST(idle_v2, testDeterminePhase) { // above upper limit and on throttle should be out of idle zone EXPECT_EQ(ICP::Running, dut.determinePhase(1101, targetInfo, 10, 0, 10)); + { + // enable feature to prevent idle state when coasting in gear + engineConfiguration->disableIdleClutchUp = true; + setMockState(engineConfiguration->clutchUpPin, false); + engineConfiguration->clutchUpPin = Gpio::G2; + engineConfiguration->clutchUpPinMode = PI_PULLDOWN; + engine->updateSwitchInputs(); + + // should be same behaviour as before when clutch is pressed/car in neutral + EXPECT_EQ(ICP::Idling, dut.determinePhase(1099, targetInfo, 0, 0, 10)); + EXPECT_EQ(ICP::Coasting, dut.determinePhase(1101, targetInfo, 0, 0, 10)); + EXPECT_EQ(ICP::CrankToIdleTaper, dut.determinePhase(1000, targetInfo, 0, 0, 0.5f)); + EXPECT_EQ(ICP::Running, dut.determinePhase(1000, targetInfo, 10, 0, 10)); + + // clutchUp indicates car in gear with clutch not pressed, should recognize as coasting instead of idle now + setMockState(engineConfiguration->clutchUpPin, true); + engine->updateSwitchInputs(); + EXPECT_EQ(ICP::Coasting, dut.determinePhase(1099, targetInfo, 0, 0, 10)); + EXPECT_EQ(ICP::Coasting, dut.determinePhase(1101, targetInfo, 0, 0, 10)); + } + // Below TPS but above RPM should be outside the zone EXPECT_EQ(ICP::Coasting, dut.determinePhase(1101, targetInfo, 0, 0, 10)); EXPECT_EQ(ICP::Coasting, dut.determinePhase(5000, targetInfo, 0, 0, 10));