FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
Macros | Functions
fuelAndIgnitionCalcs.c File Reference

Fuel and ignition calculations. More...

#include "inc/freeEMS.h"
#include "inc/utils.h"
#include "inc/locationIDs.h"
#include "inc/tableLookup.h"
#include "inc/fuelAndIgnitionCalcs.h"
Include dependency graph for fuelAndIgnitionCalcs.c:

Go to the source code of this file.

Macros

#define FUELANDIGNITIONCALCS_C

Functions

void calculateFuelAndIgnition ()
 Final fuel and ignition calculations.

Detailed Description

Fuel and ignition calculations.

This file contains all of the main fuel and ignition calculations based upon the variables that we have already determined in previous stages.

Definition in file fuelAndIgnitionCalcs.c.

Macro Definition Documentation

#define FUELANDIGNITIONCALCS_C

Definition at line 38 of file fuelAndIgnitionCalcs.c.

Function Documentation

void calculateFuelAndIgnition ( void  )

Final fuel and ignition calculations.

Using a variety of primary algorithms calculate a base pulsewidth and then apply various corrections to it such as injector dead time, transient fuel correction, engine temperature enrichment and per cylinder trims. The ignition timing and fuel injection timing are also determined here, as are the various limiters and cuts.

Todo:
TODO figure out what the correct "temperature" is to make MAF work correctly!
Todo:
accumulate errors such that we know what sort of PW WOULD have been requested and enable a "over duty cut" to protect boosted users with insufficient injector size on cold nights

TODO

Todo:
FIXME part of to schedule or not to schedule should be : (masterPulseWidth > injectorMinimumPulseWidth)

Definition at line 53 of file fuelAndIgnitionCalcs.c.

References DerivedVar::AirFlow, AirflowTableLocationID, ALGO_ALPHA_N, ALGO_MAF, ALGO_SD_AN_BLEND, fixedConfig2::algorithmSettings, algorithmSetting::algorithmType, KeyUserDebug::alphaNAirFlow, DerivedVar::BasePW, KeyUserDebug::blendAlphaNPercent, bootFuelConst, CoreVars, fixedConfig1::cutAndLimiterSettings, cutAndLimiterSetting::cutsEnabled, DEGREES_C, DerivedVar::densityAndFuel, engineSetting::densityOfFuelAtSTP, DerivedVars, singleCut::disableThreshold, DerivedVar::EffectivePW, fixedConfig1::engineSettings, DerivedVar::ETE, fixedConfigs1, fixedConfigs2, FUEL_DENSITY, FUEL_DENSITY_UNIT_FACTOR, CoreVar::IAT, DerivedVar::IDT, KeyUserDebug::ignitionCuts, cutEnabled::IgnitionRPM, cutAndLimiterSetting::IgnitionRPM, cutEnabled::IgnOverBoost, KeyUserDebug::injectionCuts, cutEnabled::InjectionRPM, cutAndLimiterSetting::InjectionRPM, cutEnabled::InjOverBoost, KeyUserDebugs, LAMBDA, DerivedVar::Lambda, lookupMainTable(), lookupTwoDTableUS(), CoreVar::MAF, CoreVar::MAP, masterPulseWidth, schedulingSetting::numberOfInjectionsPerEngineCycle, cutAndLimiterSetting::OverBoost, singleCut::reenableThreshold, DerivedVar::RefPW, CoreVar::RPM, safeAdd(), safeScale(), safeTrim(), fixedConfig1::schedulingSettings, SHORT4TH, SHORTMAX, KeyUserDebug::speedDensityAirFlow, DerivedVar::TFCTotal, CoreVar::TPS, VE, DerivedVar::VEMain, and VETableMainLocationID.

Referenced by main().

