00001 /* ignitionISRs.c 00002 00003 Copyright 2008 Fred Cooke 00004 00005 This file is part of the FreeEMS project. 00006 00007 FreeEMS software is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 FreeEMS software is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with any FreeEMS software. If not, see <http://www.gnu.org/licenses/>. 00019 00020 We ask that if you make any changes to this file you send them upstream to us at admin@diyefi.org 00021 00022 Thank you for choosing FreeEMS to run your engine! */ 00023 00024 #define IGNITIONISRS_C 00025 #include "inc/freeEMS.h" 00026 #include "inc/interrupts.h" 00027 #include "inc/ignitionISRs.h" 00028 00029 /* Summary of intended ignition timing scheme 00030 * 00031 * Set TWO PIT timers based on a reference point (probably single cam trigger or optionally toggle bit based on missing tooth on crank) 00032 * Arm one PIT timer interrupt to trigger when we need to start dwelling 00033 * Arm the other PIT timer interrupt to trigger when we need to fire 00034 * Configure a variable to point to the next pin to turn on for dwell 00035 * Configure a variable to point to the next pin to turn off to fire 00036 * On PIT interrupt for dwell check to see that spark should have finished 00037 * If so, turn on coil to dwell 00038 * If not, reset dwell timer interrupt for end of spark event 00039 * On PIT interrupt for spark, turn off coil (amything else?) 00040 * Repeat for each cylinder. 00041 */ 00042 00043 /* Further consideration to spark duration and dwell starting possibly needs to be done. */ 00044 00045 /* further reading : ftp://ftp-sop.inria.fr/esterel/pub/papers/FDL99-camready.pdf section 4.1 has a nice diagram */ 00046 00047 void IgnitionDwellISR(void) 00048 { 00049 // clear flag 00050 PITTF = DWELL_ENABLE; 00051 00052 // start dwelling asap 00053 PORTS_BA |= dwellStartMasks[nextDwellChannel]; 00054 00055 if(dwellQueueLength == 0){ 00056 // turn off the int 00057 PITINTE &= DWELL_DISABLE; 00058 00059 // disable channels 00060 PITCE &= DWELL_DISABLE; 00061 }else{ 00062 // reduce queue length by one 00063 dwellQueueLength--; 00064 00065 // increment channel counter to next channel 00066 if(nextDwellChannel < (fixedConfigs.combustionEventsPerEngineCycle - 1)){ 00067 nextDwellChannel++; // if not the last channel, increment 00068 }else{ 00069 nextDwellChannel = 0; // if the last channel, reset to zero 00070 } 00071 00072 // if the queue length after decrement is greater than 0 then we need to load the timer, if it is zero and we decremented, the timer was already loaded. 00073 if(dwellQueueLength > 0){ 00074 if(dwellQueueLength > 8){ // TODO ???? why 8 ???? 12 or combustion events per... or ? 00075 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00076 PORTS |= 0x20; 00077 }else{ 00078 // load the timer if the index is good 00079 PITLD0 = queuedDwellOffsets[dwellQueueLength - 1]; 00080 } 00081 } 00082 } 00083 00084 // blink a led 00085 PORTS ^= 0x80; 00086 } 00087 00088 00089 void IgnitionFireISR(void) 00090 { 00091 // clear flag 00092 PITTF = IGNITION_ENABLE; 00093 00094 // fire the coil asap 00095 PORTS_BA &= ignitionMasks[nextIgnitionChannel]; 00096 00097 if(ignitionQueueLength == 0){ 00098 // turn off the int 00099 PITINTE &= IGNITION_DISABLE; 00100 00101 // disable channels 00102 PITCE &= IGNITION_DISABLE ; 00103 }else{ 00104 // reduce queue length by one 00105 ignitionQueueLength--; 00106 00107 // increment channel counter to next channel 00108 if(nextIgnitionChannel < (fixedConfigs.combustionEventsPerEngineCycle - 1)){ 00109 nextIgnitionChannel++; // if not the last channel, increment 00110 }else{ 00111 nextIgnitionChannel = 0; // if the last channel, reset to zero 00112 } 00113 00114 // if the queue length after decrement is greater than 0 then we need to load the timer, if it is zero and we decremented, the timer was already loaded. 00115 if(ignitionQueueLength > 0){ 00116 if(ignitionQueueLength > fixedConfigs.combustionEventsPerEngineCycle){ // TODO as above!!!!!!!!!! 00117 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00118 PORTS |= 0x10; 00119 }else{ 00120 // load the timer if the index is good 00121 PITLD0 = queuedIgnitionOffsets[ignitionQueueLength - 1]; 00122 } 00123 } 00124 } 00125 00126 // blink a led 00127 PORTS ^= 0x40; 00128 }