00001 /* FreeEMS - the open source engine management system 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 email them upstream to 00021 us at admin(at)diyefi(dot)org or, even better, fork the code on github.com! 00022 00023 Thank you for choosing FreeEMS to run your engine! */ 00024 00025 00040 #define IGNITIONISRS_C 00041 #include "inc/freeEMS.h" 00042 #include "inc/interrupts.h" 00043 00044 00045 /* Summary of intended ignition timing scheme 00046 * 00047 * Set TWO PIT timers based on a reference point (probably single cam trigger or optionally toggle bit based on missing tooth on crank) 00048 * Arm one PIT timer interrupt to trigger when we need to start dwelling 00049 * Arm the other PIT timer interrupt to trigger when we need to fire 00050 * Configure a variable to point to the next pin to turn on for dwell 00051 * Configure a variable to point to the next pin to turn off to fire 00052 * On PIT interrupt for dwell check to see that spark should have finished 00053 * If so, turn on coil to dwell 00054 * If not, reset dwell timer interrupt for end of spark event 00055 * On PIT interrupt for spark, turn off coil (amything else?) 00056 * Repeat for each cylinder. 00057 */ 00058 00059 /* Further consideration to spark duration and dwell starting possibly needs to be done. */ 00060 00061 /* further reading : ftp://ftp-sop.inria.fr/esterel/pub/papers/FDL99-camready.pdf section 4.1 has a nice diagram */ 00062 00063 00072 void IgnitionDwellISR(void) 00073 { 00074 // clear flag 00075 PITTF = DWELL_ENABLE; 00076 00077 // start dwelling asap 00078 PORTS_BA |= dwellStartMasks[nextDwellChannel]; 00079 00080 if(dwellQueueLength == 0){ 00081 // turn off the int 00082 PITINTE &= DWELL_DISABLE; 00083 00084 // disable channels 00085 PITCE &= DWELL_DISABLE; 00086 }else{ 00087 // reduce queue length by one 00088 dwellQueueLength--; 00089 00090 // increment channel counter to next channel 00091 if(nextDwellChannel < (fixedConfigs1.engineSettings.combustionEventsPerEngineCycle - 1)){ 00092 nextDwellChannel++; // if not the last channel, increment 00093 }else{ 00094 nextDwellChannel = 0; // if the last channel, reset to zero 00095 } 00096 00097 // 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. 00098 if(dwellQueueLength > 0){ 00099 if(dwellQueueLength > 8){ // TODO ???? why 8 ???? 12 or combustion events per... or ? 00100 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00101 PORTS |= 0x20; 00102 }else{ 00103 // load the timer if the index is good 00104 PITLD0 = queuedDwellOffsets[dwellQueueLength - 1]; 00105 } 00106 } 00107 } 00108 00109 // blink a led 00110 PORTS ^= 0x80; 00111 } 00112 00113 00122 void IgnitionFireISR(void) 00123 { 00124 // clear flag 00125 PITTF = IGNITION_ENABLE; 00126 00127 // fire the coil asap 00128 PORTS_BA &= ignitionMasks[nextIgnitionChannel]; 00129 00130 if(ignitionQueueLength == 0){ 00131 // turn off the int 00132 PITINTE &= IGNITION_DISABLE; 00133 00134 // disable channels 00135 PITCE &= IGNITION_DISABLE ; 00136 }else{ 00137 // reduce queue length by one 00138 ignitionQueueLength--; 00139 00140 // increment channel counter to next channel 00141 if(nextIgnitionChannel < (fixedConfigs1.engineSettings.combustionEventsPerEngineCycle - 1)){ 00142 nextIgnitionChannel++; // if not the last channel, increment 00143 }else{ 00144 nextIgnitionChannel = 0; // if the last channel, reset to zero 00145 } 00146 00147 // 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. 00148 if(ignitionQueueLength > 0){ 00149 if(ignitionQueueLength > fixedConfigs1.engineSettings.combustionEventsPerEngineCycle){ // TODO as above!!!!!!!!!! 00150 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00151 PORTS |= 0x10; 00152 }else{ 00153 // load the timer if the index is good 00154 PITLD0 = queuedIgnitionOffsets[ignitionQueueLength - 1]; 00155 } 00156 } 00157 } 00158 00159 // blink a led 00160 PORTS ^= 0x40; 00161 }