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