main.c

Go to the documentation of this file.
00001 /*      main.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 MAIN_OR_GLOBALS
00025 #include "inc/main.h"
00026 
00027 int  main(){
00028         // Set everything up.
00029         init();
00030 
00031         //LongNoTime.timeLong = 54;
00032         // Run forever repeating.
00033         while(TRUE){
00034                 adjustPWM();
00035         //      unsigned short start = realTimeClockMillis;
00036                 /* If ADCs require forced sampling, sample now */
00037                 if(coreStatusA & FORCE_READING){
00038                         ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00039                         /* Atomic block to ensure a full set of readings are taken together */
00040 
00041                         /* Check to ensure that a reading wasn't take before we entered a non interruptable state */
00042                         if(coreStatusA & FORCE_READING){ // do we still need to do this TODO ?
00043 
00044                                 sampleEachADC(&ADCArrays); // TODO still need to do a pair of loops and clock these two functions for performance.
00045                                 //sampleLoopADC(&ADCArrays);
00046                                 resetToNonRunningState();
00047                                 Counters.timeoutADCreadingCounter++;
00048 
00049                                 /* Set flag to say calc required */
00050                                 coreStatusA |= CALC_FUEL_IGN;
00051 
00052                                 /* Clear force reading flag */
00053                                 coreStatusA &= CLEAR_FORCE_READING;
00054                         }
00055 
00056                         ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00057                 }
00058 
00059                 /* If required, do main fuel and ignition calcs first */
00060                 if(coreStatusA & CALC_FUEL_IGN){
00061                         ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00062                         /* Atomic block to ensure that we don't clear the flag for the next data set when things are tight */
00063 
00064                         /* Switch input bank so that we have a stable set of the latest data */
00065                         if(recordADCBank){
00066                                 recordADCBank = 0;
00067                                 mathInputBank = 1;
00068                         }else{
00069                                 recordADCBank = 1;
00070                                 mathInputBank = 0;
00071                         }
00072 
00073                         /* Clear the calc required flag */
00074                         coreStatusA &= CLEAR_CALC_FUEL_IGN;
00075 
00076                         ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00077 
00078                         /* Store the latency from sample time to runtime */
00079                         ISRLatencyVars.mathLatency = TCNT - ISRLatencyVars.mathSampleTimeStamp[mathInputBank];
00080                         /* Keep track of how many calcs we are managing per second... */
00081                         Counters.calcsPerformedCounter++;
00082                         /* ...and how long they take each */
00083                         unsigned short mathStartTime = TCNT;
00084 
00085                         /* Generate the core variables from sensor input and recorded tooth timings */
00086                         generateCoreVars();
00087 
00088                         RuntimeVars.genCoreVarsRuntime = TCNT - mathStartTime;
00089                         unsigned short derivedStartTime = TCNT;
00090 
00091                         /* Generate the derived variables from the core variables based on settings */
00092                         generateDerivedVars();
00093 
00094                         RuntimeVars.genDerivedVarsRuntime = TCNT - derivedStartTime;
00095                         unsigned short calcsStartTime = TCNT;
00096 
00097                         /* Perform the calculations TODO possibly move this to the software interrupt if it makes sense to do so */
00098                         calculateFuelAndIgnition();
00099 
00100                         RuntimeVars.calcsRuntime = TCNT - calcsStartTime;
00101                         /* Record the runtime of all the math total */
00102                         RuntimeVars.mathTotalRuntime = TCNT - mathStartTime;
00103 
00104                         RuntimeVars.mathSumRuntime = RuntimeVars.calcsRuntime + RuntimeVars.genCoreVarsRuntime + RuntimeVars.genDerivedVarsRuntime;
00105 
00106                         ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00107                         /* Atomic block to ensure that outputBank and outputBank Offsets match */
00108 
00109                         /* Switch banks to the latest data */
00110                         if(mathInternalBank){
00111                                 mathInternalBank = 0;
00112                                 mathInternalInjectionOffset = 0;
00113                                 mathInternalIgnitionOffset = 0;
00114                                 realTimeUseBank = 1;
00115                                 realTimeUseInjectionOffset = INJECTION_CHANNELS;
00116                                 realTimeUseIgnitionOffset = IGNITION_CHANNELS;
00117                         }else{
00118                                 mathInternalBank = 1;
00119                                 mathInternalInjectionOffset = INJECTION_CHANNELS;
00120                                 mathInternalIgnitionOffset = IGNITION_CHANNELS;
00121                                 realTimeUseBank = 0;
00122                                 realTimeUseInjectionOffset = 0;
00123                                 realTimeUseIgnitionOffset = 0;
00124                         }
00125 
00126                         ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00127                 }else{
00128                         /* In the event that no calcs are required, sleep a little before returning to retry. */
00129                         sleepMicro(RuntimeVars.mathTotalRuntime); // not doing this will cause the ISR lockouts to run for too high a proportion of the time
00130                         /* Using 0.8 ticks as micros so it will run for a little longer than the math did */
00131                 }
00132 
00133                 unsigned short logTimeBuffer = Clocks.realTimeClockTenths;
00134 
00135                 // send logging once per chosen clock tick
00136                 if((lastTime != logTimeBuffer) && (lastCalcCount != Counters.calcsPerformedCounter)){
00137                         //sendHRLog();
00138         //              sendDebug("This is a call to all my past resignations!");
00139 
00140                         sleepMicro(500);
00141 
00142                         // mechanism to ensure we send once per clock tick without doing it in the RTC section.
00143                         lastTime = logTimeBuffer;
00144                         // mechanism to ensure we only send something if the data has been updated
00145                         lastCalcCount = Counters.calcsPerformedCounter;
00146                 }else{
00147                         /* Balance out the loop for consistent running */
00148                         //sleepMicro(RuntimeVars.logSendingRuntime);
00149                         sleepMicro(500); // temporary
00150                 }
00151 
00152                 /* If the flag for com packet processing is set and the TX buffer is available process the data! */
00153                 if((RXStateFlags & RX_READY_TO_PROCESS) && !(TXBufferInUseFlags)){
00154                         /* Clear the flag */
00155                         RXStateFlags &= RX_CLEAR_READY_TO_PROCESS;
00156 
00157                         /* Handle the incoming packet */
00158                         decodePacketAndBuildResponse();
00159                 }
00160 
00161                 // on once per cycle for main loop heart beat (J0)
00162                 PORTJ ^= 0x01;
00163 
00164 
00165                 // debug...
00166                 if(SCI0CR2 & SCICR2_RX_ENABLE){
00167                         PORTK |= BIT2;
00168                 }else{
00169                         PORTK &= NBIT2;
00170                 }
00171 
00172                 if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){
00173                         PORTK |= BIT3;
00174                 }else{
00175                         PORTK &= NBIT3;
00176                 }
00177 
00178                 // PWM experimentation
00179                 adjustPWM();
00180         }
00181 }

Generated on Mon Nov 10 21:18:50 2008 for freeems by  doxygen 1.5.2