1 /* FreeEMS - the open source engine management system
3 * Copyright 2008-2011 Fred Cooke, Sean Keys
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 interruptHandlers
31 * @brief Real time interrupts
33 * This file contains real time interrupt handlers. Mainly it holds the RTI
34 * handler itself, however the modulus down counter and ETC timer overflow
35 * functions are here too.
39 #define REALTIMEISRS_C
40 #include "inc/freeEMS.h"
41 #include "inc/interrupts.h"
42 #include "inc/commsISRs.h"
43 #include "inc/decoderInterface.h"
44 #include "inc/xgateVectors.h"
47 /** @brief Real Time Interrupt Handler
49 * Handles time keeping, including all internal clocks, and generic periodic
50 * tasks that run quickly and must be done on time.
55 /* Clear the RTI flag */
58 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS
, BIT3
, PORTB
);
60 /* Increment the counter */
61 Clocks
.realTimeClockMain
++;
63 /* This function could be performed without the extra variables by rolling over the main ones at the largest multiples of the next ones, but I'm not sure thats better */
65 // TODO add content to eighths of a milli RTC ?
67 /// @todo TODO refactor this entire file, especially to remove apparently expensive modulus operations which could be replaced with >= instead. Maybe much more.
68 /* Every 8th RTI execution is one milli */
69 if(Clocks
.realTimeClockMain
% 8 == 0){
70 /* Increment the milli counter */
71 Clocks
.realTimeClockMillis
++;
73 /* Increment the milli roll over variable */
74 Clocks
.millisToTenths
++;
76 /* Perform all tasks that are once per millisecond here or preferably main */
77 Clocks
.timeoutADCreadingClock
++;
78 if(Clocks
.timeoutADCreadingClock
> fixedConfigs2
.sensorSettings
.readingTimeout
){
79 /* Set force read adc flag */
80 coreStatusA
|= FORCE_READING
;
81 Clocks
.timeoutADCreadingClock
= 0;
82 }else if (CoreVars
->RPM
> 0){ // turn on very quickly if rpm appears non zero, temp impl...
88 #include "xgateTests.c"
92 /* Every 100 millis is one tenth */
93 if(Clocks
.millisToTenths
% 100 == 0){
94 /* Increment the tenths counter */
95 Clocks
.realTimeClockTenths
++;
97 /* Increment the tenths roll over variable */
98 Clocks
.tenthsToSeconds
++;
100 /* Reset the millis roll over variable */
101 Clocks
.millisToTenths
= 0;
103 /* Perform all tasks that are once per tenth of a second here or preferably main */
104 // decrement port H debounce variable till it's zero again.
105 if(portHDebounce
!= 0){
109 /* Every 10 tenths is one second */
110 if(Clocks
.tenthsToSeconds
% 10 == 0){
111 /* Increment the seconds counter */
112 Clocks
.realTimeClockSeconds
++;
114 /* Increment the seconds roll over variable */
115 Clocks
.secondsToMinutes
++;
117 /* Reset the tenths roll over variable */
118 Clocks
.tenthsToSeconds
= 0;
119 /* Perform all tasks that are once per second here or preferably main */
121 // Toggle the CEL on the same pin as the SM load/run switch
124 // temp fuel pump prime and safety off impl
125 if(coreStatusA
& FUEL_PUMP_PRIME
){
126 if(Clocks
.secondsToMinutes
== 4){
127 coreStatusA
&= CLEAR_FUEL_PUMP_PRIME
;
130 }else if(CoreVars
->RPM
== 0){ /// @todo TODO This is too quick to turn off, average 0.5 seconds, which is OK, but fastest = 0seconds which is difficult to understand, needs a flag and to be 1 - 2 with average 1.5.
134 /* Every 60 seconds is one minute, 65535 minutes is enough for us :-) */
135 if(Clocks
.secondsToMinutes
% 60 == 0){
136 /* Increment the minutes counter */
137 Clocks
.realTimeClockMinutes
++;
139 /* Potentially put an hours field in here and below, but that would be excessive */
140 // TODO add hours RTC ?
142 /* Reset the seconds roll over variable */
143 Clocks
.secondsToMinutes
= 0;
145 /* Perform all tasks that are once per minute here or preferably main */
146 // TODO add content in minutes RTC ?
148 /* Hours if statement here if we do hours which we probably won't */
153 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS
, NBIT3
, PORTB
);
157 /** @brief ECT overflow handler
159 * When the ECT free running timer hits 65535 and rolls over, this is run. Its
160 * job is to extend the timer to an effective 32 bits for longer measuring much
161 * longer periods with the same resolution. Please see section 10.5.5 of the
162 * 68HC11 reference manual for more information on this technique!
164 * @warning The extension var should be incremented before the flag is cleared!
168 void TimerOverflow(){
169 /* Increment the timer extension variable */
170 timerExtensionClock
++;
171 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS
, BIT5
, PORTB
); // TODO Should this go after the flag, or before the timer inc??? 6 possibilities here!
172 /* Clear the timer overflow interrupt flag */
174 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS
, NBIT5
, PORTB
);
178 /** @todo TODO This could be useful in future once sleeping is implemented.
179 // Generic periodic interrupt (This only works from wait mode...)
181 // Clear the flag needs check because writing a 1 can set this one
182 //if(VREGAPICL & 0x01){ // if the flag is set...
183 VREGAPICL |= 0x01; // clear it...
184 //} // and not otherwise!