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;
|
||||
};
|
||||
|
||||
#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 {
|
||||
public:
|
||||
|
@ -136,8 +143,6 @@ public:
|
|||
|
||||
PinRepository pinRepository;
|
||||
|
||||
InjectionEvent primeInjEvent;
|
||||
|
||||
IEtbController *etbControllers[ETB_COUNT] = {nullptr};
|
||||
IFuelComputer *fuelComputer = nullptr;
|
||||
|
||||
|
@ -157,6 +162,7 @@ public:
|
|||
MainRelayController,
|
||||
IgnitionController,
|
||||
AcController,
|
||||
PrimeController,
|
||||
EngineModule // dummy placeholder so the previous entries can all have commas
|
||||
> 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()
|
||||
*/
|
||||
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.
|
||||
// So we check and update the ignition switch counter in non-volatile backup-RAM
|
||||
|
@ -460,20 +464,28 @@ void startPrimeInjectionPulse() {
|
|||
ignSwitchCounter = -1;
|
||||
// start prime injection if this is a 'fresh start'
|
||||
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).
|
||||
// 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.
|
||||
floatms_t pulseLength = interpolateClamped(maxPrimeInjAtTemperature, engineConfiguration->startOfCrankingPrimingPulse,
|
||||
engineConfiguration->primeInjFalloffTemperature, 0.0f, Sensor::get(SensorType::Clt).value_or(70));
|
||||
|
||||
efiPrintf("Firing priming pulse of %.2f ms", pulseLength);
|
||||
|
||||
if (pulseLength > 0) {
|
||||
startSimultaniousInjection();
|
||||
int turnOffDelayUs = efiRound(MS2US(pulseLength), 1.0f);
|
||||
engine->executor.scheduleForLater(sDown, turnOffDelayUs, { &endSimultaniousInjectionOnlyTogglePins, engine });
|
||||
auto now = getTimeNowNt();
|
||||
|
||||
// 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
|
||||
// we'll reset it later when the engine starts
|
||||
|
@ -511,11 +523,6 @@ void initMainEventListener() {
|
|||
#if EFI_PROD_CODE
|
||||
addConsoleActionP("maininfo", (VoidPtr) showMainInfo, engine);
|
||||
#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 */
|
||||
|
|
|
@ -15,8 +15,6 @@ void initMainEventListener();
|
|||
|
||||
void mainTriggerCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp);
|
||||
|
||||
void startPrimeInjectionPulse();
|
||||
|
||||
void startSimultaniousInjection(void* = nullptr);
|
||||
void endSimultaniousInjection(InjectionEvent *event);
|
||||
void turnInjectionPinHigh(InjectionEvent *event);
|
||||
|
|
|
@ -42,10 +42,9 @@ TEST(engine, testStartOfCrankingPrimingPulse) {
|
|||
// we need below freezing temperature to get prime fuel
|
||||
Sensor::setMockValue(SensorType::Clt, -10);
|
||||
|
||||
// prod code invokes this on ECU start, here we have to mimic this behavior
|
||||
startPrimeInjectionPulse();
|
||||
// Turn on the ignition switch!
|
||||
engine->module<PrimeController>()->onIgnitionStateChanged(true);
|
||||
|
||||
|
||||
ASSERT_EQ( 1, engine->executor.size()) << "prime fuel";
|
||||
ASSERT_EQ(2, engine->executor.size()) << "prime fuel";
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue