#include "inc/freeEMS.h"
#include "inc/commsCore.h"
#include "inc/tableLookup.h"
#include "inc/fuelAndIgnitionCalcs.h"
Include dependency graph for fuelAndIgnitionCalcs.c:
Go to the source code of this file.
Defines | |
#define | FUELANDIGNITIONCALCS_C |
#define | oneHundredPercentPCFT 32768 |
Functions | |
void | calculateFuelAndIgnition () |
#define FUELANDIGNITIONCALCS_C |
Definition at line 24 of file fuelAndIgnitionCalcs.c.
#define oneHundredPercentPCFT 32768 |
Referenced by calculateFuelAndIgnition().
void calculateFuelAndIgnition | ( | void | ) |
Definition at line 31 of file fuelAndIgnitionCalcs.c.
References ADCArrays, DerivedVar::AirFlow, DerivedVar::BasePW, bootFuelConst, fixedConfig::coreSettingsA, coreStatusA, CoreVars, currentDwell, DerivedVar::densityAndFuel, fixedConfig::densityOfFuelAtSTP, densityOfFuelTotalDivisor, DerivedVars, ADCArray::EGO, DerivedVar::ETE, FALSE, DerivedVar::FinalPW, fixedConfigs, CoreVar::IAT, DerivedVar::IDT, IGNITION_CHANNELS, ignitionAdvances, INJECTION_CHANNELS, injectorMainPulseWidths, DerivedVar::Lambda, CoreVar::MAF, CoreVar::MAP, ADCArray::MAP, masterPulseWidth, ADCArray::MAT, mathInputBank, mathInternalBank, mathInternalIgnitionOffset, mathInternalInjectionOffset, oneHundredPercentPCFT, oneHundredPercentVE, SmallTables2::perCylinderFuelTrims, fixedConfig::presetAF, fixedConfig::presetBPW, DerivedVar::RefPW, roomTemperature, SHORTMAX, SmallTablesBFlash, STAGED_NOT_REQUIRED, STAGED_ON, STAGED_REQUIRED, stoichiometricLambda, DerivedVar::TFCTotal, totalAngleAfterReferenceInjection, ADCArray::TPS, TRUE, and DerivedVar::VEMain.
Referenced by main().
00031 { 00032 /*&&&&&&&&&&&&& Perform the basic calculations one step at a time to get a final pulsewidth &&&&&&&&&&&&*/ 00033 00034 if(TRUE /* Genuine method */){ 00035 unsigned short airInletTemp = CoreVars.IAT[mathInternalBank]; /* All except MAF use this. */ 00036 /* Determine the type of air flow data */ 00037 if(TRUE /* SpeedDensity */){ 00038 /* This won't overflow until 512kPa or about 60psi of boost with 128% VE. */ 00039 DerivedVars.AirFlow[mathInternalBank] = ((unsigned long)CoreVars.MAP[mathInternalBank] * DerivedVars.VEMain[mathInternalBank]) / oneHundredPercentVE; 00040 /* Result is 450 - 65535 always. */ 00041 }else if(FALSE /*AlphaN*/){ 00042 DerivedVars.AirFlow[mathInternalBank] = DerivedVars.VEMain[mathInternalBank]; /* Not actually VE, but rather tuned air flow without density information */ 00043 }else if(FALSE /*MAF*/){ 00044 DerivedVars.AirFlow[mathInternalBank] = CoreVars.MAF[mathInternalBank]; /* Just fix temperature at appropriate level to provide correct Lambda */ 00045 // TODO figure out what the correct "temperature" is to make MAF work correctly! 00046 airInletTemp = roomTemperature; // 293.15k is 20c * 100 to get value, so divide by 100 to get real number 00047 }else if(FALSE /*FixedAF*/){ /* Fixed air flow from config */ 00048 DerivedVars.AirFlow[mathInternalBank] = fixedConfigs.presetAF; 00049 }else{ /* Default to no fuel delivery and error */ 00050 DerivedVars.AirFlow[mathInternalBank] = 0; 00051 /* If anyone is listening, let them know something is wrong */ 00052 // sendError(AIRFLOW_NOT_CONFIGURED_CODE); // or maybe queue it? 00053 } 00054 00055 00056 /* This won't overflow until well past 125C inlet, 1.5 Lambda and fuel as dense as water */ 00057 DerivedVars.densityAndFuel[mathInternalBank] = (((unsigned long)((unsigned long)airInletTemp * DerivedVars.Lambda[mathInternalBank]) / stoichiometricLambda) * fixedConfigs.densityOfFuelAtSTP) / densityOfFuelTotalDivisor; 00058 /* Result is 7500 - 60000 always. */ 00059 00060 /* Divisors for air inlet temp and pressure : 00061 * #define airInletTempDivisor 100 00062 * #define airPressureDivisor 100 00063 * cancel each other out! all others are used. */ 00064 00065 00066 DerivedVars.BasePW[mathInternalBank] = (bootFuelConst * DerivedVars.AirFlow[mathInternalBank]) / DerivedVars.densityAndFuel[mathInternalBank]; 00067 }else if(FALSE /*configured*/){ /* Fixed PW from config */ 00068 DerivedVars.BasePW[mathInternalBank] = fixedConfigs.presetBPW; 00069 }else{ /* Default to no fuel delivery and error */ 00070 DerivedVars.BasePW[mathInternalBank] = 0; 00071 /* If anyone is listening, let them know something is wrong */ 00072 // sendError(BPW_NOT_CONFIGURED_CODE); // or maybe queue it? 00073 } 00074 00075 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00076 00077 00078 00079 00080 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&& Apply All Corrections PCFC, ETE, IDT, TFC etc &&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00081 00082 /* Apply the corrections after calculating */ 00083 DerivedVars.FinalPW[mathInternalBank] = DerivedVars.BasePW[mathInternalBank]; 00084 DerivedVars.FinalPW[mathInternalBank] += DerivedVars.TFCTotal[mathInternalBank]; /* TODO check for overflow when TFC is positive and underflow when negative */ 00085 DerivedVars.FinalPW[mathInternalBank] += DerivedVars.ETE[mathInternalBank]; /* TODO check for overflow always */ 00086 00087 00088 /* "Calculate" the individual fuel pulse widths */ 00089 unsigned char channel; 00090 /* TODO move this to a header with all other #defines found in code */ 00091 #define oneHundredPercentPCFT 32768 00092 for(channel = 0; channel < INJECTION_CHANNELS; channel++){ // TODO make injector channels come from config, not defines. 00093 /* Add or subtract the per cylinder fuel trims */ 00094 unsigned short trimmedPW; 00095 trimmedPW = ((unsigned long)DerivedVars.FinalPW[mathInternalBank] * SmallTablesBFlash.perCylinderFuelTrims[channel]) / oneHundredPercentPCFT; 00096 00097 /* Check for overflow */ 00098 unsigned short absoluteLastPW; 00099 /* If the trim is greater than 100% then the trimmedPW MUST be larger */ 00100 /* If it's less than 100% it can't have overflowed */ /* If it's not larger, it overflowed */ 00101 if((SmallTablesBFlash.perCylinderFuelTrims[channel] > oneHundredPercentPCFT) && (DerivedVars.FinalPW[mathInternalBank] > trimmedPW)){ 00102 absoluteLastPW = SHORTMAX; /* So max it out! */ 00103 }else{ 00104 /* Add on the IDT and check again */ 00105 unsigned short withIDTPW = trimmedPW + DerivedVars.IDT[mathInternalBank]; 00106 if(trimmedPW > withIDTPW){ /* If it's not larger, it overflowed */ 00107 absoluteLastPW = SHORTMAX; /* So max it out! */ 00108 }else{ 00109 absoluteLastPW = withIDTPW; 00110 } 00111 } 00112 00113 /* Load the final value with trim and opening time checked for overflow into the array */ 00114 injectorMainPulseWidths[channel + mathInternalInjectionOffset] = absoluteLastPW; 00115 } 00116 00117 /* Reference PW for comparisons etc */ 00118 unsigned short refPW = DerivedVars.FinalPW[mathInternalBank] + DerivedVars.IDT[mathInternalBank]; 00119 if(DerivedVars.FinalPW[mathInternalBank] > refPW){ /* If it's not larger, it overflowed */ 00120 refPW = SHORTMAX; /* So max it out! */ 00121 } 00122 DerivedVars.RefPW[mathInternalBank] = refPW; 00123 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00124 00125 00126 00127 00128 /*&&&&&&&&&&&&&&&&& Based on IDT schedule PW start such that Fuel is correctly timed &&&&&&&&&&&&&&&&&&&*/ 00129 00130 // unsigned char channel; 00131 for(channel = 0;channel < INJECTION_CHANNELS;channel++){ // TODO make injector channels come from config, not defines. 00132 //injectorMainAdvances[channel] = IDT blah blah. 00133 } 00134 00135 /* This will involve using RPM, injector firing angle and IDT to schedule the events correctly */ 00136 00137 /* TODO work needs to be done on scheduling before this can be completed. */ 00138 00139 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00140 00141 00142 00143 00144 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Calculate Dwell and Ignition angle &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00145 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00146 00147 00148 00149 00150 /*&&&&&&&&&&&&&&& Based on Dwell and Ignition angle schedule the start and end of dwell &&&&&&&&&&&&&&&&*/ 00151 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00152 00153 00154 00155 00156 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& TEMPORARY (and old) &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00157 00158 /* "Calculate" the nominal total pulse width before per channel corrections */ 00159 masterPulseWidth = (ADCArrays.EGO[mathInputBank] << 6) + (ADCArrays.MAP[mathInputBank] >> 4); 00160 00161 /* "Calculate" the individual fuel pulse widths */ 00162 // unsigned char channel; 00163 for(channel = 0; channel < INJECTION_CHANNELS; channel++){ 00164 injectorMainPulseWidths[channel + mathInternalInjectionOffset] = masterPulseWidth; 00165 } 00166 00167 // TODO x 6 main, x 6 staged, x 6 flags for staged if(coreSettingsA & STAGED_ON){} 00168 00169 /* Set the staged status on or off (for now based on changeable settings) */ 00170 if(fixedConfigs.coreSettingsA & STAGED_ON){ 00171 coreStatusA |= STAGED_REQUIRED; 00172 }else{ 00173 coreStatusA &= STAGED_NOT_REQUIRED; 00174 } 00175 00176 // temporary ign tests 00177 unsigned short intendedAdvance = ADCArrays.MAT[mathInputBank] << 6; 00178 unsigned short intendedDwell = intendedAdvance >> 1; 00179 00180 short c; 00181 for(c=0;c<IGNITION_CHANNELS;c++){ 00182 ignitionAdvances[IGNITION_CHANNELS + mathInternalIgnitionOffset] = intendedAdvance; 00183 } 00184 currentDwell[mathInternalBank] = intendedDwell; 00185 00186 // unsigned short minPeriod = ignitionMinimumDwell << 1; 00187 // if(intendedDwell < ignitionMinimumDwell){ 00188 // dwellLength = ignitionMinimumDwell; 00189 // }else{ 00190 // dwellLength = intendedDwell; 00191 // } 00192 // if(intendedPeriod < minPeriod){ 00193 // dwellPeriod = minPeriod; 00194 // }else{ 00195 // dwellPeriod = intendedPeriod; 00196 // } 00197 // PITLD0 = dwellPeriod; 00198 00199 /* Calculate the fuel advances */ 00200 // TODO x 6 00201 // just use one for all for now 00202 totalAngleAfterReferenceInjection = (ADCArrays.TPS[mathInputBank] << 6); 00203 00204 /* Calculate the dwell period */ 00205 // TODO x 1 00206 00207 /* Calculate the ignition advances */ 00208 //TODO x 12 00209 00210 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& TEMPORARY END &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00211 }