3 Copyright 2008 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 send them upstream to us at admin@diyefi.org
22 Thank you for choosing FreeEMS to run your engine! */
24 /* Header file multiple inclusion protection courtesy eclipse Header Template */
25 /* and http://gcc.gnu.org/onlinedocs/gcc-3.1.1/cpp/ C pre processor manual */
26 #ifndef FILE_FREEEMS_H_SEEN
27 #define FILE_FREEEMS_H_SEEN
30 /* Include top level files that everything else relies on */
32 #include "9S12XDP512.h"
33 #include "flashGlobals.h" // TODO For Sean to integrate back in
34 //#include "registerMasks.h TODO we should define those masks that we use in one place, but probably not in the main device header.
36 /* Include define files at the top here as other includes use them */
37 #include "errorDefines.h"
38 #include "globalDefines.h"
41 /* Include data types at the top as other includes use them */
42 #include "structs.h" // TODO split this out into more chunks as it's too big.
46 /* These specific subsets became too large to stay in this file. */
47 #include "globalConstants.h"
50 /* Where extern is used instead of EXTERN it indicates that */
51 /* the variable is initialised in staticInit.c, if someone */
52 /* attempts to use extern and doesn't initialise the variable */
53 /* statically then the linker should error on undefined symbol */
54 #ifdef MAIN_OR_GLOBALS
63 * BEWARE : Be explicit!!
65 * char 8 bit (defaults to unsigned, but always specify signed/unsigned anyway)
66 * short 16 bit (defaults to signed, but always specify signed/unsigned anyway)
67 * int 16 bit DO NOT USE! (current compile flags make this 16 bits, but a change of flags could will change your program if you use this because they will all be 32 bit all of a sudden)
68 * long 32 bit (defaults to signed, but always specify signed/unsigned anyway)
69 * long long 64 bit (inefficient, avoid these, if using : defaults to signed, but always specify signed/unsigned anyway)
70 * float 32 bit IEEE floating point numbers (inefficient, avoid these, used fixed point math)
71 * double 64 bit IEEE floating point numbers (inefficient, avoid these, used fixed point math)
75 /* GLOBAL Variables */
76 // TODO change any of these that need it to volatile!!!
79 // temporary test vars
80 EXTERN
unsigned short RPM0
; // to be replaced with logging scheme for teeth.
81 EXTERN
unsigned short RPM1
; // to be replaced with logging scheme for teeth.
82 extern unsigned short tachoPeriod
;
83 EXTERN
unsigned char portHDebounce
;
85 // these should not be here... TODO move to a comms header
86 extern unsigned char asyncDatalogType
;
87 #define asyncDatalogOff 0x00
88 #define asyncDatalogBasic 0x01
89 #define asyncDatalogConfig 0x02
90 #define asyncDatalogLogic 0x03
91 #define asyncDatalogADC 0x04
92 #define asyncDatalogCircBuf 0x05
93 #define asyncDatalogCircCAS 0x06
94 #define asyncDatalogTrigger 0x07 // what is this
95 EXTERN
unsigned short configuredBasicDatalogLength
;
98 // temporary test vars
99 EXTERN
void* memdumpaddr
;
100 EXTERN
unsigned char ShouldSendLog
;
102 /* Declare instances of variable structs for use */
103 EXTERN Clock Clocks
; /* Timer Clocks for various functions */
104 EXTERN Counter Counters
; /* Execution count for various blocks of code */
105 EXTERN RuntimeVar RuntimeVars
; /* Execution times for various blocks of code */
106 EXTERN ISRLatencyVar ISRLatencyVars
; /* Delay in execution start for various blocks of code */
109 /* The banked running variable system and structure
111 * The program running variables are divided into three broad groups: inputs, working
112 * and outputs. For both the input and output groups there are two copies of each set
113 * of variables, whereas there is only one copy of each set in the working group. This
114 * is required to allow both the inputs and outputs to be safely written and read at
115 * the same time. To facilitate this all sets of variables within the input and output
116 * groups are referenced with two pointers each. For the input group, the copy pointed
117 * to is swapped when fresh data is both available to and required by the mathematics
118 * function. For the output group the copy pointed to is swapped when the mathematics
119 * function has produced new output data. The input data is supplied by the engine
120 * position interrupt service routines as ADC readings and RPM values. The output data
121 * consists of pulse widths, timing angles, dwell periods and scheduling information.
123 * Accessory functions (Idle, Boost, etc)
125 * In order to achieve minimal latency and maximum frequency of execution of the
126 * main mathematics code the accessory functions must run asynchronously. Although
127 * we can guarantee that these functions will base their calculations on a matched
128 * set of data, we can not guarantee that it will be the same set of data presented
129 * along side the accessory data in the data log. Thus, where it is required to see
130 * the inputs that an accessory functions calculations were based on, those values
131 * should be cached for logging on a per function basis.
133 * Although it seems like a lot of trouble to go to, it is critical to transient
134 * performance that the environmental conditions the engine is operating under are
135 * tracked and reacted to as quickly as possible. Having the less important stuff
136 * run asynchronously will result in an order of magnitude improvement of parameter
137 * tracking and is well worth the extra memory expense and complication.
140 EXTERN CoreVar
* CoreVars
; /* Pointer to the core running variables */
141 EXTERN CoreVar CoreVars0
; /* Bank 0 core running variables */
142 /* If we move to xgate or isr driven logging, add bank 1 back in */
144 EXTERN DerivedVar
* DerivedVars
; /* Pointer to the secondary running variables */
145 EXTERN DerivedVar DerivedVars0
; /* Bank 0 secondary running variables */
146 /* If we move to xgate or isr driven logging, add bank 1 back in */
148 EXTERN ADCArray
* ADCArrays
; /* main adc storage area for syncronous sampling in the engine position ISR or injection ISR or ignition ISR etc. */
149 EXTERN ADCArray
* ADCArraysRecord
; /* main adc storage area for syncronous sampling in the engine position ISR or injection ISR or ignition ISR etc. */
150 EXTERN ADCArray ADCArrays0
; /* main adc storage area for syncronous sampling in the engine position ISR or injection ISR or ignition ISR etc. */
151 EXTERN ADCArray ADCArrays1
; /* main adc storage area for syncronous sampling in the engine position ISR or injection ISR or ignition ISR etc. */
153 EXTERN ADCArray
* asyncADCArrays
; /* secondary adc storage area for asynchronously sampling in the RTC/RTI ISR */
154 EXTERN ADCArray
* asyncADCArraysRecord
; /* secondary adc storage area for asynchronously sampling in the RTC/RTI ISR */
155 EXTERN ADCArray asyncADCArrays0
; /* secondary adc storage area for asynchronously sampling in the RTC/RTI ISR */
156 EXTERN ADCArray asyncADCArrays1
; /* secondary adc storage area for asynchronously sampling in the RTC/RTI ISR */
158 EXTERN
unsigned short* mathSampleTimeStamp
; // TODO temp, remove
159 EXTERN
unsigned short* mathSampleTimeStampRecord
; // TODO temp, remove
160 EXTERN
unsigned short* RPM
; // TODO temp, remove
161 EXTERN
unsigned short* RPMRecord
; // TODO temp, remove
162 EXTERN
unsigned short* currentDwellMath
; // TODO temp, remove
163 EXTERN
unsigned short* currentDwellRealtime
; // TODO temp, remove
164 EXTERN
unsigned short currentDwell0
; // TODO temp, remove
165 EXTERN
unsigned short currentDwell1
; // TODO temp, remove
167 /*break this on purpose so i fix it later
168 #define VETablereference (*((volatile mainTable*)(0x1000)))
169 EXTERN const mainTable *VETableRef;
171 const volatile mainTable *VETableRef = (volatile mainTable*)0x1000;
172 broken too, need to research how to do this.
174 see line 80 or so from inc/injectorISR.c for array of pointer use. the above may not be possible... TODO */
177 /* Potentially pointers for data in ram depending on how it gets implemented */
179 //EXTERN tunableConfig tunableConfigs;
181 /* Layout the tunable copies and buffers in ram space */
185 /* Unions for paged large table access using RPAGE */
187 mainTable VETableMain
;
188 mainTable IgnitionAdvanceTableMain
;
189 SmallTables1 SmallTablesA
;
193 mainTable VETableSecondary
;
194 mainTable IgnitionAdvanceTableSecondary
;
195 SmallTables2 SmallTablesB
;
199 mainTable VETableMainTertiary
;
200 mainTable InjectionAdvanceTableMain
;
201 SmallTables3 SmallTablesC
;
205 mainTable LambdaTable
;
206 mainTable InjectionAdvanceTableSecondary
;
207 SmallTables4 SmallTablesD
;
212 EXTERN
unsigned char TXBuffer
[TX_BUFFER_SIZE
] TXBUF
;
213 EXTERN
unsigned char RXBuffer
[RX_BUFFER_SIZE
] RXBUF
;
214 EXTERN Tables1 TablesA RWINDOW
;
215 EXTERN Tables2 TablesB RWINDOW
;
216 EXTERN Tables3 TablesC RWINDOW
;
217 EXTERN Tables4 TablesD RWINDOW
;
220 /* RAM page variables */
221 EXTERN
unsigned char currentFuelRPage
;
222 EXTERN
unsigned char currentTuneRPage
;
223 EXTERN
unsigned char currentTimeRPage
;
226 //union { /* Declare Union http://www.esacademy.com/faq/docs/cpointers/structures.htm */
227 // unsigned long timeLong;
228 // unsigned short timeShorts[2];
229 //} LongNoTime RWINDOW ;
231 /* These are inited once and remain the same, rpage switches change meaning. */
233 ///* Pointers to main tables to aid readability */
234 //EXTERN mainTable* VETableMain;
235 //EXTERN mainTable* VETableSecondary;
236 //EXTERN mainTable* VETableTertiary;
237 //EXTERN mainTable* LambdaTable;
239 //EXTERN mainTable* IgnitionAdvanceTableMain;
240 //EXTERN mainTable* IgnitionAdvanceTableSecondary;
241 //EXTERN mainTable* InjectionAdvanceTableMain;
242 //EXTERN mainTable* InjectionAdvanceTableSecondary;
244 ///* Pointers to SmallTablesA */
245 //EXTERN twoDTableUS* dwellDesiredVersusVoltageTable;
246 //EXTERN twoDTableUS* injectorDeadTimeTable;
247 //EXTERN twoDTableUS* postStartEnrichmentTable;
248 //EXTERN twoDTableUS* engineTempEnrichmentTableFixed;
249 //EXTERN twoDTableUS* primingVolumeTable;
250 //EXTERN twoDTableUS* engineTempEnrichmentTablePercent;
251 //EXTERN twoDTableUS* dwellMaxVersusRPMTable;
253 ///* Pointers to SmallTablesB */
254 //EXTERN unsigned short* perCylinderFuelTrims;
257 /* Pointers to SmallTablesC */
260 /* Pointers to SmallTablesD */
265 /* Output variables (init not required) TODO ditch this in favour of the real vars in the calcs function and struct */
266 extern unsigned short masterPulseWidth
;
267 EXTERN
unsigned short totalDwell
;
268 extern unsigned short totalAngleAfterReferenceInjection
;
269 extern unsigned short totalAngleAfterReferenceIgnition
;
271 EXTERN
unsigned long bootFuelConst
; /* constant derived from configurable constants */
272 EXTERN
unsigned short TPSMAPRange
; /* The MAP range used to convert fake TPS from MAP and vice versa */
273 EXTERN
unsigned short TPSADCRange
; /* The ADC range used to generate TPS percentage */
274 EXTERN
unsigned short boundedTPSADC
; // temp to view to debug
276 EXTERN
unsigned short bootTimeAAP
; /* TODO populate this at switch on time depending on a few things. */
278 /* ALL STATUS STUFF HERE */
280 /* State variables : 0 = false (don't forget to change the init mask to suit!) */
281 EXTERN
unsigned short coreStatusA
; /* Each bit represents the state of some core parameter, masks below */
282 /* Bit masks for coreStatusA */ // TODO needs a rename as does coresetingsA
283 #define COREA01 BIT1_16 /* 1 this was RPM_VALID Whether we are sure rpm is what the variable says (used to inject fuel without ignition below the threshold rpm) */
284 #define PRIMARY_SYNC BIT2_16 /* 2 Wasted spark/Semi sequential */
285 #define SECONDARY_SYNC BIT3_16 /* 3 COP/Full sequential */
286 #define ENGINE_PHASE BIT4_16 /* 4 For COP/Sequential, which revolution we are in, first or second */
287 #define FUEL_CUT BIT5_16 /* 5 Remove injection completely */
288 #define HARD_SPARK_CUT BIT6_16 /* 6 Remove ignition completely */
289 #define SOFT_SPARK_CUT BIT7_16 /* 7 Remove ignition events round robin style */
290 #define SPARK_RETARD BIT8_16 /* 8 Retard ignition in RPM dependent way */
291 #define STAGED_REQUIRED BIT9_16 /* 9 Fire the staged injectors */
292 #define CALC_FUEL_IGN BIT10_16 /* 10 Fuel and ignition require calculation (i.e. variables have been updated) */
293 #define FORCE_READING BIT11_16 /* 11 Flag to force ADC sampling at low rpm/stall */
294 #define COREA12 BIT12_16 /* 12 */
295 #define COREA13 BIT13_16 /* 13 */
296 #define COREA14 BIT14_16 /* 14 */
297 #define COREA15 BIT15_16 /* 15 */
298 #define COREA16 BIT16_16 /* 16 */
300 #define CLEAR_PRIMARY_SYNC NBIT2_16 /**/
301 #define STAGED_NOT_REQUIRED NBIT9_16 /* 9 Do not fire the staged injectors */
302 #define CLEAR_CALC_FUEL_IGN NBIT10_16 /* 10 Fuel and ignition don't require calculation */
303 #define CLEAR_FORCE_READING NBIT11_16 /* 11 Clear flag to force ADC sampling at low rpm/stall */
306 //TODO make this volatile?
307 /* ECT IC extension variable (init not required, don't care where it is, only differences between figures) */
308 unsigned short timerExtensionClock
; /* Increment for each overflow of the main timer, allows finer resolution and longer time period */
309 /* section 10.3.5 page 290 68hc11 reference manual e.g. groups.csail.mit.edu/drl/courses/cs54-2001s/pdf/M68HC11RM.pdf */
312 /* For extracting 32 bit long time stamps from the overflow counter and timer registers */
313 typedef union { /* Declare Union http://www.esacademy.com/faq/docs/cpointers/structures.htm */
314 unsigned long timeLong
;
315 unsigned short timeShorts
[2];
319 /* Flag registers, init to zero required */
320 EXTERN
unsigned char mainOn
; /* Keep track of where we are at for possible use as multi interrupt per injection */
321 EXTERN
unsigned short dwellOn
; /* Keep track of ignition output state */
322 EXTERN
unsigned char stagedOn
; /* Ensure we turn an injector off again if we turn it on. */
323 EXTERN
unsigned char selfSetTimer
; /* Set the start time of injection at the end of the last one in the channels ISR instead of the input ISR */
324 EXTERN
unsigned char rescheduleFuelFlags
; /* Pulse width is probably longer than engine cycle so schedule a restart at the next start time */
327 /* Engine Position and RPM reading variables */
329 /* Engine runtime properties (inits???) TODO */
330 EXTERN
unsigned short primaryPulsesPerSecondaryPulse
; /* Type short because of nissan style cam wheels (char would do for other types) */
331 EXTERN
unsigned short primaryPulsesPerSecondaryPulseBuffer
; /* Type short because of nissan style cam wheels (char would do for other types) */
332 EXTERN
unsigned short primaryLeadingEdgeTimeStamp
; /* Store the timestamp of the leading edge during a pulse */
333 EXTERN
unsigned short primaryTrailingEdgeTimeStamp
; /* Store the timestamp of the leading edge during a pulse */
334 EXTERN
unsigned short timeBetweenSuccessivePrimaryPulses
; /* This number equates to the speed of the engine */
335 EXTERN
unsigned short timeBetweenSuccessivePrimaryPulsesBuffer
; /* This number equates to the speed of the engine */
336 EXTERN
unsigned short lastPrimaryPulseTimeStamp
; /* Store the timer value of the each pulse here before exiting the ISR */
337 extern unsigned long engineCyclePeriod
; /* Timer units between engine cycle starts */
338 EXTERN
unsigned long lastSecondaryOddTimeStamp
;
339 EXTERN
unsigned short primaryTeethDroppedFromLackOfSync
;
343 // ignition experimentation stuff
344 EXTERN
unsigned char dwellQueueLength
; /* 0 = no dwell pending start, 1 = single event scheduled, 2 = one scheduled, and one in the queue, etc */
345 EXTERN
unsigned char ignitionQueueLength
; /* 0 = no spark event pending, 1 = single event scheduled, 2 = one scheduled, and one in the queue, etc */
346 EXTERN
unsigned char nextDwellChannel
; /* Which one to bang off next */
347 EXTERN
unsigned char nextIgnitionChannel
; /* Which one to bang off next */
348 EXTERN
unsigned short ignitionAdvances
[IGNITION_CHANNELS
* 2]; // Uses channel + offset to have two values at any time
349 EXTERN
unsigned short queuedDwellOffsets
[IGNITION_CHANNELS
]; // Uses next channel as index
350 EXTERN
unsigned short queuedIgnitionOffsets
[IGNITION_CHANNELS
]; // Uses next channel as index
353 /* Injection stuff */
355 /* Register addresses */
356 EXTERN
volatile unsigned short * volatile injectorMainTimeRegisters
[INJECTION_CHANNELS
];
357 EXTERN
volatile unsigned char * volatile injectorMainControlRegisters
[INJECTION_CHANNELS
];
359 /* Timer holding vars (init not required) */
360 EXTERN
unsigned short injectorMainStartTimesHolding
[INJECTION_CHANNELS
];
361 EXTERN
unsigned long injectorMainEndTimes
[INJECTION_CHANNELS
];
363 // TODO make these names consistent
364 /* Code time to run variables (init not required) */
365 EXTERN
unsigned short injectorCodeOpenRuntimes
[INJECTION_CHANNELS
];
366 EXTERN
unsigned short injectorCodeCloseRuntimes
[INJECTION_CHANNELS
];
368 /* individual channel pulsewidths (init not required) */
369 EXTERN
unsigned short* injectorMainPulseWidthsMath
;
370 EXTERN
unsigned short* injectorStagedPulseWidthsMath
;
371 EXTERN
unsigned short* injectorMainPulseWidthsRealtime
;
372 EXTERN
unsigned short* injectorStagedPulseWidthsRealtime
;
373 EXTERN
unsigned short injectorMainPulseWidths0
[INJECTION_CHANNELS
];
374 EXTERN
unsigned short injectorMainPulseWidths1
[INJECTION_CHANNELS
];
375 EXTERN
unsigned short injectorStagedPulseWidths0
[INJECTION_CHANNELS
];
376 EXTERN
unsigned short injectorStagedPulseWidths1
[INJECTION_CHANNELS
];
378 /* Channel latencies (init not required) */
379 EXTERN
unsigned short injectorCodeLatencies
[INJECTION_CHANNELS
];
384 /* let us know if we are being untidy with headers */
385 #warning "Header file FREEEMS_H seen before, sort it out!"
386 /* end of the wrapper ifdef from the very top */