26#if EFI_PRINTF_FUEL_DETAILS
30#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
36#include "cyclic_buffer.h"
58 for (
size_t i = 0; i < efi::size(event->
outputs); i++) {
70 for (
size_t i = 0; i < efi::size(event->
outputsStage2); i++) {
98 const float injectionMassStage2 = stage2Fraction * injectionMassGrams;
99 float injectionMassStage1 = injectionMassGrams - injectionMassStage2;
108 float actualInjectedMass = numberOfInjections * (injectionMassStage1 + injectionMassStage2);
110#ifdef MODULE_ODOMETER
120#if EFI_PRINTF_FUEL_DETAILS
122 printf(
"fuel injectionDuration=%.2fms adjusted=%.2fms\n",
124 injectionDurationStage1);
143 if (std::isnan(injectionDurationStage1) || std::isnan(injectionDurationStage2)) {
147 if (injectionDurationStage1 < 0) {
156 if (injectionDurationStage1 < 0.050f)
161 floatus_t durationUsStage1 = MS2US(injectionDurationStage1);
162 floatus_t durationUsStage2 = MS2US(injectionDurationStage2);
165 bool hasStage2Injection = durationUsStage2 > 50;
167#if EFI_PRINTF_FUEL_DETAILS
170 printf(
"handleFuelInjectionEvent fuelout %s injection_duration %dus engineCycleDuration=%.1fms\t\n", output->
getName(), (
int)durationUsStage1,
175 action_s startAction, endActionStage1, endActionStage2;
178 startAction = action_s::make<startSimultaneousInjection>();
179 endActionStage1 = action_s::make<endSimultaneousInjection>(
this);
181 auto const taggedPointer{
TaggedPointer<
decltype(
this)>::make(
this, hasStage2Injection)};
184 startAction = action_s::make<turnInjectionPinHigh>( taggedPointer.getRaw() );
185 endActionStage1 = action_s::make<turnInjectionPinLow>(
this );
186 endActionStage2 = action_s::make<turnInjectionPinLowStage2>(
this );
190 float angleFromNow = eventAngle - currentPhase;
191 if (angleFromNow < 0) {
196 efitick_t startTime =
scheduleByAngle(
nullptr, nowNt, angleFromNow, startAction);
199 efitick_t turnOffTimeStage1 = startTime + US2NT((
int)durationUsStage1);
203 if (hasStage2Injection && endActionStage2) {
204 efitick_t turnOffTimeStage2 = startTime + US2NT((
int)durationUsStage2);
208#if EFI_DETAILED_LOGGING
209 printf(
"scheduling injection angle=%.2f/delay=%d injectionDuration=%d %d\r\n", angleFromNow, (
int)NT2US(startTime - nowNt), (
int)durationUsStage1, (
int)durationUsStage2);
211#if EFI_DETAILED_LOGGING
212 efiPrintf(
"handleFuel pin=%s eventIndex %d duration=%.2fms %d",
outputs[0]->name,
214 injectionDurationStage1,
215 getRevolutionCounter());
216 efiPrintf(
"handleFuel pin=%s delay=%.2f %d",
outputs[0]->name, NT2US(startTime - nowNt),
217 getRevolutionCounter());
221static void handleFuel(efitick_t nowNt,
float currentPhase,
float nextPhase) {
230 bool limitedFuel = !limitedFuelState.
value;
242#if FUEL_MATH_EXTREME_LOGGING
244 efiPrintf(
"handleFuel [%.1f, %.1f) %d", currentPhase, nextPhase, getRevolutionCounter());
258 if (hasFirmwareError()) {
273 if (trgEventIndex == 0) {
287 m.onEnginePhase(rpm, edgeTimestamp, currentPhase, nextPhase);
294 handleFuel(edgeTimestamp, currentPhase, nextPhase);
297 rpm, edgeTimestamp, currentPhase, nextPhase);
Non-volatile backup-RAM registers support.
void periodicFastCallback()
RpmCalculator rpmCalculator
TunerStudioOutputChannels outputChannels
constexpr auto & module()
type_list< Mockable< InjectorModelPrimary >, Mockable< InjectorModelSecondary >,#if EFI_IDLE_CONTROL Mockable< IdleController >,#endif TriggerScheduler,#if EFI_HPFP &&EFI_ENGINE_CONTROL Mockable< HpfpController >,#endif #if EFI_ENGINE_CONTROL Mockable< ThrottleModel >,#endif #if EFI_ALTERNATOR_CONTROL AlternatorController,#endif MainRelayController, Mockable< IgnitionController >, Mockable< AcController >, PrimeController, DfcoController,#if EFI_HD_ACR HarleyAcr,#endif Mockable< WallFuelController >, KnockController, SensorChecker,#if EFI_ENGINE_CONTROL Mockable< LimpManager >,#endif #if EFI_VVT_PID VvtController1, VvtController2, VvtController3, VvtController4,#endif #if EFI_BOOST_CONTROL BoostController,#endif TpsAccelEnrichment,#if EFI_LAUNCH_CONTROL NitrousController,#endif #if EFI_LTFT_CONTROL LongTermFuelTrim,#endif ShortTermFuelTrim,#include "modules_list_generated.h" EngineModule > engineModules
virtual bool isCranking() const =0
float injectionStage2Fraction
void onTriggerTooth(efitick_t nowNt, float currentPhase, float nextPhase)
InjectorOutputPin * outputsStage2[MAX_WIRES_COUNT]
void onTriggerTooth(efitick_t nowNt, float currentPhase, float nextPhase)
InjectorOutputPin * outputs[MAX_WIRES_COUNT]
float injectionStartAngle
void close(efitick_t nowNt)
LimpState allowInjection() const
const char * getName() const
float getCachedRpm() const
static float getOrZero(SensorType type)
float adjust(float desiredMassGrams)
bool isPhaseInRange(float test, float current, float next)
LimpManager * getLimpManager()
Scheduler * getScheduler()
TriggerCentral * getTriggerCentral()
FuelSchedule * getFuelSchedule()
EngineRotationState * getEngineRotationState()
EngineState * getEngineState()
IgnitionEventList * getIgnitionEvents()
static EngineAccessor engine
static constexpr engine_configuration_s * engineConfiguration
floatms_t getCrankshaftRevolutionTimeMs(float rpm)
bool warning(ObdCode code, const char *fmt,...)
int getNumberOfInjections(injection_mode_e mode)
void endSimultaneousInjectionOnlyTogglePins()
void mainTriggerCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp, angle_t currentPhase, angle_t nextPhase)
static void handleFuel(efitick_t nowNt, float currentPhase, float nextPhase)
void turnInjectionPinLow(InjectionEvent *event)
void endSimultaneousInjection(InjectionEvent *event)
static void turnInjectionPinLowStage2(InjectionEvent *event)
@ CUSTOM_OBD_NEG_INJECTION
@ CUSTOM_OBD_NAN_INJECTION
efitick_t scheduleByAngle(scheduling_s *timer, efitick_t nowNt, angle_t angle, action_s const &action)
void onTriggerEventSparkLogic(float rpm, efitick_t edgeTimestamp, float currentPhase, float nextPhase)
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.
injection_mode_e crankingInjectionMode
injection_mode_e injectionMode
float injectionMass[MAX_CYLINDER_COUNT]
float actualLastInjectionRatio
scaled_channel< uint16_t, 300, 1 > actualLastInjectionStage2
float actualLastInjectionRatioStage2
scaled_channel< uint16_t, 300, 1 > actualLastInjection