Set dead time to flat 0.9ms until I can get a chance to measure it with the new drive...
[freeems-vanilla.git] / src / main / miscISRs.c
blob2c393f2b27e483da782f88f73e6404f76358eeb3
1 /* FreeEMS - the open source engine management system
3 * Copyright 2008-2013 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!
27 /** @file
29 * @ingroup interruptHandlers
31 * @brief Miscellaneous Interrupt Handlers
33 * Various non-descript interrupt handlers that don't really fit anywhere else
34 * and aren't big enough to live on their own just yet.
38 #include "inc/freeEMS.h"
39 #include "inc/interrupts.h"
40 #include "inc/decoderInterface.h"
41 #include "inc/init.h"
44 /** @brief Unimplemented Interrupt Handler
46 * Unimplemented interrupt service routine for calls we weren't expecting.
47 * Currently this simply counts bad calls like any other event type.
49 * @todo TODO Split this into its own file, create one for each, and clear flags for all, and increment shared counter as is.
50 * @todo TODO Currently not a problem, but as indirectly pointed out by johntramp, if no flag clearing is being done, then this code will run continuously, which is not a good idea...
52 void UISR(void){
53 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
54 FLAG_AND_INC_FLAGGABLE(FLAG_CALLS_TO_UISRS_OFFSET);
55 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
58 /** @brief Spurious Interrupt Handler
60 * This is fired when the correct vector for an interrupt can not be determined.
62 * Theoretically this should not happen, and probably indicates a code fault.
64 void SpuriousISR(void){
65 // No flag to clear
66 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
67 FLAG_AND_INC_FLAGGABLE2(FLAG_SPURIOUS_INTERRUPTS_OFFSET);
68 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
71 /** @brief Unimplemented Opcode Handler
73 * Unimplemented opcode trap. This should never run and probably indicates an
74 * attempt to execute data instead of code, but could be an assembler issue.
76 void UnimplOpcodeISR(void){
77 // No flag to clear
78 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
79 FLAG_AND_INC_FLAGGABLE2(FLAG_UNIMPLEMENTED_OPCODES_OFFSET);
80 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
83 /** @brief CPU RAM Access Violation Handler
85 * If the CPU tries to access protected XGATE RAM, this is fired.
87 void RAMViolationISR(void){
88 // Clear the flag
89 RAMWPC = AVIF;
90 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
91 FLAG_AND_INC_FLAGGABLE2(FLAG_RAM_ACCESS_VIOLATIONS_OFFSET);
92 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
95 /** @brief XGATE Software Error Handler
97 * If buggy code is being executed on the XGATE, this may fire alerting us to it.
99 void XGATEErrorISR(void){
100 // Clear the flag
101 XGMCTL = (XGSWEIFM | XGSWEIF);
102 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
103 FLAG_AND_INC_FLAGGABLE2(FLAG_XGATE_SOFTWARE_ERRORS_OFFSET);
104 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
107 /** @brief PLL Lock Lost/Gained
109 * When the Phase Locked Loop is lost or gained, this is called.
111 void PLLLockISR(void){
112 // Clear the flag
113 CRGFLG = PLLLOCKIF;
114 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
115 // Check the state of PLL lock
116 if(CRGFLG & PLLLOCK){ // Recovered
117 // Re-enable outputs with return of accurate clock
118 ((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnLostPLL = 0;
119 ((injectionCutFlags *)&KeyUserDebugs.injectionCuts)->InjLostPLL = 0;
120 }else{ // Lock lost
121 // Record the loss of PLL lock
122 FLAG_AND_INC_FLAGGABLE(FLAG_PHASE_LOCKED_LOOP_LOCK_LOST_OFFSET);
123 // Force sync loss with special code to prevent engine damage from incorrect timings
124 // This is required otherwise we never see the self clock code, as it's immediately over-written by our code
125 if(KeyUserDebugs.syncLostWithThisID == SELF_CLOCK_MODE_PRECAUTIONARY){
126 // Don't over-write the self clock sync loss ID
127 resetToNonRunningState(SELF_CLOCK_MODE_PRECAUTIONARY);
128 }else{
129 // This means ONLY the PLL lock was lost (at this time)
130 resetToNonRunningState(PLL_LOCK_LOST_PRECAUTIONARY);
132 // Disable outputs as a precaution with dodgy clock
133 ((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnLostPLL = 1;
134 ((injectionCutFlags *)&KeyUserDebugs.injectionCuts)->InjLostPLL = 1;
136 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
139 /** @brief Self Clock Mode Entered/Exited
141 * When the main clock quality drops too low to be used, self clock is entered.
143 * See section 2.6.3 of the device manual for more information.
145 void SelfClockISR(void){
146 // Clear the flag
147 CRGFLG = SCMIF;
148 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
149 // Check the state of self clock mode flag
150 if(CRGFLG & SCM){ // Self Clock Mode
151 // Record the loss of main clock
152 FLAG_AND_INC_FLAGGABLE(FLAG_SELF_CLOCK_MODE_ENTERED_OFFSET);
153 // Force sync loss with special code to prevent engine damage from incorrect timings
154 resetToNonRunningState(SELF_CLOCK_MODE_PRECAUTIONARY);
155 // Disable outputs as a precaution with dodgy clock
156 ((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnSelfClock = 1;
157 ((injectionCutFlags *)&KeyUserDebugs.injectionCuts)->InjSelfClock = 1;
158 }else{ // Recovered
159 // Disabled when falling back to Self Clock Mode, re-enable here
160 enablePLL(); // Note, busy wait with no limit, danger to the manifold!
162 // Re-enable outputs with return of accurate clock
163 ((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnSelfClock = 0;
164 ((injectionCutFlags *)&KeyUserDebugs.injectionCuts)->InjSelfClock = 0;
166 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
169 /** @brief Port P pins ISR
171 * Interrupt handler for edge events on port P pins. Not currently used.
173 void PortPISR(void){
174 /* Clear all port P flags (we only want one at a time) */
175 PIFP = ONES;
176 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
177 FLAG_AND_INC_FLAGGABLE(FLAG_CALLS_TO_UISRS_OFFSET);
178 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
182 /** @brief Port J pins ISR
184 * Interrupt handler for edge events on port J pins. Not currently used.
186 void PortJISR(void){
187 /* Clear all port H flags (we only want one at a time) */
188 PIFJ = ONES;
189 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
190 FLAG_AND_INC_FLAGGABLE(FLAG_CALLS_TO_UISRS_OFFSET);
191 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
195 /** @brief Port H pins ISR
197 * Interrupt handler for edge events on port H pins. Not currently used.
199 void PortHISR(void)
201 // // read the interrupt flags to a variable
202 // unsigned char portHFlags = PIFH;
203 // portHFlags &= 0xF8; // mask out the other bits
205 // /* Clear all port H flags (we only want one at a time) */
206 PIFH = ONES;
207 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
209 // Bump this for the time being as this should not be occurring.
210 FLAG_AND_INC_FLAGGABLE(FLAG_CALLS_TO_UISRS_OFFSET);
212 // // Toggle a LED so we can see if the code ran
213 // PO-don't use this-RTA ^= 0x80; // Fuel pump pin (A7)
215 // debounce
216 if(portHDebounce == 0){
217 portHDebounce = 2;
218 }else{
219 return;
222 // // find out which pin triggered it, clear the flag, perform the action.
223 // switch(portHFlags)
224 // {
225 // case 0x80 : // Increment cylinder count and set port count appropriately.
226 // switch (configs.combustionEventsPerEngineCycle) {
227 // case 1 :
228 // configs.combustionEventsPerEngineCycle = 2;
229 // configs.ports = 2;
230 // break;
231 // case 2 :
232 // configs.combustionEventsPerEngineCycle = 3;
233 // configs.ports = 3;
234 // break;
235 // case 3 :
236 // configs.combustionEventsPerEngineCycle = 4;
237 // configs.ports = 4;
238 // break;
239 // case 4 :
240 // configs.combustionEventsPerEngineCycle = 5;
241 // configs.ports = 5;
242 // break;
243 // case 5 :
244 // configs.combustionEventsPerEngineCycle = 6;
245 // configs.ports = 6;
246 // break;
247 // case 6 :
248 // configs.combustionEventsPerEngineCycle = 8;
249 // configs.ports = 4;
250 // break;
251 // case 8 :
252 // configs.combustionEventsPerEngineCycle = 10;
253 // configs.ports = 5;
254 // break;
255 // case 10 :
256 // configs.combustionEventsPerEngineCycle = 12;
257 // configs.ports = 6;
258 // break;
259 // case 12 :
260 // configs.combustionEventsPerEngineCycle = 1;
261 // configs.ports = 1;
262 // break;
263 // }
264 // break;
265 // case 0x40 : // Injection output enable/disable
266 // break;
267 // case 0x20 : // Ignition output enable/disable
268 // break;
269 // case 0x10 : // Staged injection enable/disable
270 // break;
271 // case 0x08 : // Staged injection start sched/fixed
272 // break;
273 // case 0x04 : // Staged injection end sched/fixed
274 // break;
275 // case 0x02 : // free input
276 // break;
277 // case 0x01 : // free input
278 // break;
279 // default : // Two or more pressed, nothing to do except wait for another button press
280 // break;
281 // }
282 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
286 /** @brief IRQ/PE1 pin ISR
288 * Interrupt handler for edge events on the IRQ/PE1 pin. Not currently used.
290 void IRQISR(void){
291 /* Clear the flag */
292 // ?? TODO
293 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
294 FLAG_AND_INC_FLAGGABLE(FLAG_CALLS_TO_UISRS_OFFSET);
295 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
299 /** @brief XIRQ/PE0 pin ISR
301 * Interrupt handler for edge events on the XIRQ/PE0 pin. Not currently used.
303 void XIRQISR(void){
304 /* Clear the flag */
305 // ?? TODO
306 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
307 FLAG_AND_INC_FLAGGABLE(FLAG_CALLS_TO_UISRS_OFFSET);
308 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
312 /** @brief Low Voltage Counter
314 * Count how often our voltage drops lower than it should without resetting.
316 void LowVoltageISR(void){
317 /* Clear the flag */
318 VREGCTRL |= 0x01;
319 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT6, PORTB);
320 FLAG_AND_INC_FLAGGABLE(FLAG_LOW_VOLTAGE_CONDITION_OFFSET);
321 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT6, PORTB);