mirror of https://github.com/rusefi/rusefi.git
prime upon ignition voltage, not on power on (#3662)
* ignition controller detects rising edge on voltage * update test * comment * ignore negative transients * tweak * test * priming happens on ignition-on * priming has its own scheduling * test * dead adjacent line of code
This commit is contained in:
parent
161d75197d
commit
2050580a16
|
@ -108,7 +108,14 @@ protected:
|
||||||
trigger_type_e getType() const override;
|
trigger_type_e getType() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_MOCK_SPEED -1
|
class PrimeController : public EngineModule {
|
||||||
|
public:
|
||||||
|
void onIgnitionStateChanged(bool ignitionOn) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
scheduling_s m_start;
|
||||||
|
scheduling_s m_end;
|
||||||
|
};
|
||||||
|
|
||||||
class Engine final : public TriggerStateListener {
|
class Engine final : public TriggerStateListener {
|
||||||
public:
|
public:
|
||||||
|
@ -136,8 +143,6 @@ public:
|
||||||
|
|
||||||
PinRepository pinRepository;
|
PinRepository pinRepository;
|
||||||
|
|
||||||
InjectionEvent primeInjEvent;
|
|
||||||
|
|
||||||
IEtbController *etbControllers[ETB_COUNT] = {nullptr};
|
IEtbController *etbControllers[ETB_COUNT] = {nullptr};
|
||||||
IFuelComputer *fuelComputer = nullptr;
|
IFuelComputer *fuelComputer = nullptr;
|
||||||
|
|
||||||
|
@ -157,6 +162,7 @@ public:
|
||||||
MainRelayController,
|
MainRelayController,
|
||||||
IgnitionController,
|
IgnitionController,
|
||||||
AcController,
|
AcController,
|
||||||
|
PrimeController,
|
||||||
EngineModule // dummy placeholder so the previous entries can all have commas
|
EngineModule // dummy placeholder so the previous entries can all have commas
|
||||||
> engineModules;
|
> engineModules;
|
||||||
|
|
||||||
|
|
|
@ -438,10 +438,14 @@ static bool isPrimeInjectionPulseSkipped() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prime injection pulse, mainly needed for mono-injectors or long intake manifolds.
|
* Prime injection pulse
|
||||||
* See testStartOfCrankingPrimingPulse()
|
* See testStartOfCrankingPrimingPulse()
|
||||||
*/
|
*/
|
||||||
void startPrimeInjectionPulse() {
|
void PrimeController::onIgnitionStateChanged(bool ignitionOn) {
|
||||||
|
if (!ignitionOn) {
|
||||||
|
// don't prime on ignition-off
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// First, we need a protection against 'fake' ignition switch on and off (i.e. no engine started), to avoid repeated prime pulses.
|
// First, we need a protection against 'fake' ignition switch on and off (i.e. no engine started), to avoid repeated prime pulses.
|
||||||
// So we check and update the ignition switch counter in non-volatile backup-RAM
|
// So we check and update the ignition switch counter in non-volatile backup-RAM
|
||||||
|
@ -460,20 +464,28 @@ void startPrimeInjectionPulse() {
|
||||||
ignSwitchCounter = -1;
|
ignSwitchCounter = -1;
|
||||||
// start prime injection if this is a 'fresh start'
|
// start prime injection if this is a 'fresh start'
|
||||||
if (ignSwitchCounter == 0) {
|
if (ignSwitchCounter == 0) {
|
||||||
engine->primeInjEvent.ownIndex = 0;
|
|
||||||
engine->primeInjEvent.isSimultanious = true;
|
|
||||||
|
|
||||||
scheduling_s *sDown = &engine->injectionEvents.elements[0].endOfInjectionEvent;
|
|
||||||
// When the engine is hot, basically we don't need prime inj.pulse, so we use an interpolation over temperature (falloff).
|
// When the engine is hot, basically we don't need prime inj.pulse, so we use an interpolation over temperature (falloff).
|
||||||
// If 'primeInjFalloffTemperature' is not specified (by default), we have a prime pulse deactivation at zero celsius degrees, which is okay.
|
// If 'primeInjFalloffTemperature' is not specified (by default), we have a prime pulse deactivation at zero celsius degrees, which is okay.
|
||||||
const float maxPrimeInjAtTemperature = -40.0f; // at this temperature the pulse is maximal.
|
const float maxPrimeInjAtTemperature = -40.0f; // at this temperature the pulse is maximal.
|
||||||
floatms_t pulseLength = interpolateClamped(maxPrimeInjAtTemperature, engineConfiguration->startOfCrankingPrimingPulse,
|
floatms_t pulseLength = interpolateClamped(maxPrimeInjAtTemperature, engineConfiguration->startOfCrankingPrimingPulse,
|
||||||
engineConfiguration->primeInjFalloffTemperature, 0.0f, Sensor::get(SensorType::Clt).value_or(70));
|
engineConfiguration->primeInjFalloffTemperature, 0.0f, Sensor::get(SensorType::Clt).value_or(70));
|
||||||
|
|
||||||
|
efiPrintf("Firing priming pulse of %.2f ms", pulseLength);
|
||||||
|
|
||||||
if (pulseLength > 0) {
|
if (pulseLength > 0) {
|
||||||
startSimultaniousInjection();
|
auto now = getTimeNowNt();
|
||||||
int turnOffDelayUs = efiRound(MS2US(pulseLength), 1.0f);
|
|
||||||
engine->executor.scheduleForLater(sDown, turnOffDelayUs, { &endSimultaniousInjectionOnlyTogglePins, engine });
|
// TODO: configurable prime delay
|
||||||
|
auto primeDelayMs = 200;
|
||||||
|
|
||||||
|
auto start = now + MS2NT(primeDelayMs);
|
||||||
|
auto end = start + MS2NT(pulseLength);
|
||||||
|
|
||||||
|
engine->executor.scheduleByTimestampNt("prime", &m_start, start, startSimultaniousInjection);
|
||||||
|
engine->executor.scheduleByTimestampNt("prime", &m_end, end, endSimultaniousInjectionOnlyTogglePins);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
efiPrintf("Skipped priming pulse since ignSwitchCounter = %d", ignSwitchCounter);
|
||||||
}
|
}
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
// we'll reset it later when the engine starts
|
// we'll reset it later when the engine starts
|
||||||
|
@ -511,11 +523,6 @@ void initMainEventListener() {
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
addConsoleActionP("maininfo", (VoidPtr) showMainInfo, engine);
|
addConsoleActionP("maininfo", (VoidPtr) showMainInfo, engine);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We start prime injection pulse at the early init stage - don't wait for the engine to start spinning!
|
|
||||||
if (engineConfiguration->startOfCrankingPrimingPulse > 0)
|
|
||||||
startPrimeInjectionPulse();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EFI_ENGINE_CONTROL */
|
#endif /* EFI_ENGINE_CONTROL */
|
||||||
|
|
|
@ -15,8 +15,6 @@ void initMainEventListener();
|
||||||
|
|
||||||
void mainTriggerCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp);
|
void mainTriggerCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp);
|
||||||
|
|
||||||
void startPrimeInjectionPulse();
|
|
||||||
|
|
||||||
void startSimultaniousInjection(void* = nullptr);
|
void startSimultaniousInjection(void* = nullptr);
|
||||||
void endSimultaniousInjection(InjectionEvent *event);
|
void endSimultaniousInjection(InjectionEvent *event);
|
||||||
void turnInjectionPinHigh(InjectionEvent *event);
|
void turnInjectionPinHigh(InjectionEvent *event);
|
||||||
|
|
|
@ -42,10 +42,9 @@ TEST(engine, testStartOfCrankingPrimingPulse) {
|
||||||
// we need below freezing temperature to get prime fuel
|
// we need below freezing temperature to get prime fuel
|
||||||
Sensor::setMockValue(SensorType::Clt, -10);
|
Sensor::setMockValue(SensorType::Clt, -10);
|
||||||
|
|
||||||
// prod code invokes this on ECU start, here we have to mimic this behavior
|
// Turn on the ignition switch!
|
||||||
startPrimeInjectionPulse();
|
engine->module<PrimeController>()->onIgnitionStateChanged(true);
|
||||||
|
|
||||||
|
ASSERT_EQ(2, engine->executor.size()) << "prime fuel";
|
||||||
ASSERT_EQ( 1, engine->executor.size()) << "prime fuel";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue