1 /* FreeEMS - the open source engine management system
3 * Copyright 2008-2012 Fred Cooke
5 * This file is part of the FreeEMS project.
7 * FreeEMS software is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * FreeEMS software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
20 * We ask that if you make any changes to this file you email them upstream to
21 * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
23 * Thank you for choosing FreeEMS to run your engine!
29 * @ingroup measurementsAndCalculations
31 * @brief Generate the derived variables.
33 * Second level variables are derived from the core variables and generated here.
37 #define DERIVEDVARSGENERATOR_C
38 #include "inc/freeEMS.h"
39 #include "inc/commsCore.h"
40 #include "inc/tableLookup.h"
41 #include "inc/derivedVarsGenerator.h"
42 #include "inc/locationIDs.h"
43 #include "inc/decoderInterface.h"
47 * Use core variables to lookup and calculate the derived variables. This
48 * function uses the core variables to lookup and calculate further second
49 * order variables such as load, VE, Lamdda, Transient fuel correction, engine
50 * temperature enrichment, Injector dead time, etc.
52 void generateDerivedVars(){
53 /* Determine load based on options */
54 if(!(fixedConfigs2
.algorithmSettings
.loadType
)){ /* Use MAP as load */
55 DerivedVars
->LoadMain
= CoreVars
->MAP
;
56 }else if(fixedConfigs2
.algorithmSettings
.loadType
== LOAD_TPS
){ /* Use TPS as load */
57 DerivedVars
->LoadMain
= CoreVars
->TPS
;
58 }else if(fixedConfigs2
.algorithmSettings
.loadType
== LOAD_AAP
){ /* Use AAP corrected MAP as load */
59 DerivedVars
->LoadMain
= ((unsigned long)CoreVars
->MAP
* CoreVars
->AAP
) / KPA(100);
60 // TODO add maf calc load option here
61 }else{ /* Default to MAP, but throw error */
62 DerivedVars
->LoadMain
= CoreVars
->MAP
;
63 /* If anyone is listening, let them know something is wrong */
64 sendErrorIfClear(LOAD_NOT_CONFIGURED_CODE
); // or maybe queue it?
68 /* Look up VE with RPM and Load */
69 DerivedVars
->VEMain
= lookupMainTable(CoreVars
->RPM
, DerivedVars
->LoadMain
, VETableMainLocationID
);
72 /* Look up target Lambda with RPM and Load */
73 DerivedVars
->Lambda
= lookupMainTable(CoreVars
->RPM
, DerivedVars
->LoadMain
, LambdaTableLocationID
);
76 /* Look up injector dead time with battery voltage */
77 DerivedVars
->IDT
= lookupTwoDTableUS((twoDTableUS
*)&TablesA
.SmallTablesA
.injectorDeadTimeTable
, CoreVars
->BRV
);
79 if(!(fixedConfigs2
.algorithmSettings
.dwellType
)){
80 DerivedVars
->Dwell
= lookupTwoDTableUS((twoDTableUS
*)&TablesA
.SmallTablesA
.dwellDesiredVersusVoltageTable
, CoreVars
->BRV
);
81 }else if(fixedConfigs2
.algorithmSettings
.dwellType
== DWELL_RPM
){
82 DerivedVars
->Dwell
= lookupTwoDTableUS((twoDTableUS
*)&TablesA
.SmallTablesA
.dwellVersusRPMTable
, CoreVars
->RPM
);
83 }else if(fixedConfigs2
.algorithmSettings
.dwellType
== DWELL_FIXED
){
84 DerivedVars
->Dwell
= fixedConfigs2
.algorithmSettings
.dwellFixedPeriod
;
86 DerivedVars
->Dwell
= 0;
89 unsigned long tempAdvance
= ANGLE_FACTOR
* (unsigned long)lookupMainTable(CoreVars
->RPM
, DerivedVars
->LoadMain
, IgnitionAdvanceTableMainLocationID
);
90 DerivedVars
->Advance
= (unsigned short)(tempAdvance
/ 1024); // This calculation will change when the timing tables get shrunk to a more reasonable 8 bit size with appropriate scaling
91 // Move this magic number to an appropriate place and/or refactor timing calcs/values/etc
93 /// @todo TODO make generic!!!!
94 // to go generic we need:
95 // angle between ignition events (if have tpd) (or total angle and number of events)
98 // a setting to choose which behaviour (don't limit/% dwell limit/min spark time/other?)
99 #if CONFIG == HOTEL_ID
100 /// @bug hack for hyundai! 135 = 3/4 of 180 = one cycle...
101 unsigned long threeQuartersOfAvailableTime
= ((unsigned long)CoreVars
->DRPM
* 135 * ANGLE_FACTOR
) / ticks_per_degree_multiplier
;
102 if(DerivedVars
->Dwell
> threeQuartersOfAvailableTime
){
103 DerivedVars
->Dwell
= threeQuartersOfAvailableTime
;
107 /* Look up the engine temperature enrichment percentage with temperature */
108 DerivedVars
->ETE
= lookupTwoDTableUS((twoDTableUS
*)&TablesA
.SmallTablesA
.engineTempEnrichmentTablePercent
, CoreVars
->CHT
);
109 /* TODO The above needs some careful thought put into it around different loads and correction effects. */
112 /* Calculate the Transient Fuel Correction */
113 if(TRUE
/*WWTFC*/){ /* Do ONLY WW correction if enabled */
114 // Do ww stuff, maybe pre done via RTC/RTI for consistent period?
115 DerivedVars
->TFCTotal
= 0; /* TODO replace with real code */
116 }else if(FALSE
/*STDTFC*/){ /* Do any combination of standard approximate methods */
117 /* Initialse the variable as a base */
118 DerivedVars
->TFCTotal
= 0;
119 /* Based on the rate of change of MAP and some history/taper time */
120 if(FALSE
/*MAPTFC*/){
122 DerivedVars
->TFCTotal
+= 0;
125 /* Based on the rate of change of TPS and some history/taper time */
126 if(FALSE
/*TPSTFC*/){
128 DerivedVars
->TFCTotal
+= 0;
131 /* Based on the rate of change of RPM and some history/taper time */
132 if(FALSE
/*RPMTFC*/){
134 DerivedVars
->TFCTotal
+= 0;
136 }else{ /* Default to no correction */
137 DerivedVars
->TFCTotal
= 0;
138 /* Don't throw error as correction may not be required */