rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
prime_injection.cpp
Go to the documentation of this file.
1/*
2 * @file prime_injection.cpp
3 */
4
5#include "pch.h"
6#include "prime_injection.h"
7#include "injection_gpio.h"
8#include "sensor.h"
9#include "backup_ram.h"
10#if EFI_PROD_CODE
11#include "microsecond_timer.h"
12#endif
13
16
17 // If the coolant sensor is dead, skip the prime. The engine will still start fine, but may take a little longer.
18 if (!clt) {
19 return 0;
20 }
21
22 auto primeMass =
23 0.001f * // convert milligram to gram
25
26 efiPrintf("Priming pulse mass: %.4f g", primeMass);
27
28 return engine->module<InjectorModelPrimary>()->getInjectionDuration(primeMass);
29}
30
31// Check if the engine is not stopped or cylinder cleanup is activated
33 // Skip if the engine is already spinning
34 if (!getEngineRotationState()->isStopped()) {
35 return true;
36 }
37
38 // Skip if cylinder cleanup is active
40}
41
43 if (!ignitionOn) {
44 // don't prime on ignition-off
45 return;
46 }
47
48 // First, we need a protection against 'fake' ignition switch on and off (i.e. no engine started), to avoid repeated prime pulses.
49 // So we check and update the ignition switch counter in non-volatile backup-RAM
50 uint32_t ignSwitchCounter = getKeyCycleCounter();
51
52 // if we're just toying with the ignition switch, give it another chance eventually...
53 if (ignSwitchCounter > 10) {
54 ignSwitchCounter = 0;
55 }
56
57 // If we're going to skip this pulse, then save the counter as 0.
58 // That's because we'll definitely need the prime pulse next time (either due to the cylinder cleanup or the engine spinning)
60 ignSwitchCounter = -1;
61 }
62
63 // start prime injection if this is a 'fresh start'
64 if (ignSwitchCounter == 0) {
65 // Give sensors long enough to wake up before priming
66 constexpr float minimumPrimeDelayMs = 100;
67 int32_t primeDelayNt = assertFloatFitsInto32BitsAndCast("primingDelay", MSF2NT(engineConfiguration->primingDelay * 1000 + minimumPrimeDelayMs));
68
69 auto startTime = getTimeNowNt() + primeDelayNt;
70 getScheduler()->schedule("primingDelay", nullptr, startTime, action_s::make<onPrimeStartAdapter>( this ));
71 } else {
72 efiPrintf("Skipped priming pulse since ignSwitchCounter = %lu", ignSwitchCounter);
73 }
74
75 // we'll reset it later when the engine starts
76 setKeyCycleCounter(ignSwitchCounter + 1);
77}
78
80#if EFI_BACKUP_SRAM
82#endif // EFI_BACKUP_SRAM
83}
84
86#if EFI_BACKUP_SRAM
88#else // not EFI_BACKUP_SRAM
89 return 0;
90#endif // EFI_BACKUP_SRAM
91}
92
94 auto durationMs = getPrimeDuration();
95
96 // Don't prime a zero-duration pulse
97 if (durationMs <= 0) {
98 efiPrintf("Skipped zero-duration priming pulse.");
99 return;
100 }
101#if EFI_PROD_CODE
102 if (durationMs >= TOO_FAR_INTO_FUTURE_MS) {
103 criticalError("Priming duration too long %dms", durationMs);
104 }
105#endif
106
107 efiPrintf("Firing priming pulse of %.2f ms", durationMs);
109
110 auto endTime = sumTickAndFloat(getTimeNowNt(), MSF2NT(durationMs));
111
112 // Open all injectors, schedule closing later
113 m_isPriming = true;
115 getScheduler()->schedule("onPrimeStart", nullptr, endTime, action_s::make<onPrimeEndAdapter>( this ));
116}
117
123
125 if (!getEngineRotationState()->isStopped()) {
126#if EFI_BACKUP_SRAM
128#endif /* EFI_BACKUP_SRAM */
129 }
130}
Non-volatile backup-RAM registers support.
uint32_t backupRamLoad(backup_ram_e idx)
void backupRamSave(backup_ram_e idx, uint32_t value)
TunerStudioOutputChannels outputChannels
Definition engine.h:109
constexpr auto & module()
Definition engine.h:200
floatms_t getPrimeDuration() const
void onSlowCallback() override
void setKeyCycleCounter(uint32_t count)
uint32_t getKeyCycleCounter() const
void onIgnitionStateChanged(bool ignitionOn) override
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
efitick_t getTimeNowNt()
Definition efitime.cpp:19
efitick_t sumTickAndFloat(efitick_t ticks, float extra)
Definition efitime.h:90
constexpr int32_t assertFloatFitsInto32BitsAndCast(const char *msg, float value)
Definition efitime.h:82
Scheduler * getScheduler()
Definition engine.cpp:585
EngineRotationState * getEngineRotationState()
Definition engine.cpp:573
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10))
void startSimultaneousInjection()
void endSimultaneousInjectionOnlyTogglePins()
static bool isPrimeInjectionPulseSkipped()
Base class for sensors. Inherit this class to implement a new type of sensor.
virtual void schedule(const char *msg, scheduling_s *scheduling, efitick_t targetTime, action_s const &action)=0
Schedule an action to be executed in the future.
scaled_channel< int16_t, 1, 1 > primeBins[PRIME_CURVE_COUNT]
scaled_channel< uint8_t, 1, 5 > primeValues[PRIME_CURVE_COUNT]
uint16_t count
Definition tunerstudio.h:1