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"
Go to the source code of this file.
Defines | |
#define | FUELANDIGNITIONCALCS_C |
Functions | |
void | calculateFuelAndIgnition () |
Fuel and ignition calculations. |
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.
#define FUELANDIGNITIONCALCS_C |
Definition at line 39 of file fuelAndIgnitionCalcs.c.
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 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.
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 }