fuelAndIgnitionCalcs.c File Reference

Fuel and ignition calculations. More...

#include "inc/freeEMS.h"
#include "inc/utils.h"
#include "inc/commsCore.h"
#include "inc/tableLookup.h"
#include "inc/DecoderInterface.h"
#include "inc/fuelAndIgnitionCalcs.h"
Include dependency graph for fuelAndIgnitionCalcs.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define FUELANDIGNITIONCALCS_C

Functions

void calculateFuelAndIgnition ()
 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.

Author:
Fred Cooke

Definition in file fuelAndIgnitionCalcs.c.


Define Documentation

#define FUELANDIGNITIONCALCS_C

Definition at line 39 of file fuelAndIgnitionCalcs.c.


Function Documentation

void calculateFuelAndIgnition ( void   ) 

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 fuel injection timing is also determined here.

Calculate the ignition timing and dwell here too. Several corrections are applied to these as well.

Todo:

TODO implement the all of the ignition stuff and finish off all of the fuel injection stuff.

TODO change the way configuration is done and make sure the most common options are after the first if().

TODO add actual configuration options to the fixed config blocks for these items.

Author:
Fred Cooke

Todo:
TODO figure out what the correct "temperature" is to make MAF work correctly!
Todo:
TODO make injector channels come from config, not defines.
Todo:
TODO make injector channels come from config, not defines.
Todo:
TODO work needs to be done on scheduling before this can be completed.
Todo:
TODO x 6 main pulsewidths, x 6 staged pulsewidths, x 6 flags for staged channels if(coreSettingsA & STAGED_ON){}
Todo:
TODO determine the requirement for staged based on some sort of map and or complex load based configuration.
Todo:
TODO Calculate the fuel advances (six of)
Todo:
TODO Calculate the dwell period (one of)
Todo:
TODO Calculate the ignition advances (twelve of)

Definition at line 64 of file fuelAndIgnitionCalcs.c.

References ADCArrays, DerivedVar::AirFlow, DerivedVar::BasePW, bootFuelConst, fixedConfig1::coreSettingsA, coreStatusA, CoreVars, currentDwellMath, DerivedVar::densityAndFuel, engineSetting::densityOfFuelAtSTP, densityOfFuelTotalDivisor, DerivedVars, DerivedVar::EffectivePW, fixedConfig1::engineSettings, DerivedVar::ETE, FALSE, fixedConfigs1, fixedConfigs2, CoreVar::IAT, DerivedVar::IDT, IGNITION_CHANNELS, ignitionAdvances, INJECTION_CHANNELS, injectorMainPulseWidthsMath, DerivedVar::Lambda, CoreVar::MAF, CoreVar::MAP, masterPulseWidth, ADCArray::MAT, oneHundredPercentVE, sensorPreset::presetAF, sensorPreset::presetBPW, DerivedVar::RefPW, roomTemperature, safeAdd(), safeScale(), safeTrim(), fixedConfig2::sensorPresets, STAGED_NOT_REQUIRED, STAGED_ON, STAGED_REQUIRED, stoichiometricLambda, DerivedVar::TFCTotal, totalAngleAfterReferenceInjection, ADCArray::TPS, TRUE, and DerivedVar::VEMain.

Referenced by main().

00064                                {
00065     /*&&&&&&&&&&&&& Perform the basic calculations one step at a time to get a final pulsewidth &&&&&&&&&&&&*/
00066 
00067     if(TRUE /* Genuine method */){
00068         unsigned short airInletTemp = CoreVars->IAT; /* All except MAF use this. */
00069         /* Determine the type of air flow data */
00070         if(TRUE /* SpeedDensity */){
00071             /* This won't overflow until 512kPa or about 60psi of boost with 128% VE. */
00072             DerivedVars->AirFlow = ((unsigned long)CoreVars->MAP * DerivedVars->VEMain) / oneHundredPercentVE;
00073             /* Result is 450 - 65535 always. */
00074         }else if(FALSE /*AlphaN*/){
00075             DerivedVars->AirFlow = DerivedVars->VEMain; /* Not actually VE, but rather tuned air flow without density information */
00076         }else if(FALSE /*MAF*/){
00077             DerivedVars->AirFlow = CoreVars->MAF; /* Just fix temperature at appropriate level to provide correct Lambda */
00079             airInletTemp = roomTemperature; // 293.15k is 20c * 100 to get value, so divide by 100 to get real number
00080         }else if(FALSE /*FixedAF*/){ /* Fixed air flow from config */
00081             DerivedVars->AirFlow = fixedConfigs2.sensorPresets.presetAF;
00082         }else{ /* Default to no fuel delivery and error */
00083             DerivedVars->AirFlow = 0;
00084             /* If anyone is listening, let them know something is wrong */
00085 //          sendError(AIRFLOW_NOT_CONFIGURED_CODE); // or maybe queue it?
00086         }
00087 
00088 
00089         /* This won't overflow until well past 125C inlet, 1.5 Lambda and fuel as dense as water */
00090         DerivedVars->densityAndFuel = (((unsigned long)((unsigned long)airInletTemp * DerivedVars->Lambda) / stoichiometricLambda) * fixedConfigs1.engineSettings.densityOfFuelAtSTP) / densityOfFuelTotalDivisor;
00091         /* Result is 7500 - 60000 always. */
00092 
00093         /* Divisors for air inlet temp and pressure :
00094          * #define airInletTempDivisor 100
00095          * #define airPressureDivisor 100
00096          * cancel each other out! all others are used. */
00097 
00098 
00099         DerivedVars->BasePW = (bootFuelConst * DerivedVars->AirFlow) / DerivedVars->densityAndFuel;
00100     }else if(FALSE /*configured*/){ /* Fixed PW from config */
00101         DerivedVars->BasePW = fixedConfigs2.sensorPresets.presetBPW;
00102     }else{ /* Default to no fuel delivery and error */
00103         DerivedVars->BasePW = 0;
00104         /* If anyone is listening, let them know something is wrong */
00105 //      sendError(BPW_NOT_CONFIGURED_CODE); // or maybe queue it?
00106     }
00107 
00108     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00109 
00110 
00111 
00112 
00113     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&& Apply All Corrections PCFC, ETE, IDT, TFC etc &&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00114 
00115     /* Apply the corrections after calculating */
00116     DerivedVars->EffectivePW = safeTrim(DerivedVars->BasePW, DerivedVars->TFCTotal);
00117     DerivedVars->EffectivePW = safeScale(DerivedVars->EffectivePW, DerivedVars->ETE);
00118 
00119 
00120     unsigned char channel; // the declaration of this variable is used in multiple loops below.
00121 
00122     /* "Calculate" the individual fuel pulse widths */
00123     for(channel = 0; channel < INJECTION_CHANNELS; channel++){ 
00124         /* Add or subtract the per cylinder fuel trims */
00125         unsigned short channelPW;
00126         channelPW = safeScale(DerivedVars->EffectivePW, TablesB.SmallTablesB.perCylinderFuelTrims[channel]);
00127 
00128         /* Add on the IDT to get the final value and put it into the array */
00129         injectorMainPulseWidthsMath[channel] = safeAdd(channelPW, DerivedVars->IDT);
00130     }
00131 
00132     /* Reference PW for comparisons etc */
00133     unsigned short refPW = safeAdd(DerivedVars->EffectivePW, DerivedVars->IDT);
00134     DerivedVars->RefPW = refPW;
00135     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00136 
00137 
00138 
00139 
00140     /*&&&&&&&&&&&&&&&&& Based on IDT schedule PW start such that Fuel is correctly timed &&&&&&&&&&&&&&&&&&&*/
00141 
00142     for(channel = 0;channel < INJECTION_CHANNELS;channel++){ 
00143         //injectorMainAdvances[channel] = IDT blah blah.
00144     }
00145 
00146     /* This will involve using RPM, injector firing angle and IDT to schedule the events correctly */
00147 
00150     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00151 
00152 
00153 
00154 
00155     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Calculate Dwell and Ignition angle &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00156     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00157 
00158 
00159 
00160 
00161     /*&&&&&&&&&&&&&&& Based on Dwell and Ignition angle schedule the start and end of dwell &&&&&&&&&&&&&&&&*/
00162     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00163 
00164 
00165 
00166 
00167     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& TEMPORARY (and old) &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00168 
00169     /* "Calculate" the nominal total pulse width before per channel corrections */
00170     masterPulseWidth = refPW;//(ADCArrays->EGO << 6) + (ADCArrays->MAP >> 4);
00171 
00172     /* "Calculate" the individual fuel pulse widths */
00173     for(channel = 0; channel < INJECTION_CHANNELS; channel++){
00174         injectorMainPulseWidthsMath[channel] = masterPulseWidth;
00175     }
00176 
00178 
00179     /* Set the staged status on or off (for now based on changeable settings) */
00180     if(fixedConfigs1.coreSettingsA & STAGED_ON){
00181         coreStatusA |= STAGED_REQUIRED;
00183     }else{
00184         coreStatusA &= STAGED_NOT_REQUIRED;
00185     }
00186 
00187     // temporary ign tests
00188     unsigned short intendedAdvance = ADCArrays->MAT << 6;
00189     unsigned short intendedDwell = intendedAdvance >> 1;
00190 
00191     short c;
00192     for(c=0;c<IGNITION_CHANNELS;c++){
00193         ignitionAdvances[IGNITION_CHANNELS] = intendedAdvance;
00194     }
00195     *currentDwellMath = intendedDwell;
00196 
00197 //  unsigned short minPeriod = ignitionMinimumDwell << 1;
00198     //  if(intendedDwell < ignitionMinimumDwell){
00199 //      dwellLength = ignitionMinimumDwell;
00200 //  }else{
00201 //      dwellLength = intendedDwell;
00202 //  }
00203 //  if(intendedPeriod < minPeriod){
00204 //      dwellPeriod = minPeriod;
00205 //  }else{
00206 //      dwellPeriod = intendedPeriod;
00207 //  }
00208 //  PITLD0 = dwellPeriod;
00209 
00211     // just use one for all for now...
00212     totalAngleAfterReferenceInjection = (ADCArrays->TPS << 6);
00213 
00218     /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& TEMPORARY END &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00219 }

Here is the call graph for this function:

Generated on Sat Oct 16 21:29:11 2010 for FreeEMS by  doxygen 1.6.3