init.c

Go to the documentation of this file.
00001 /*      init.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 INIT_C
00025 #include "inc/freeEMS.h"
00026 #include "inc/interrupts.h"
00027 #include "inc/utils.h"
00028 #include "inc/commsISRs.h"
00029 #include "inc/init.h"
00030 #include <string.h>
00031 
00032 
00033 /* Set the Phase Locked Loop to our desired frequency (80MHz) and switch to using it for clock (40MHz bus speed) */
00034 void initPLL(){
00035         CLKSEL &= PLLSELOFF;    /* Switches to base external OSCCLK to ensure PLL is not being used (off out of reset, but not sure if the monitor turns it on before passing control or not) */
00036         PLLCTL &= PLLOFF;               /* Turn the PLL device off to adjust its speed (on by default out of reset) */
00037         REFDV = PLLDIVISOR;             /* 16MHz / (3 + 1) = 4MHz Bus frequency */
00038         SYNR = PLLMULTIPLIER;   /* 4MHz * (9 + 1) = 40MHz Bus frequency */
00039         PLLCTL |= PLLON;                /* Turn the PLL device back on again at 80MHz */
00040 
00041         while (!(CRGFLG & PLLLOCK)){
00042                 /* Do nothing while we wait till the PLL loop locks onto the target frequency. */
00043                 /* Target frequency is given by (2 * (crystal frequency / (REFDV + 1)) * (SYNR + 1)) */
00044                 /* Bus frequency is half PLL frequency and given by ((crystal frequency / (REFDV + 1)) * (SYNR + 1)) */
00045         }
00046 
00047         CLKSEL = PLLSELON;              /* Switches to PLL clock for internal bus frequency */
00048         /* from MC9S12XDP512V2.pdf Section 2.4.1.1.2 page 101 Third paragraph */
00049         /* This takes a MAXIMUM of 4 OSCCLK clock cylces PLUS 4 PLL clock cycles */
00050         /* During this time ALL clocks freeze, and CPU activity ceases */
00051         /* For this reason there is no point in waiting for this to occur, we already are */
00052 }
00053 
00054 /* TODO Check the code for flash errors based on stored checksum */
00055 void checkChecksum(){
00056         //
00057 }
00058 
00059 /* Configure all the I/O to default values to keep power use down etc */
00060 void initIO(){
00061         /* for now, hard code all stuff to be outputs as per Freescale documentation,   */
00062         /* later what to do will be pulled from flash configuration such that all               */
00063         /* things are setup at once, and not messed with thereafter. when the port              */
00064         /* something uses is changed via the tuning interface, the confuration will be  */
00065         /* done on the fly, and the value burned to flash such that next boot happens   */
00066         /* correctly and current running devices are used in that way.                                  */
00067 
00068         /* Turn off and on and configure all the modules in an explicit way */
00069         // TODO set up and turn off all modules (CAN,SCI,SPI,IIC,etc)
00070 
00071         /* Turn off the digital input buffers on the ATD channels */
00072         ATD0DIEN = ZEROS; /* You are out of your mind if you waste this on digital Inputs */
00073         ATD1DIEN0 = ZEROS; /* You are out of your mind if you waste this on digital Inputs (NOT-bonded, can't use) */
00074         ATD1DIEN1 = ZEROS; /* You are out of your mind if you waste this on digital Inputs */
00075         /* TODO Second half of ATD1 - can we disable this somehow */
00076 
00077         /* And configure them all for analog input */
00078         ATD0CTL2 = 0x80; /* Turns on the ADC block. */
00079         ATD0CTL3 = 0x40; /* Set sequence length = 8 */
00080         ATD0CTL5 = 0xB0; /* Sets justification to right, multiplex and scan all channels. */
00081         // TODO find out if this is the default (i suspect it is)
00082         // TODO look into sampling techniques
00083 
00084         /* And configure them all for analog input */
00085         ATD1CTL0 = 0x07; /* Sets wrap on 8th ADC because we can't use the other 8 */
00086         ATD1CTL2 = 0x80; /* Turns on the ADC block. */
00087         ATD1CTL3 = 0x40; /* Set sequence length = 8 */
00088         ATD1CTL5 = 0xB0; /* Sets justification to right, multiplex and scan all channels. */
00089         // TODO find out if this is the default (i suspect it is)
00090         // TODO look into sampling techniques
00091 
00092         /* Set up the PWM component and initialise its values to off */
00093         PWME = 0x7F; /* Turn on PWM 0 - 6 (7 is user LED on main board) */
00094         PWMCLK = ZEROS; /* The fastest we can go for all channels */
00095         PWMPRCLK = ZEROS; /* The fastest prescaler we can go for all channels */
00096         PWMSCLA = ZEROS; /* The fastest we can go */
00097         PWMSCLB = ZEROS; /* The fastest we can go */
00098         /* TODO PWM channel concatenation for high resolution */
00099         // join channel pairs together here (needs 16 bit regs enabled too)
00100         /* TODO Initialise pwm channels with frequency, and initial duty for real use */
00101         // intitial PWM settings for testing
00102         /* PWM periods */
00103         PWMPER0 = 0xFF; // 255 for ADC0 testing
00104         PWMPER1 = 0xFF; // 255 for ADC1 testing
00105         PWMPER2 = 0xFF; // 255 for ADC1 testing
00106         PWMPER3 = 0xFF; // 255 for ADC1 testing
00107         PWMPER4 = 0xFF; // 255 for ADC1 testing
00108         PWMPER5 = 0xFF; // 255 for ADC1 testing
00109         PWMPER6 = 0xFF; // 255 for ADC1 testing
00110         PWMPER7 = 0xFF; // 255 for ADC1 testing
00111         /* PWM duties */
00112         PWMDTY0 = 0;
00113         PWMDTY1 = 0;
00114         PWMDTY2 = 0;
00115         PWMDTY3 = 0;
00116         PWMDTY4 = 0;
00117         PWMDTY5 = 0;
00118         PWMDTY6 = 0;
00119         PWMDTY7 = 0;
00120 
00121 
00122         /* TODO Set up the SCI0 interface for basic comms here */
00123 
00124 
00125         /* Initialise the state of pins configured as output */
00126         /* Initialise to low such that transistor grounded things are all turned off by default. */
00127         PORTA = ZEROS; /* The serial monitor pin is on 0x40, and could cause problems if capacitance at the output is large when a reset occurs. */
00128         PORTB = ZEROS; /* Init the rest of the spark outputs as off */
00129         PORTE = 0x1F; /* 0b_0001_1111 : when not in use 0b_1001_1111 PE7 should be high PE5 and PE6 should be low, the rest high */
00130         PORTK = ZEROS;
00131         PORTS = ZEROS;
00132         PORTT = ZEROS; /* All pins in off state at boot up (only matters for 2 - 7) */
00133         PORTM = ZEROS;
00134         PORTP = ZEROS; // TODO hook these up to the adc channels such that you can vary the brightness of an led with a pot.
00135         PORTH = ZEROS;
00136         PORTJ = ZEROS;
00137         /* AD0PT1 You are out of your mind if you waste this on digital Inputs */
00138         /* AD1PT1 You are out of your mind if you waste this on digital Inputs */
00139 
00140         /* Initialise the Data Direction Registers */
00141         /* To outputs based on the note at the end of chapter 1.2.2 of MC9S12XDP512V2.pdf */
00142         DDRA = ONES; /* GPIO (8) */
00143         DDRB = ONES; /* GPIO (8) */
00144         DDRE = 0xFC; /* 0b_1111_1100 : Clock and mode pins PE0,PE1 are input only pins, the rest are GPIO */
00145         DDRK = ONES; /* Only 0,1,2,3,4,5,7, NOT 6 (7) */
00146         DDRS = ONES; /* SCI0, SCI1, SPI0 (8) */
00147         DDRT = 0xFC; /* 0b_1111_1100 set ECT pins 0,1 to IC and 2:7 to OC (8) */
00148         DDRM = ONES; /* CAN 0 - 3 (8) */
00149         DDRP = ONES; /* PWM pins (8) */
00150         DDRH = ZEROS; /* All pins configured as input for misc isrs (SPI1, SPI2) (8) */
00151         DDRJ = ONES; /* Only 0,1,6,7 are brought out on the 112 pin chip (4) */
00152         /* Configure the non bonded pins to output to avoid current drain (112 pin package) */
00153         DDRC = ONES; /* NON-bonded external data bus pins */
00154         DDRD = ONES; /* NON-bonded external data bus pins */
00155         /* AD0DDR1 You are out of your mind if you waste this on digital Inputs */
00156         /* AD1DDR1 You are out of your mind if you waste this on digital Inputs */
00157 }
00158 
00159 
00160 void initPagedRam(){
00161         /* Take the tables and config from flash up to RAM.
00162          *
00163          * For the main tables and other paged config we need to adjust
00164          * the RPAGE value to the appropriate one before copying up.
00165          */
00166 
00167         /* Copy the tables up to their paged ram blocks through the window from flash */
00168         RPAGE = RPAGE_FUEL_ONE;
00169         memcpy((void*)&TablesA, (void*)&VETableMainFlash,                                               1024);
00170         memcpy((void*)&TablesB, (void*)&VETableSecondaryFlash,                                  1024);
00171         memcpy((void*)&TablesC, (void*)&VETableTertiaryFlash,                                   1024);
00172         memcpy((void*)&TablesD, (void*)&LambdaTableFlash,                                               1024);
00173         RPAGE = RPAGE_FUEL_TWO;
00174         memcpy((void*)&TablesA, (void*)&VETableMainFlash2,                                              1024);
00175         memcpy((void*)&TablesB, (void*)&VETableSecondaryFlash2,                                 1024);
00176         memcpy((void*)&TablesC, (void*)&VETableTertiaryFlash2,                                  1024);
00177         memcpy((void*)&TablesD, (void*)&LambdaTableFlash2,                                              1024);
00178         RPAGE = RPAGE_TIME_ONE;
00179         memcpy((void*)&TablesA, (void*)&IgnitionAdvanceTableMainFlash,                  1024);
00180         memcpy((void*)&TablesB, (void*)&IgnitionAdvanceTableSecondaryFlash,             1024);
00181         memcpy((void*)&TablesC, (void*)&InjectionAdvanceTableMainFlash,                 1024);
00182         memcpy((void*)&TablesD, (void*)&InjectionAdvanceTableSecondaryFlash,    1024);
00183         RPAGE = RPAGE_TIME_TWO;
00184         memcpy((void*)&TablesA, (void*)&IgnitionAdvanceTableMainFlash2,                 1024);
00185         memcpy((void*)&TablesB, (void*)&IgnitionAdvanceTableSecondaryFlash2,    1024);
00186         memcpy((void*)&TablesC, (void*)&InjectionAdvanceTableMainFlash2,                1024);
00187         memcpy((void*)&TablesD, (void*)&InjectionAdvanceTableSecondaryFlash2,   1024);
00188         RPAGE = RPAGE_TUNE_ONE;
00189         memcpy((void*)&TablesA, (void*)&SmallTablesAFlash,                                              1024);
00190         memcpy((void*)&TablesB, (void*)&SmallTablesBFlash,                                              1024);
00191         memcpy((void*)&TablesC, (void*)&SmallTablesCFlash,                                              1024);
00192         memcpy((void*)&TablesD, (void*)&SmallTablesDFlash,                                              1024);
00193         RPAGE = RPAGE_TUNE_TWO;
00194         memcpy((void*)&TablesA, (void*)&SmallTablesAFlash2,                                             1024);
00195         memcpy((void*)&TablesB, (void*)&SmallTablesBFlash2,                                             1024);
00196         memcpy((void*)&TablesC, (void*)&SmallTablesCFlash2,                                             1024);
00197         memcpy((void*)&TablesD, (void*)&SmallTablesDFlash2,                                             1024);
00198 
00199         /* Default to page one for now, perhaps read the configured port straight out of reset in future? TODO */
00200         setupPagedRAM(TRUE); // probably something like (PORTA & TableSwitchingMask)
00201 
00202         // Set to four locations in page window
00203 //      VETableMain                             = (mainTable*)0x1000;
00204 //      VETableSecondary                = (mainTable*)0x1400;
00205 //      AdvanceTableMain                = (mainTable*)0x1800;
00206 //      AdvanceTableSecondary   = (mainTable*)0x1C00;
00207 //
00208 //      // Over write with locations of flash to ensure the rest works
00209 //      VETableMain                             = (mainTable*)&VETableMainFlash;
00210 //      VETableSecondary                = (mainTable*)&VETableSecondaryFlash;
00211 //      AdvanceTableMain                = (mainTable*)&AdvanceTableMainFlash;
00212 //      AdvanceTableSecondary   = (mainTable*)&AdvanceTableSecondaryFlash;
00213 //      VETableMain                             = &VETableMainFlash;
00214 //      VETableSecondary                = &VETableSecondaryFlash;
00215 //      AdvanceTableMain                = &AdvanceTableMainFlash;
00216 //      AdvanceTableSecondary   = &AdvanceTableSecondaryFlash;  // warning assignment discards qualifiers from pointer target type
00217 
00218 
00219         //      VETableTertiary         = 0x1800;
00220 //      LambdaTable                     = 0x1C00;
00221 }
00222 
00223 void initStats(){
00224         /* This should not be necessary as C defines new vars as 0 on this platform anyway,
00225          * however we'll do it just in case because it's the right thing to do. */
00226 
00227         /* Zero all the counters for various conditions */
00228         Counters.UISRCounter = 0;
00229         Counters.lowVoltISRCounter = 0;
00230         Counters.lostCamSyncCounter = 0;
00231         Counters.lostCrankSyncCounter = 0;
00232         Counters.lostRPMValidityCounter = 0;
00233         Counters.primaryTeethCounter = 0;
00234         Counters.secondaryTeethCounter = 0;
00235         Counters.syncedADCreadingCounter = 0;
00236         Counters.timeoutADCreadingCounter = 0;
00237         Counters.calcsPerformedCounter = 0;
00238         Counters.logsSentCounter = 0;
00239 
00240 
00241         /* Real Time Clocks */
00242         Clocks.millisToTenths = 0;
00243         Clocks.tenthsToSeconds = 0;
00244         Clocks.secondsToMinutes = 0;
00245         Clocks.realTimeClockMain = 0;
00246         Clocks.realTimeClockMillis = 0;
00247         Clocks.realTimeClockTenths = 0;
00248         Clocks.realTimeClockSeconds = 0;
00249         Clocks.realTimeClockMinutes = 0;
00250         Clocks.timeoutADCreadingClock = 0;
00251 
00252 
00253         /* These here for clarity only */
00254 //      Clocks.timerExtensionClock = 0; This does not need to be inited because we do not care what value it has
00255 //      CoreVars.* = 0; These do not need to be inited as they will quickly be overwritten anyway
00256 //      RuntimeVars.* = 0; These do not need to be inited as they will quickly be overwritten anyway
00257 //      ADCArrays.* = 0; These do not need to be inited as they will quickly be overwritten anyway
00258 //      asyncADCArrays.* = 0; These do not need to be inited as they will quickly be overwritten anyway
00259 
00260 }
00261 
00262 /* Initialise and set up some running variables etc here */
00263 void initVariables(){
00264         /* State */
00265         coreStatusA = ZEROS16;                  /* See definitions in freeems.h */
00266         mainOn = ZEROS;
00267         stagedOn = ZEROS;
00268         dwellOn = ZEROS16;
00269         selfSetTimer = ZEROS;
00270         rescheduleFuelFlags = ZEROS;
00271 
00272         // Values for testing
00273         masterPulseWidth = 10;
00274         totalAngleAfterReferenceIgnition = 540;
00275         totalAngleAfterReferenceInjection = 180;
00276 
00277         /* Set the banks to be the same at boot */
00278         recordADCBank = 0;
00279         realTimeUseBank = 0;
00280         realTimeUseInjectionOffset = 0;
00281         realTimeUseIgnitionOffset = 0;
00282         /* And the opposite for the other halves */
00283         mathInputBank = 1;
00284         mathInternalBank = 1;
00285         mathInternalInjectionOffset = INJECTION_CHANNELS;
00286         mathInternalIgnitionOffset = IGNITION_CHANNELS;
00287 
00288         /* Setup the pointers to the registers for fueling use, this does NOT work if done in global.c, I still don't know why. */
00289         injectorMainTimeRegisters[0] = TC2_ADDR;
00290         injectorMainTimeRegisters[1] = TC3_ADDR;
00291         injectorMainTimeRegisters[2] = TC4_ADDR;
00292         injectorMainTimeRegisters[3] = TC5_ADDR;
00293         injectorMainTimeRegisters[4] = TC6_ADDR;
00294         injectorMainTimeRegisters[5] = TC7_ADDR;
00295         injectorMainControlRegisters[0] = TCTL2_ADDR;
00296         injectorMainControlRegisters[1] = TCTL2_ADDR;
00297         injectorMainControlRegisters[2] = TCTL1_ADDR;
00298         injectorMainControlRegisters[3] = TCTL1_ADDR;
00299         injectorMainControlRegisters[4] = TCTL1_ADDR;
00300         injectorMainControlRegisters[5] = TCTL1_ADDR;
00301 
00302         /* Ignition stuff */
00303         dwellQueueLength = 0;
00304         ignitionQueueLength = 0;
00305 
00306         // TODO perhaps read from the ds1302 once at start up and init the values or different ones with the actual time and date then update them in RTI
00307 
00308         // TODO do these require init????
00309         primaryPulsesPerSecondaryPulse = 0;
00310         primaryPulsesPerSecondaryPulseBuffer = 0;
00311         primaryLeadingEdgeTimeStamp = 0;
00312         timeBetweenSuccessivePrimaryPulses = 0;
00313         timeBetweenSuccessivePrimaryPulsesBuffer = 0;
00314         lastPrimaryPulseTimeStamp = 0;
00315         lastSecondaryOddTimeStamp = 0;
00316 
00317         /* Setup so that the tacho reads low when the engine isn't running */
00318         engineCyclePeriod = ticksPerCycleAtOneRPM;
00319 
00320         // TODO remove this : Test stuff
00321         portHDebounce = 0;
00322 }
00323 
00324 /* TODO initialise the flash burning configuration regs */
00325 void initFlash(){
00326         // TBC
00327         unsigned char flashclock;
00328         unsigned short SysClock = 16000;    //TODO see if Fred already specified this var and/or move to configs/constants
00329 
00330         if (SysClock >= 12000){
00331                 flashclock = (unsigned char) (SysClock/8/200 );
00332         }
00333         else{
00334                 flashclock = (unsigned char) (SysClock/200 +1);
00335         }
00336 // TODO FIX SO EQUASION WORKS
00337 //      FCLKDIV = FCLKDIV|flashclock;
00338         FCLKDIV = 0x4A;
00339 
00340         FPROT = 0xFF;  //disable all flash protection
00341         FSTAT = FSTAT|(PVIOL|ACCERR);  //clear any errors
00342 
00343 }
00344 
00345 /* Set up the timer module and its various interrupts */
00346 void initECTTimer(){
00347 
00348         // TODO rearrange the order of this stuff and pull enable and interrupt enable out to the last function call of init.
00349 
00350         /* Timer channel interrupts */
00351         TIE = 0x03; /* 0,1 IC interrupts enabled for reading engine position and RPM, 6 OC channels disabled such that no injector switching happens till scheduled */
00352         TFLG = ONES; /* Clear all the flags such that we are up and running before they first occur */
00353         TFLGOF = ONES; /* Clear all the flags such that we are up and running before they first occur */
00354 
00355         /* TODO Turn the timer on and set the rate and overflow interrupt */
00356         TSCR1 = 0x88; /* 0b_1000_1000 Timer enabled, and precision timer turned on */
00357         TSCR2 = 0x87; /* 0b_1000_0111 Overflow interrupt enable, divide by 256 if precision turned off */
00358 //      PTPSR = 0x03; /* 4 prescaler gives .1uS resolution and max period of 7ms measured */
00359         PTPSR = 0x1F; /* 32 prescaler gives 0.8uS resolution and max period of 52.4288ms measured */
00360 //      PTPSR = 0x3F; /* 64 prescaler gives 1.6uS resolution and max period of 105ms measured */
00361 //      PTPSR = 0xFF; /* 256 prescaler gives 6.4uS resolution and max period of 400ms measured */
00362 //      PTPSR = 0x7F; /* 128 prescaler gives 3.2uS resolution and max period of 200ms measured */
00363         /* http://www.google.com/search?hl=en&safe=off&q=1+%2F+%2840MHz+%2F+32+%29&btnG=Search */
00364         /* http://www.google.com/search?hl=en&safe=off&q=1+%2F+%2840MHz+%2F+32+%29+*+2%5E16&btnG=Search */
00365         /* www.mecheng.adelaide.edu.au/robotics_novell/WWW_Devs/Dragon12/LM4_Timer.pdf */
00366 
00367         /* Initial actions */
00368         TIOS = 0xFC; /* 0b_1111_1100 0 and 1 are input capture, 2 through 7 are output compare */
00369         TCTL1 = ZEROS; /* Set disabled at startup time, use these and other flags to switch fueling on and off inside the decoder */
00370         TCTL2 = ZEROS; /* 0,1 have compare turned off regardless as they are in IC mode. */
00371         TCTL3 = ZEROS; /* Capture off for 4 - 7 */
00372         TCTL4 = 0x0F; /* Capture on both edges of two pins for IC (0,1), capture off for 2,3 */
00373 
00374         // TODO setup delay counters on 0 and 1 to filter noise (nice feature!)
00375         //DLYCT = ??; built in noise filter
00376 
00377         /* Configurable tachometer output */
00378         PTMCPSR = fixedConfigs.tachoTickFactor - 1; // Precision prescaler - fastest is 1 represented by 0, slowest/longest possible is 256 represented by 255 or 0xFF
00379         MCCNT = ONES16; // init to slowest possible, first
00380         MCCTL = 0xC4; // turn on and setup the mod down counter
00381         MCFLG = 0x80; // clear the flag up front
00382 
00383 }
00384 
00385 /* Configure the PIT timers for their various uses. */
00386 void initPITTimer(){
00387         /*  */
00388         // set micro periods
00389         PITMTLD0 = 0x1F; /* 32 prescaler gives 0.8uS resolution and max period of 52.4288ms measured */
00390         PITMTLD1 = 0x1F; /* ditto */
00391         /* http://www.google.com/search?hl=en&safe=off&q=1+%2F+%2840MHz+%2F+32+%29 Exactly the same as for ECT */
00392 
00393         // set timers running
00394 //      PITLD0 = dwellPeriod;
00395         // enable module
00396         PITCFLMT = 0x80;
00397         // enable channels
00398         //PITCE = 0x03;
00399         // enable interrupt
00400 //      PITINTE = 0x01;
00401         // clear flags
00402         //PITFLT = ONES;
00403 }
00404 
00405 /* Setup the sci module(s) that we need to use. */
00406 void initSCIStuff(){
00407         /* The alternative register set selector defaults to zero */
00408 
00409         // set the baud/data speed
00410         SCI0BD = fixedConfigs.baudDivisor;
00411 
00412         // etc
00413 
00414         /* Switch to alternative register set? */
00415 
00416         // etc
00417 
00418         /* Switch back again? */
00419 
00420         /*
00421          * 0 = LOOPS (normal two wire operation)
00422          * 0 = SCISWAI (Wait mode on)
00423          * 0 = RSRC (if loops=1, int/ext wiring)
00424          * 1 = M MODE (9 bit operation)
00425          * 0 = WAKE (idle line wakeup)
00426          * 0 = ILT (idle line type count start pos)
00427          * 1 = PE (parity on)
00428          * 1 = PT (odd parity) (minicom defaults to no parity)
00429          *
00430          * 00010011 = 0x13
00431          */
00432         SCI0CR1 = 0x13;
00433 
00434         /*
00435          * 0 = TIE (tx data empty isr disabled)
00436          * 0 = TCIE (tx complete isr disabled)
00437          * 1 = RIE (rx full isr enabled)
00438          * 0 = ILIE (idle line isr disabled)
00439          * 1 = TE (transmit enabled)
00440          * 1 = RE (receive enabled)
00441          * 0 = RWU (rx wake up normal)
00442          * 0 = SBK (send break off)
00443          *
00444          * 00101100 = 0x2C
00445          */
00446         SCI0CR2 = 0x2C;
00447 }
00448 
00449 /* TODO Load and calculate all configuration data required to run */
00450 void initConfiguration(){
00451 //      // TODO Calc TPS ADC range on startup or every time? this depends on whether we ensure that things work without a re init or reset or not.
00452 
00453 
00454         /* Add in tunable physical parameters at boot time TODO move to init.c TODO duplicate for secondary fuel? or split somehow?
00455          *nstant = ((masterConst * perCylinderVolume) / (stoichiometricAFR * injectorFlow));
00456          *nstant = ((139371764   * 16384                        ) / (15053                         * 4096                ));
00457          * OR
00458          *nstant = ((masterConst / injectorFlow) * perCylinderVolume) / stoichiometricAFR;
00459          *nstant = ((139371764   / 4096            ) * 16384                    ) / 15053                        ;
00460          * http://www.google.com/search?hl=en&safe=off&q=((139371764++%2F+4096+++++)+*+16384+++)+%2F+15053++++&btnG=Search */
00461         bootFuelConst = ((unsigned long)(masterFuelConstant / fixedConfigs.injectorFlow) * fixedConfigs.perCylinderVolume) / fixedConfigs.stoichiometricAFR;
00462 
00463         /* The MAP range used to convert fake TPS from MAP and vice versa */
00464         TPSMAPRange = fixedConfigs.TPSOpenMAP - fixedConfigs.TPSClosedMAP;
00465 
00466         /* The ADC range used to generate TPS percentage */
00467         TPSADCRange = fixedConfigs.TPSMaximumADC - fixedConfigs.TPSMinimumADC;
00468 
00469 
00470         /* Use like flags for now, just add one for each later */
00471         unsigned char cumulativeConfigErrors = 0;
00472 
00473         /* Check various aspects of config which will cause problems */
00474 
00475         /* BRV max bigger than variable that holds it */
00476         if(((unsigned long)fixedConfigs.BRVMinimum + fixedConfigs.BRVRange) > 65535){
00477                 //sendError(BRV_MAX_TOO_LARGE);
00478                 cumulativeConfigErrors++;
00479         }
00480 
00481         /* Check lengths of main VE table TODO refactor into function for all main tables! */
00482         if((VETableMainFlash.LoadLength * VETableMainFlash.RPMLength) > MAINTABLE_MAX_MAIN_LENGTH){
00483                 //sendError(VE_TABLE_MAIN_MAIN_LENGTH_TOO_LONG);
00484                 cumulativeConfigErrors += 2;
00485         }
00486         if(VETableMainFlash.LoadLength > MAINTABLE_MAX_LOAD_LENGTH){
00487                 //sendError(VE_TABLE_MAIN_LOAD_LENGTH_TOO_LONG);
00488                 cumulativeConfigErrors += 4;
00489         }
00490         if(VETableMainFlash.RPMLength > MAINTABLE_MAX_RPM_LENGTH){
00491                 //sendError(VE_TABLE_MAIN_RPM_LENGTH_TOO_LONG);
00492                 cumulativeConfigErrors += 8;
00493         }
00494         // TODO factor the above out.
00495 
00496         // TODO check all table sizes and other critical variables here!
00497 
00498         /*
00499          * check ignition settings for range etc, possibly check some of those on the fly too
00500          * check fuel settings for being reasonable
00501          * check all variable tables for correct sizing
00502          * etc
00503          */
00504 
00505         while(cumulativeConfigErrors > 0){
00506                 sleep(1000);
00507                 PORTS_BA ^= ONES16; // flash leds
00508                 //send("There were ");
00509                 //sendUC(cumulativeConfigErrors);
00510                 //send(" config errors, init aborted!");
00511         } // TODO ensure that we can recieve config and settings via serial while this is occuring! If not a bad config will lock us out all together.
00512 }
00513 
00514 
00515 /* Set up all the remaining interrupts */
00516 void initInterrupts(){
00517         /* IMPORTANT : Set the s12x vector base register (Thanks Karsten!!) */
00518         IVBR = 0xF7; /* Without this the interrupts will never find your code! */
00519 
00520         /* Set up the Real Time Interrupt */
00521         RTICTL = 0x81; /* 0b_1000_0001 0.125ms/125us period http://www.google.com/search?hl=en&safe=off&q=1+%2F+%2816MHz+%2F+%282+*+10%5E3%29+%29&btnG=Search */
00522 //      RTICTL = 0xF9; /* 0b_1111_1001 0.125s/125ms period http://www.google.com/search?hl=en&safe=off&q=1+%2F+%2816MHz+%2F+%282*10%5E6%29+%29&btnG=Search */
00523         CRGINT |= 0x80; /* Enable the RTI */
00524         CRGFLG = 0x80; /* Clear the RTI flag */
00525 
00526         // set up port H for testing
00527         PPSH = ZEROS; // falling edge/pull up for all
00528         PIEH = ONES; // enable all pins interrupts
00529         PIFH = ONES; // clear all port H interrupt flags
00530 
00531         // TODO set up irq and xirq for testing
00532         // IRQCR for IRQ
00533         //
00534 
00535         /* VReg API setup (only for wait mode? i think so) */
00536 //      VREGAPIR = 0x09C3; /* For 500ms period : (500ms - 0.2ms) / 0.2ms = 0b100111000011 = 2499 */
00537 //      VREGAPICL = 0x02; /* Enable the interrupt */
00538 //      VREGAPICL = 0x04; /* Start the counter running */
00539         /* Writing a one to the flag will set it if it is unset, so best not to mess with it here as it probably starts off unset */
00540 
00541         /* LVI Low Voltage Interrupt enable */
00542         VREGCTRL = 0x02; // Counts bad power events for diagnosis reasons
00543 }
00544 
00545 /* Main init function to be called from main.c before enterring the main loop */
00546 void init(){
00547         ATOMIC_START();                 /* Disable ALL interrupts while we configure the board ready for use */
00548         initPLL();                              /* Set up the PLL and use it */
00549         checkChecksum();                /* TODO maybe checksum the code base excluding the areas of flash used for tuning data OR, include the tuning data and write a checksum in with it each time. display a warning via tacho, shiftlights, etc if stuffed. */
00550         initIO();                               /* TODO make this config dependent. Set up all the pins and modules to be in low power harmless states */
00551         initPagedRam();                 /* Copy table and config blocks of data from flash to the paged ram blocks for fast data lookup */
00552         initStats();                    /* Initialise all statistics variables */
00553         initVariables();                /* Initialise the rest of the running variables etc */
00554         initFlash();                    /* TODO, populate */
00555         initECTTimer();                 /* TODO move this to inside config in an organised way. Set up the timer module and its various aspects */
00556         initPITTimer();                 /* TODO ditto... */
00557         initSCIStuff();                 /* Setup the sci module(s) that we will use. */
00558         initConfiguration();    /* TODO Set user/feature/config up here! */
00559         initInterrupts();               /* still last, reset timers, enable interrupts here TODO move this to inside config in an organised way. Set up the rest of the individual interrupts */
00560         ATOMIC_END(); /* Re-enable any configured interrupts */
00561 }

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