{
unsigned short airInletTemp = CoreVars->IAT; /* All except MAF use this. */
/* Determine the type of air flow data */
/* Look up VE with RPM and MAP */
/* This won't overflow until 512kPa or about 60psi of boost with 128% VE. */
DerivedVars->AirFlow = ((unsigned long)CoreVars->MAP * DerivedVars->VEMain) / VE(100);
/* Result is 450 - 65535 always. */
/* Look up Airflow with RPM and TPS */
DerivedVars->AirFlow = lookupMainTable(CoreVars->RPM, CoreVars->TPS, AirflowTableLocationID); /* Tuned air flow without density information */
DerivedVars->AirFlow = CoreVars->MAF; /* Just fix temperature at appropriate level to provide correct Lambda */
/// @todo TODO figure out what the correct "temperature" is to make MAF work correctly!
airInletTemp = DEGREES_C(20); // Room temperature?
/* Look up VE with RPM and MAP */
/* This won't overflow until 512kPa or about 60psi of boost with 128% VE. */
/* Look up Airflow with RPM and TPS */
KeyUserDebugs.alphaNAirFlow = lookupMainTable(CoreVars->RPM, CoreVars->TPS, AirflowTableLocationID); /* Tuned air flow without density information */
KeyUserDebugs.blendAlphaNPercent = lookupTwoDTableUS((twoDTableUS*)&TablesA.SmallTablesA.blendVersusRPMTable, CoreVars->RPM);
DerivedVars->AirFlow = safeAdd(airflowSD, airflowAN);
}else{ /* Default to no fuel delivery and error */
}
/* This won't overflow until well past 125C inlet, 1.5 Lambda and fuel as dense as water */
/* Result is 7500 - 60000 always. TODO clean up the last item on the above line */
/* Divisors for air inlet temp and pressure :
* #define airInletTempDivisor 100
* #define airPressureDivisor 100
* cancel each other out! all others are used. */
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&& Apply All Corrections PCFC, ETE, IDT, TFC etc &&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/* Apply the corrections after calculating */
// unsigned char channel; // the declaration of this variable is used in multiple loops below.
//
// /* "Calculate" the individual fuel pulse widths */
// for(channel = 0; channel < INJECTION_CHANNELS; channel++){ /// @todo TODO make injector channels come from config, not defines.
// /* Add or subtract the per cylinder fuel trims */
// unsigned short channelPW;
// channelPW = safeScale(DerivedVars->EffectivePW, TablesB.SmallTablesB.perCylinderFuelTrims[channel]);
//
// /* Add on the IDT to get the final value and put it into the array */
// //outputEventPulseWidthsMath[channel] = safeAdd(channelPW, DerivedVars->IDT); do not re-enable this without fixing it properly...
// }
// Make sure we don't have a PW if PW is supposed to be zero, ie, zero the IDT as well.
DerivedVars->IDT = 0; // This also makes fuel and electrical duty work consistently in external apps.
}
/* Reference PW for comparisons etc */
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/// @todo accumulate errors such that we know what sort of PW WOULD have been requested and enable a "over duty cut" to protect boosted users with insufficient injector size on cold nights
/// TODO @todo FIXME part of to schedule or not to schedule should be : (masterPulseWidth > injectorMinimumPulseWidth)
// IE, NOT in the decoders... KISS in the decoders. This is a hangover from (very) early decoder dev
// for(channel = 0;channel < INJECTION_CHANNELS;channel++){ /// @todo TODO make injector channels come from config, not defines.
//injectorMainAdvances[channel] = IDT blah blah.
// }
/* "Calculate" the nominal total pulse width before per channel corrections */
// but requires to know how big a cycle is, 1/4 1, 1/2, etc
// Note, conversions to address and then pointer are necessary to avoid error on direct cast
// Cuts and limiters TODO move these to their own special place?
// TODO Make source of threshold either struct or temp based curve for these
unsigned short confirmedReenableThreshold = fixedConfigs1.cutAndLimiterSettings.IgnitionRPM.reenableThreshold;
}
}else if(CoreVars->RPM < confirmedReenableThreshold){
}
}
unsigned short confirmedReenableThreshold = fixedConfigs1.cutAndLimiterSettings.InjectionRPM.reenableThreshold;
}
}else if(CoreVars->RPM < confirmedReenableThreshold){
}
}
// TODO add time based lock out as well as threshold based as threshold could re-enable too quickly
unsigned short confirmedReenableThreshold = fixedConfigs1.cutAndLimiterSettings.OverBoost.reenableThreshold;
}
}else if(CoreVars->MAP < confirmedReenableThreshold){
((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnOverBoost = 0;
}
}
}

Here is the call graph for this function:

Here is the caller graph for this function: