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