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 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.
53 /* Clear the RTI flag */
56 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS
, BIT3
, PORTB
);
58 /* Increment the counter */
59 Clocks
.realTimeClockMain
++;
61 /* 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 */
63 // TODO add content to eighths of a milli RTC ?
65 /// @todo TODO refactor this entire file, especially to remove apparently expensive modulus operations which could be replaced with >= instead. Maybe much more.
66 /* Every 8th RTI execution is one milli */
67 if(Clocks
.realTimeClockMain
% 8 == 0){
68 /* Increment the milli counter */
69 Clocks
.realTimeClockMillis
++;
71 /* Increment the milli roll over variable */
72 Clocks
.millisToTenths
++;
74 /* Perform all tasks that are once per millisecond here or preferably main */
75 Clocks
.timeoutADCreadingClock
++;
76 if(Clocks
.timeoutADCreadingClock
> fixedConfigs2
.sensorSettings
.readingTimeout
){
77 /* Set force read adc flag */
78 coreStatusA
|= FORCE_READING
;
79 Clocks
.timeoutADCreadingClock
= 0;
80 }else if (CoreVars
->RPM
> 0){ // turn on very quickly if rpm appears non zero, temp impl...
86 #include "xgateTests.c"
90 /* Every 100 millis is one tenth */
91 if(Clocks
.millisToTenths
% 100 == 0){
92 /* Increment the tenths counter */
93 Clocks
.realTimeClockTenths
++;
95 /* Increment the tenths roll over variable */
96 Clocks
.tenthsToSeconds
++;
98 /* Reset the millis roll over variable */
99 Clocks
.millisToTenths
= 0;
101 /* Perform all tasks that are once per tenth of a second here or preferably main */
102 // decrement port H debounce variable till it's zero again.
103 if(portHDebounce
!= 0){
107 /* Every 10 tenths is one second */
108 if(Clocks
.tenthsToSeconds
% 10 == 0){
109 /* Increment the seconds counter */
110 Clocks
.realTimeClockSeconds
++;
112 /* Increment the seconds roll over variable */
113 Clocks
.secondsToMinutes
++;
115 /* Reset the tenths roll over variable */
116 Clocks
.tenthsToSeconds
= 0;
117 /* Perform all tasks that are once per second here or preferably main */
119 // Toggle the CEL on the same pin as the SM load/run switch
122 // temp fuel pump prime and safety off impl
123 if(coreStatusA
& FUEL_PUMP_PRIME
){
124 if(Clocks
.secondsToMinutes
== fixedConfigs2
.sensorSettings
.fuelPumpPrimePeriod
){
125 coreStatusA
&= CLEAR_FUEL_PUMP_PRIME
;
128 }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.
132 /* Every 60 seconds is one minute, 65535 minutes is enough for us :-) */
133 if(Clocks
.secondsToMinutes
% 60 == 0){
134 /* Increment the minutes counter */
135 Clocks
.realTimeClockMinutes
++;
137 /* Potentially put an hours field in here and below, but that would be excessive */
138 // TODO add hours RTC ?
140 /* Reset the seconds roll over variable */
141 Clocks
.secondsToMinutes
= 0;
143 /* Perform all tasks that are once per minute here or preferably main */
144 // TODO add content in minutes RTC ?
146 /* Hours if statement here if we do hours which we probably won't */
151 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS
, NBIT3
, PORTB
);
155 /** @brief ECT overflow handler
157 * When the ECT free running timer hits 65535 and rolls over, this is run. Its
158 * job is to extend the timer to an effective 32 bits for longer measuring much
159 * longer periods with the same resolution. Please see section 10.5.5 of the
160 * 68HC11 reference manual for more information on this technique!
162 * @warning The extension var should be incremented before the flag is cleared!
164 void TimerOverflow(){
165 /* Increment the timer extension variable */
166 timerExtensionClock
++;
167 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS
, BIT5
, PORTB
); // TODO Should this go after the flag, or before the timer inc??? 6 possibilities here!
168 /* Clear the timer overflow interrupt flag */
170 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS
, NBIT5
, PORTB
);
174 /** @todo TODO This could be useful in future once sleeping is implemented.
175 // Generic periodic interrupt (This only works from wait mode...)
177 // Clear the flag needs check because writing a 1 can set this one
178 //if(VREGAPICL & 0x01){ // if the flag is set...
179 VREGAPICL |= 0x01; // clear it...
180 //} // and not otherwise!