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 #include "inc/main.h"
00025 
00026 int  main(){ // TODO maybe move this to paged flash ?
00027         // Set everything up.
00028         init();
00029 
00030         //LongNoTime.timeLong = 54;
00031         // Run forever repeating.
00032         while(TRUE){
00033                 adjustPWM();
00034         //      unsigned short start = realTimeClockMillis;
00035                 /* If ADCs require forced sampling, sample now */
00036                 if(coreStatusA & FORCE_READING){
00037                         ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00038                         /* Atomic block to ensure a full set of readings are taken together */
00039 
00040                         /* Check to ensure that a reading wasn't take before we entered a non interruptable state */
00041                         if(coreStatusA & FORCE_READING){ // do we still need to do this TODO ?
00042 
00043                                 sampleEachADC(ADCArraysRecord); // TODO still need to do a pair of loops and clock these two functions for performance.
00044                                 //sampleLoopADC(&ADCArrays);
00045                                 resetToNonRunningState();
00046                                 Counters.timeoutADCreadings++;
00047 
00048                                 /* Set flag to say calc required */
00049                                 coreStatusA |= CALC_FUEL_IGN;
00050 
00051                                 /* Clear force reading flag */
00052                                 coreStatusA &= CLEAR_FORCE_READING;
00053                         }
00054 
00055                         ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00056                 }
00057 
00058                 /* If required, do main fuel and ignition calcs first */
00059                 if(coreStatusA & CALC_FUEL_IGN){
00060                         ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00061                         /* Atomic block to ensure that we don't clear the flag for the next data set when things are tight */
00062 
00063                         /* Switch input bank so that we have a stable set of the latest data */
00064                         if(ADCArrays == &ADCArrays1){
00065                                 RPM = &RPM0; // TODO temp, remove
00066                                 RPMRecord = &RPM1; // TODO temp, remove
00067                                 ADCArrays = &ADCArrays0;
00068                                 ADCArraysRecord = &ADCArrays1;
00069                                 mathSampleTimeStamp = &ISRLatencyVars.mathSampleTimeStamp0; // TODO temp, remove
00070                                 mathSampleTimeStampRecord = &ISRLatencyVars.mathSampleTimeStamp1; // TODO temp, remove
00071                         }else{
00072                                 RPM = &RPM1; // TODO temp, remove
00073                                 RPMRecord = &RPM0; // TODO temp, remove
00074                                 ADCArrays = &ADCArrays1;
00075                                 ADCArraysRecord = &ADCArrays0;
00076                                 mathSampleTimeStamp = &ISRLatencyVars.mathSampleTimeStamp1; // TODO temp, remove
00077                                 mathSampleTimeStampRecord = &ISRLatencyVars.mathSampleTimeStamp0; // TODO temp, remove
00078                         }
00079 
00080                         /* Clear the calc required flag */
00081                         coreStatusA &= CLEAR_CALC_FUEL_IGN;
00082 
00083                         ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00084 
00085                         /* Store the latency from sample time to runtime */
00086                         ISRLatencyVars.mathLatency = TCNT - *mathSampleTimeStamp;
00087                         /* Keep track of how many calcs we are managing per second... */
00088                         Counters.calculationsPerformed++;
00089                         /* ...and how long they take each */
00090                         unsigned short mathStartTime = TCNT;
00091 
00092                         /* Generate the core variables from sensor input and recorded tooth timings */
00093                         generateCoreVars();
00094 
00095                         RuntimeVars.genCoreVarsRuntime = TCNT - mathStartTime;
00096                         unsigned short derivedStartTime = TCNT;
00097 
00098                         /* Generate the derived variables from the core variables based on settings */
00099                         generateDerivedVars();
00100 
00101                         RuntimeVars.genDerivedVarsRuntime = TCNT - derivedStartTime;
00102                         unsigned short calcsStartTime = TCNT;
00103 
00104                         /* Perform the calculations TODO possibly move this to the software interrupt if it makes sense to do so */
00105                         calculateFuelAndIgnition();
00106 
00107                         RuntimeVars.calcsRuntime = TCNT - calcsStartTime;
00108                         /* Record the runtime of all the math total */
00109                         RuntimeVars.mathTotalRuntime = TCNT - mathStartTime;
00110 
00111                         RuntimeVars.mathSumRuntime = RuntimeVars.calcsRuntime + RuntimeVars.genCoreVarsRuntime + RuntimeVars.genDerivedVarsRuntime;
00112 
00113                         ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00114                         /* Atomic block to ensure that outputBank and outputBank Offsets match */
00115 
00116                         /* Switch banks to the latest data */
00117                         if(injectorMainPulseWidthsMath == injectorMainPulseWidths1){
00118                                 currentDwellMath = &currentDwell0;
00119                                 currentDwellRealtime = &currentDwell1;
00120                                 injectorMainPulseWidthsMath = injectorMainPulseWidths0;
00121                                 injectorMainPulseWidthsRealtime = injectorMainPulseWidths1;
00122                                 injectorStagedPulseWidthsMath = injectorStagedPulseWidths0;
00123                                 injectorStagedPulseWidthsRealtime = injectorStagedPulseWidths1;
00124                         }else{
00125                                 currentDwellMath = &currentDwell1;
00126                                 currentDwellRealtime = &currentDwell0;
00127                                 injectorMainPulseWidthsMath = injectorMainPulseWidths1;
00128                                 injectorMainPulseWidthsRealtime = injectorMainPulseWidths0;
00129                                 injectorStagedPulseWidthsMath = injectorStagedPulseWidths1;
00130                                 injectorStagedPulseWidthsRealtime = injectorStagedPulseWidths0;
00131                         }
00132 
00133                         ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
00134                 }else{
00135                         /* In the event that no calcs are required, sleep a little before returning to retry. */
00136                         sleepMicro(RuntimeVars.mathTotalRuntime); // not doing this will cause the ISR lockouts to run for too high a proportion of the time
00137                         /* Using 0.8 ticks as micros so it will run for a little longer than the math did */
00138                 }
00139 
00140 
00141                 if(!(TXBufferInUseFlags)){
00142                 //      unsigned short logTimeBuffer = Clocks.realTimeClockTenths;
00143                         /* If the flag for com packet processing is set and the TX buffer is available process the data! */
00144                         if(RXStateFlags & RX_READY_TO_PROCESS){
00145                                 /* Clear the flag */
00146                                 RXStateFlags &= RX_CLEAR_READY_TO_PROCESS;
00147 
00148                                 /* Handle the incoming packet */
00149                                 decodePacketAndRespond();
00150                         }else if(ShouldSendLog){//(lastTime != logTimeBuffer) && (lastCalcCount != Counters.calculationsPerformed)){
00151 
00152                                 /* send asynchronous data log if required */
00153                                 if(asyncDatalogType!= asyncDatalogOff){
00154                                         switch (asyncDatalogType) {
00155                                         case asyncDatalogBasic:
00156                                         {
00157                                                 /* Flag that we are transmitting! */
00158                                                 TXBufferInUseFlags |= COM_SET_SCI0_INTERFACE_ID;
00159                                                 // SCI0 only for now...
00160 
00161                                                 // headers including length...                                          *length = configuredBasicDatalogLength;
00162                                                 TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
00163 
00164                                                 /* Initialised here such that override is possible */
00165                                                 TXBufferCurrentPositionSCI0 = (unsigned char*)&TXBuffer;
00166                                                 TXBufferCurrentPositionCAN0 = (unsigned char*)&TXBuffer;
00167 
00168                                                 /* Set the flags : firmware, no ack, no addrs, has length */
00169                                                 *TXBufferCurrentPositionHandler = HEADER_HAS_LENGTH;
00170                                                 TXBufferCurrentPositionHandler++;
00171 
00172                                                 /* Set the payload ID */
00173                                                 *((unsigned short*)TXBufferCurrentPositionHandler) = responseBasicDatalog;
00174                                                 TXBufferCurrentPositionHandler += 2;
00175 
00176                                                 /* Set the length */
00177                                                 *((unsigned short*)TXBufferCurrentPositionHandler) = configuredBasicDatalogLength;
00178                                                 TXBufferCurrentPositionHandler += 2;
00179 
00180                                                 /* populate data log */
00181                                                 populateBasicDatalog();
00182                                                 checksumAndSend();
00183                                                 break;
00184                                         }
00185                                         case asyncDatalogConfig:
00186                                         {
00187                                                 // TODO
00188                                                 break;
00189                                         }
00190                                         case asyncDatalogTrigger:
00191                                         {
00192                                                 // TODO
00193                                                 break;
00194                                         }
00195                                         case asyncDatalogADC:
00196                                         {
00197                                                 // TODO
00198                                                 break;
00199                                         }
00200                                         case asyncDatalogCircBuf:
00201                                         {
00202                                                 // TODO
00203                                                 break;
00204                                         }
00205                                         case asyncDatalogCircCAS:
00206                                         {
00207                                                 // TODO
00208                                                 break;
00209                                         }
00210                                         case asyncDatalogLogic:
00211                                         {
00212                                                 // TODO
00213                                                 break;
00214                                         }
00215                                         }
00216                                 }
00217                                 ShouldSendLog = FALSE;
00218 //                              // mechanism to ensure we send once per clock tick without doing it in the RTC section.
00219 //                              lastTime = logTimeBuffer;
00220 //                              // mechanism to ensure we only send something if the data has been updated
00221 //                              lastCalcCount = Counters.calculationsPerformed;
00222                         }
00223                 }
00224                 // on once per cycle for main loop heart beat (J0)
00225                 PORTJ ^= 0x01;
00226 
00227 
00228                 // debug...
00229                 if(SCI0CR2 & SCICR2_RX_ENABLE){
00230                         PORTK |= BIT2;
00231                 }else{
00232                         PORTK &= NBIT2;
00233                 }
00234 
00235                 if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){
00236                         PORTK |= BIT3;
00237                 }else{
00238                         PORTK &= NBIT3;
00239                 }
00240 
00241                 // PWM experimentation
00242                 adjustPWM();
00243         }
00244 }

Generated on Mon Dec 22 21:29:18 2008 for freeems by  doxygen 1.5.2