interrupts.h File Reference

All interrupt handler declarations. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define INT   __attribute__((interrupt))
#define ATOMIC_START()   __asm__ __volatile__ ("sei")
#define ATOMIC_END()   __asm__ __volatile__ ("cli")
#define VECTORS   __attribute__ ((section (".vectors")))

Typedefs

typedef void(* interruptTable )(void)

Functions

void _start (void)
void UISR (void) INT TEXT1
 Unimplemented Interrupt Handler.
void Injector1ISR (void) INT TEXT1
void Injector2ISR (void) INT TEXT1
void Injector3ISR (void) INT TEXT1
void Injector4ISR (void) INT TEXT1
void Injector5ISR (void) INT TEXT1
void Injector6ISR (void) INT TEXT1
void PrimaryRPMISR (void) INT TEXT1
void SecondaryRPMISR (void) INT TEXT1
 Use the rising and falling edges...................
void TimerOverflow (void) INT TEXT1
 ECT overflow handler.
void ModDownCtrISR (void) INT TEXT1
 Tacho pulse generator.
void IgnitionDwellISR (void) INT TEXT1
 Ignition dwell control.
void IgnitionFireISR (void) INT TEXT1
 Ignition discharge control.
void StagedOnISR (void) INT TEXT1
void StagedOffISR (void) INT TEXT1
void PortPISR (void) INT TEXT1
 Port P pins ISR.
void PortHISR (void) INT TEXT1
 Port H pins ISR.
void PortJISR (void) INT TEXT1
 Port J pins ISR.
void IRQISR (void) INT TEXT1
 IRQ/PE1 pin ISR.
void XIRQISR (void) INT TEXT1
 XIRQ/PE0 pin ISR.
void RTIISR (void) INT TEXT1
 Real Time Interrupt Handler.
void SCI0ISR (void) INT TEXT1
 Serial Communication Interface 0 ISR.
void LowVoltageISR (void) INT TEXT1
 Low Voltage Counter.
void VRegAPIISR (void) INT TEXT1


Detailed Description

All interrupt handler declarations.

All of the declarations for ISR functions are done here because they are all used in one place and it doesn't make sense to spread them out over N files for N functions. ISR headers only exist where there is a requirement for local variables and constants etc.

Author:
Fred Cooke

Definition in file interrupts.h.


Define Documentation

 
#define ATOMIC_END (  )     __asm__ __volatile__ ("cli")

Definition at line 58 of file interrupts.h.

Referenced by init(), and main().

 
#define ATOMIC_START (  )     __asm__ __volatile__ ("sei")

Definition at line 57 of file interrupts.h.

Referenced by init(), and main().

#define INT   __attribute__((interrupt))

Definition at line 50 of file interrupts.h.

#define VECTORS   __attribute__ ((section (".vectors")))

Definition at line 61 of file interrupts.h.


Typedef Documentation

typedef void(* interruptTable)(void)

Definition at line 99 of file interrupts.h.


Function Documentation

void _start ( void   ) 

void IgnitionDwellISR ( void   ) 

Ignition dwell control.

This function turns ignition pins on to dwell when required.

Author:
Fred Cooke
Todo:
TODO make this actually work.

Definition at line 72 of file ignitionISRs.c.

References engineSetting::combustionEventsPerEngineCycle, DWELL_DISABLE, DWELL_ENABLE, dwellQueueLength, dwellStartMasks, fixedConfig1::engineSettings, fixedConfigs1, nextDwellChannel, PITCE, PITINTE, PITLD0, PITTF, PORTS, PORTS_BA, and queuedDwellOffsets.

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 }

void IgnitionFireISR ( void   ) 

Ignition discharge control.

This function turns ignition pins off to discharge when required.

Author:
Fred Cooke
Todo:
TODO make this actually work.

Definition at line 122 of file ignitionISRs.c.

References engineSetting::combustionEventsPerEngineCycle, fixedConfig1::engineSettings, fixedConfigs1, IGNITION_DISABLE, IGNITION_ENABLE, ignitionMasks, ignitionQueueLength, nextIgnitionChannel, PITCE, PITINTE, PITLD0, PITTF, PORTS, PORTS_BA, and queuedIgnitionOffsets.

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 }

void Injector1ISR ( void   ) 

void Injector2ISR ( void   ) 

void Injector3ISR ( void   ) 

void Injector4ISR ( void   ) 

void Injector5ISR ( void   ) 

void Injector6ISR ( void   ) 

void IRQISR ( void   ) 

IRQ/PE1 pin ISR.

Interrupt handler for edge events on the IRQ/PE1 pin. Not currently used.

Author:
Fred Cooke

Definition at line 202 of file miscISRs.c.

References Counter::callsToUISRs, and Counters.

00202                  {
00203     /* Clear the flag */
00204     // ?? TODO
00205 
00206     /* Increment the unimplemented ISR execution counter */
00207     Counters.callsToUISRs++;
00208 }

void LowVoltageISR ( void   ) 

Low Voltage Counter.

Count how often our voltage drops lower than it should without resetting.

Author:
Fred Cooke

Definition at line 232 of file miscISRs.c.

References Counters, Counter::lowVoltageConditions, and VREGCTRL.

00232                         {
00233     /* Clear the flag */
00234     VREGCTRL |= 0x01;
00235 
00236     /* Increment the counter */
00237     Counters.lowVoltageConditions++;
00238 }

void ModDownCtrISR ( void   ) 

Tacho pulse generator.

Currently this is being used to generate a variable frequency tachometer output. Although this is a bit of a waste of a timer resource it does allow tachometers that were intended for engines with a different cylinder count to be used where it would otherwise not be possible.

Author:
Fred Cooke

Definition at line 148 of file realtimeISRs.c.

References engineCyclePeriod, fixedConfigs1, MCCNT, MCFLG, PORTA, tachoPeriod, fixedConfig1::tachoSettings, tachoSetting::tachoTotalFactor, and ticksPerCycleAtOneRPM.

00148                     {
00149     /* Clear the modulus down counter interrupt flag */
00150     MCFLG = 0x80;
00151 
00152     /* If the rpm isn't genuine go ultra slow */
00153     if(engineCyclePeriod == ticksPerCycleAtOneRPM){
00154         tachoPeriod = 65535;
00155     }else{
00156         /* Use engine cycle period to setup the frequency of this counter and thereby act as a tacho out */
00157         tachoPeriod = (unsigned long)engineCyclePeriod / fixedConfigs1.tachoSettings.tachoTotalFactor;
00158     }
00159     /* Set the count down value */
00160     MCCNT = tachoPeriod;
00161 
00162     /* Bit bang the output port */
00163     PORTA ^= 0x40; // SM pin (A6)
00164 }

void PortHISR ( void   ) 

Port H pins ISR.

Interrupt handler for edge events on port H pins. Not currently used.

Author:
Fred Cooke

Definition at line 89 of file miscISRs.c.

References ONES, PIFH, PORTA, and portHDebounce.

00090 {
00091 //  // read the interrupt flags to a variable
00092 //  unsigned char portHFlags = PIFH;
00093 //  portHFlags &= 0xF8; // mask out the other bits
00094 //
00095 //  /* Clear all port H flags (we only want one at a time) */
00096     PIFH = ONES;
00097 //
00098 //  // Toggle a LED so we can see if the code ran
00099     PORTA ^= 0x80; // Fuel pump pin (A7)
00100 //
00101     // debounce
00102     if(portHDebounce == 0){
00103         portHDebounce = 2;
00104     }else{
00105         return;
00106     }
00107 //
00108 //  // find out which pin triggered it, clear the flag, perform the action.
00109 //  switch(portHFlags)
00110 //  {
00111 //  case 0x80 : // Increment cylinder count and set port count appropriately.
00112 //      switch (configs.combustionEventsPerEngineCycle) {
00113 //          case 1 :
00114 //              configs.combustionEventsPerEngineCycle = 2;
00115 //              configs.ports = 2;
00116 //              break;
00117 //          case 2 :
00118 //              configs.combustionEventsPerEngineCycle = 3;
00119 //              configs.ports = 3;
00120 //              break;
00121 //          case 3 :
00122 //              configs.combustionEventsPerEngineCycle = 4;
00123 //              configs.ports = 4;
00124 //              break;
00125 //          case 4 :
00126 //              configs.combustionEventsPerEngineCycle = 5;
00127 //              configs.ports = 5;
00128 //              break;
00129 //          case 5 :
00130 //              configs.combustionEventsPerEngineCycle = 6;
00131 //              configs.ports = 6;
00132 //              break;
00133 //          case 6 :
00134 //              configs.combustionEventsPerEngineCycle = 8;
00135 //              configs.ports = 4;
00136 //              break;
00137 //          case 8 :
00138 //              configs.combustionEventsPerEngineCycle = 10;
00139 //              configs.ports = 5;
00140 //              break;
00141 //          case 10 :
00142 //              configs.combustionEventsPerEngineCycle = 12;
00143 //              configs.ports = 6;
00144 //              break;
00145 //          case 12 :
00146 //              configs.combustionEventsPerEngineCycle = 1;
00147 //              configs.ports = 1;
00148 //              break;
00149 //      }
00150 //      break;
00151 //  case 0x40 : // Injection output enable/disable
00152 //      if(coreSettingsA & FUEL_CUT){
00153 //          coreSettingsA &= FUEL_CUT_OFF;
00154 //      }else{
00155 //          coreSettingsA |= FUEL_CUT;
00156 //      }
00157 //      break;
00158 //  case 0x20 : // Ignition output enable/disable
00159 //      if(coreSettingsA & HARD_SPARK_CUT){
00160 //          coreSettingsA &= HARD_SPARK_CUT_OFF;
00161 //      }else{
00162 //          coreSettingsA |= HARD_SPARK_CUT;
00163 //      }
00164 //      break;
00165 //  case 0x10 : // Staged injection enable/disable
00166 //      if(coreSettingsA & STAGED_ON){
00167 //          coreSettingsA &= STAGED_OFF;
00168 //      }else{
00169 //          coreSettingsA |= STAGED_ON;
00170 //      }
00171 //      break;
00172 //  case 0x08 : // Staged injection start sched/fixed
00173 //      if(coreSettingsA & STAGED_START){
00174 //          coreSettingsA &= CLEAR_STAGED_START;
00175 //      }else{
00176 //          coreSettingsA |= STAGED_START;
00177 //      }
00178 //      break;
00179 //  case 0x04 : // Staged injection end sched/fixed
00180 //      if(coreSettingsA & STAGED_END){
00181 //          coreSettingsA &= CLEAR_STAGED_END;
00182 //      }else{
00183 //          coreSettingsA |= STAGED_END;
00184 //      }
00185 //      break;
00186 //  case 0x02 : // free input
00187 //      break;
00188 //  case 0x01 : // free input
00189 //      break;
00190 //  default : // Two or more pressed, nothing to do except wait for another button press
00191 //      break;
00192 //  }
00193 }

void PortJISR ( void   ) 

Port J pins ISR.

Interrupt handler for edge events on port J pins. Not currently used.

Author:
Fred Cooke

Definition at line 75 of file miscISRs.c.

References Counter::callsToUISRs, Counters, ONES, and PIFJ.

00075                    {
00076     /* Clear all port H flags (we only want one at a time) */
00077     PIFJ = ONES;
00078     /* Increment the unimplemented ISR execution counter */
00079     Counters.callsToUISRs++;
00080 }

void PortPISR ( void   ) 

Port P pins ISR.

Interrupt handler for edge events on port P pins. Not currently used.

Author:
Fred Cooke

Definition at line 61 of file miscISRs.c.

References Counter::callsToUISRs, Counters, ONES, and PIFP.

00061                    {
00062     /* Clear all port P flags (we only want one at a time) */
00063     PIFP = ONES;
00064     /* Increment the unimplemented ISR execution counter */
00065     Counters.callsToUISRs++;
00066 }           /* Port P interrupt service routine */

void PrimaryRPMISR ( void   ) 

Primary RPM ISR

Todo:
TODO Docs here!

Primary RPM ISR

Todo:
TODO Docs here!

Primary RPM ISR

Todo:
TODO Docs here!

Primary RPM ISR

Summary of intended engine position capture scheme (out of date as at 3/1/09)

Position/RPM signal interpretation : Discard edges that have arrived too soon (lose sync here?) Check to ensure we haven't lost sync (pulse arrives too late) Compare time stamps of successive edges and calculate RPM Store RPM and position in globals

Schedule events : loop through all events (spark and fuel), schedule those that fall sufficiently after this tooth and before the next one we expect.

Sample ADCs : Grab a unified set of ADC readings at one time in a consistent crank location to eliminate engine cycle dependent noise. Set flag stating that New pulse, advance, etc should be calculated.

Author:
Fred Cooke
Warning:
These are for testing and demonstration only, not suitable for driving with just yet.
Todo:
TODO bring the above docs up to date with reality

TODO finish this off to a usable standard

Primary RPM ISR

Todo:
TODO Docs here!

Todo:
TODO fill in or remove the else

Definition at line 62 of file LT1-360-8.c.

References ADCArrays, CALC_FUEL_IGN, CLEAR_PRIMARY_SYNC, Clocks, engineSetting::combustionEventsPerEngineCycle, fixedConfig1::coreSettingsA, coreStatusA, Counters, Counter::crankSyncLosses, DWELL_ENABLE, dwellQueueLength, engineCyclePeriod, fixedConfig1::engineSettings, fixedConfigs1, IGNITION_ENABLE, ignitionQueueLength, injectorMainControlRegisters, injectorMainEnableMasks, injectorMainEndTimes, injectorMainOnMasks, injectorMainPulseWidthsRealtime, injectorMainStartTimesHolding, injectorMainTimeRegisters, injectorMinimumPulseWidth, injectorSwitchOffCodeTime, ISRLatencyVars, isSynced, lastPrimaryPulseTimeStamp, LONGHALF, masterPulseWidth, mathSampleTimeStampRecord, nextDwellChannel, nextIgnitionChannel, PITCE, PITCNT0, PITCNT1, PITINTE, PITLD0, PITLD1, PITTF, PORTJ, PRIMARY_POLARITY, PRIMARY_SYNC, ISRLatencyVar::primaryInputLatency, RuntimeVar::primaryInputLeadingRuntime, RuntimeVar::primaryInputTrailingRuntime, primaryLeadingEdgeTimeStamp, primaryPulsesPerSecondaryPulse, primaryTeethDroppedFromLackOfSync, PrimaryTeethDuringHigh, PrimaryTeethDuringLow, Counter::primaryTeethSeen, PTIT, queuedDwellOffsets, queuedIgnitionOffsets, RPMRecord, RuntimeVars, sampleBlockADC(), selfSetTimer, Counter::syncedADCreadings, TC0, TCNT, TFLG, TFLGOF, ticksPerCycleAtOneRPMx2, TIE, timeBetweenSuccessivePrimaryPulses, timeBetweenSuccessivePrimaryPulsesBuffer, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, totalAngleAfterReferenceInjection, and trailingEdgeSecondaryRPMInputCodeTime.

00062                         {
00063     /* Clear the interrupt flag for this input compare channel */
00064     TFLG = 0x01;
00065 
00066     /* Save all relevant available data here */
00067 //  unsigned short codeStartTimeStamp = TCNT;       /* Save the current timer count */
00068 //  unsigned short edgeTimeStamp = TC0;             /* Save the edge time stamp */
00069     unsigned char PTITCurrentState = PTIT;          /* Save the values on port T regardless of the state of DDRT */
00070 //  unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */
00071 
00072 //  unsigned char risingEdge; /* in LT1s case risingEdge means signal is high */
00073 //  if(fixedConfigs1.coreSettingsA & PRIMARY_POLARITY){
00074 //      risingEdge = PTITCurrentState & 0x01;
00075 //  }else{
00076 //      risingEdge = !(PTITCurrentState & 0x01);
00077 //  }
00078 
00079     PORTJ |= 0x80; /* Echo input condition on J7 */
00080     if(!isSynced){  /* If the CAS is not in sync get window counts so SecondaryRPMISR can set position */
00081         if (PTITCurrentState & 0x02){
00082             PrimaryTeethDuringHigh++;  /* if low resolution signal is high count number of pulses */
00083         }else{
00084             PrimaryTeethDuringLow++;  /* if low resolution signal is low count number of pulses */
00085         }
00086     }else{ /* The CAS is synced and we need to update our 360/5=72 tooth wheel */
00088     }
00089 }

Here is the call graph for this function:

void RTIISR ( void   ) 

Real Time Interrupt Handler.

Handles time keeping, including all internal clocks, and generic periodic tasks that run quickly and must be done on time.

Author:
Fred Cooke

Definition at line 52 of file realtimeISRs.c.

References Clocks, coreStatusA, CRGFLG, fixedConfigs2, FORCE_READING, Clock::millisToTenths, portHDebounce, PORTP, sensorSetting::readingTimeout, Clock::realTimeClockMain, Clock::realTimeClockMillis, Clock::realTimeClockMinutes, Clock::realTimeClockSeconds, Clock::realTimeClockTenths, RuntimeVar::RTCRuntime, RuntimeVars, Clock::secondsToMinutes, fixedConfig2::sensorSettings, ShouldSendLog, TCNT, Clock::tenthsToSeconds, Clock::timeoutADCreadingClock, and TRUE.

00052              {
00053     /* Clear the RTI flag */
00054     CRGFLG = 0x80;
00055 
00056     /* Record time stamp for code run time reporting */
00057     unsigned short startTimeRTI = TCNT;
00058 
00059     /* Increment the counter */
00060     Clocks.realTimeClockMain++;
00061 
00062     /* This function could be performed without the extra variables by rolling over the main ones at the largest multiples of the next ones, but I'm not sure thats better */
00063 
00064     // TODO add content to eighths of a milli RTC ?
00065 
00066     /* Every 8th RTI execution is one milli */
00067     if(Clocks.realTimeClockMain % 8 == 0){
00068         /* Increment the milli counter */
00069         Clocks.realTimeClockMillis++;
00070 
00071         /* Increment the milli roll over variable */
00072         Clocks.millisToTenths++;
00073 
00074         /* Perform all tasks that are once per millisecond here or preferably main */
00075         Clocks.timeoutADCreadingClock++;
00076         if(Clocks.timeoutADCreadingClock > fixedConfigs2.sensorSettings.readingTimeout){
00077             /* Set force read adc flag */
00078             coreStatusA |= FORCE_READING;
00079             Clocks.timeoutADCreadingClock = 0;
00080         }
00081 
00082         /* Every 100 millis is one tenth */
00083         if(Clocks.millisToTenths % 100 == 0){
00084             /* Increment the tenths counter */
00085             Clocks.realTimeClockTenths++;
00086 
00087             /* Increment the tenths roll over variable */
00088             Clocks.tenthsToSeconds++;
00089 
00090             /* Reset the millis roll over variable */
00091             Clocks.millisToTenths = 0;
00092 
00093             /* Perform all tasks that are once per tenth of a second here or preferably main */
00094             // decrement port H debounce variable till it's zero again.
00095             if(portHDebounce != 0){
00096                 portHDebounce -= 1;
00097             }
00098 
00099             /* Every 10 tenths is one second */
00100             if(Clocks.tenthsToSeconds % 10 == 0){
00101                 /* Increment the seconds counter */
00102                 Clocks.realTimeClockSeconds++;
00103 
00104                 /* Increment the seconds roll over variable */
00105                 Clocks.secondsToMinutes++;
00106 
00107                 /* Reset the tenths roll over variable */
00108                 Clocks.tenthsToSeconds = 0;
00109                 /* Perform all tasks that are once per second here or preferably main */
00110 
00111                 // temp throttling for log due to tuner performance issues (in the bedroom)
00112                 ShouldSendLog = TRUE;
00113                 /* Flash the user LED as a "heartbeat" to let new users know it's alive */
00114                 PORTP ^= 0x80;
00115 
00116                 /* Every 60 seconds is one minute, 65535 minutes is enough for us :-) */
00117                 if(Clocks.secondsToMinutes % 60 == 0){
00118                     /* Increment the minutes counter */
00119                     Clocks.realTimeClockMinutes++;
00120 
00121                     /* Potentially put an hours field in here and below, but that would be excessive */
00122                     // TODO add hours RTC ?
00123 
00124                     /* Reset the seconds roll over variable */
00125                     Clocks.secondsToMinutes = 0;
00126 
00127                     /* Perform all tasks that are once per minute here or preferably main */
00128                     // TODO add content in minutes RTC ?
00129 
00130                     /* Hours if statement here if we do hours which we probably won't */
00131                 }
00132             }
00133         }
00134     }
00135     RuntimeVars.RTCRuntime = TCNT - startTimeRTI;
00136 }

void SCI0ISR ( void   ) 

Serial Communication Interface 0 ISR.

SCI0 ISR handles all interrupts for SCI0 by reading flags and acting appropriately. Its functions are to send raw bytes out over the wire from a buffer and to receive bytes from the wire un-escape them, checksum them and store them in a buffer.

Author:
Fred Cooke
Todo:
TODO Move this code into an include file much like the fuel interrupts such that it can be used for multiple UART SCI devices without duplication.

TODO Remove the debug code that uses the IO ports to light LEDs during specific actions.

Definition at line 147 of file commsISRs.c.

References BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, CLEAR_ALL_SOURCE_ID_FLAGS, COM_CLEAR_SCI0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, Counter::commsChecksumMismatches, Counters, ESCAPE_BYTE, ESCAPED_ESCAPE_BYTE, ESCAPED_START_BYTE, ESCAPED_STOP_BYTE, PORTA, PORTB, receiveAndIncrement(), resetReceiveState(), RuntimeVars, RX_BUFFER_SIZE, RX_READY_TO_PROCESS, RX_SCI_ESCAPED_NEXT, RX_SCI_NOT_ESCAPED_NEXT, RXBufferContentSourceID, RXBufferCurrentPosition, RXCalculatedChecksum, RXPacketLengthReceived, RXStateFlags, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_RX_DISABLE, SCICR2_RX_ISR_DISABLE, SCICR2_RX_ISR_ENABLE, SCICR2_TX_ISR_DISABLE, SCICR2_TX_ISR_ENABLE, SCISR1_RX_FRAMING, SCISR1_RX_NOISE, SCISR1_RX_OVERRUN, SCISR1_RX_PARITY, SCISR1_RX_REGISTER_FULL, SCISR1_TX_REGISTER_EMPTY, sendAndIncrement(), Counter::serialEscapePairMismatches, Counter::serialFramingErrors, RuntimeVar::serialISRRuntime, Counter::serialNoiseErrors, Counter::serialOverrunErrors, Counter::serialPacketsOverLength, Counter::serialParityErrors, Counter::serialStartsInsideAPacket, START_BYTE, STOP_BYTE, TCNT, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, TXByteEscaped, and TXPacketLengthToSendSCI0.

00147               {
00148     /* Read the flags register */
00149     unsigned char flags = SCI0SR1;
00150     /* Note: Combined with reading or writing the data register this also clears the flags. */
00151 
00152     /* Start counting */
00153     unsigned short start = TCNT;
00154 
00155     /* If the RX interrupt is enabled check RX related flags */
00156     if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){
00157         /* Grab the received byte from the register */
00158         unsigned char rawByte = SCI0DRL;
00159 
00160         PORTB |= BIT0;
00161 
00162         /* Record error conditions always */
00163         unsigned char resetOnError = 0;
00164         /* If there is noise on the receive line record it */
00165         if(flags & SCISR1_RX_NOISE){
00166             Counters.serialNoiseErrors++;
00167             resetOnError++;
00168         }/* If an overrun occurs record it */
00169         if(flags & SCISR1_RX_OVERRUN){
00170             Counters.serialOverrunErrors++;
00171             resetOnError++;
00172         }/* If a framing error occurs record it */
00173         if(flags & SCISR1_RX_FRAMING){
00174             Counters.serialFramingErrors++;
00175             resetOnError++;
00176         }/* If a parity error occurs record it */
00177         if(flags & SCISR1_RX_PARITY){
00178             Counters.serialParityErrors++;
00179             resetOnError++;
00180         }
00181 
00182         /* Drop out because of error flags  */
00183         if(resetOnError){
00184             resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00185             PORTB |= BIT1;
00186             return;
00187         }
00188 
00189         /* If there is data waiting to be received */
00190         if(flags & SCISR1_RX_REGISTER_FULL){
00191             PORTB |= BIT2;
00192             /* Look for a start bresetReceiveStateyte to indicate a new packet */
00193             if(rawByte == START_BYTE){
00194                 PORTB |= BIT3;
00195                 /* If another interface is using it (Note, clear flag, not normal) */
00196                 if(RXBufferContentSourceID & COM_CLEAR_SCI0_INTERFACE_ID){
00197                     /* Turn off our reception */
00198                     SCI0CR2 &= SCICR2_RX_DISABLE;
00199                     SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
00200                     PORTB |= BIT4;
00201                 }else{
00202                     PORTB |= BIT5;
00203                     /* If we are using it */
00204                     if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){
00205                         /* Increment the counter */
00206                         Counters.serialStartsInsideAPacket++;
00207                     }
00208                     /* Reset to us using it unless someone else was */
00209                     resetReceiveState(COM_SET_SCI0_INTERFACE_ID);
00210                 }
00211             }else if(RXPacketLengthReceived >= RX_BUFFER_SIZE){
00212                 /* Buffer was full, record and reset */
00213                 Counters.serialPacketsOverLength++;
00214                 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00215                 PORTB |= BIT6;
00216             }else if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){
00217                 if(RXStateFlags & RX_SCI_ESCAPED_NEXT){
00218                     PORTB |= BIT7;
00219                     /* Clear escaped byte next flag, thanks Karsten! ((~ != !) == (! ~= ~)) == LOL */
00220                     RXStateFlags &= RX_SCI_NOT_ESCAPED_NEXT;
00221 
00222                     if(rawByte == ESCAPED_ESCAPE_BYTE){
00223                         /* Store and checksum escape byte */
00224                         receiveAndIncrement(ESCAPE_BYTE);
00225                     }else if(rawByte == ESCAPED_START_BYTE){
00226                         /* Store and checksum start byte */
00227                         receiveAndIncrement(START_BYTE);
00228                     }else if(rawByte == ESCAPED_STOP_BYTE){
00229                         /* Store and checksum stop byte */
00230                         receiveAndIncrement(STOP_BYTE);
00231                     }else{
00232                         /* Otherwise reset and record as data is bad */
00233                         resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00234                         Counters.serialEscapePairMismatches++;
00235                     }
00236                 }else if(rawByte == ESCAPE_BYTE){
00237                     PORTA |= BIT0;
00238                     /* Set flag to indicate that the next byte should be un-escaped. */
00239                     RXStateFlags |= RX_SCI_ESCAPED_NEXT;
00240                 }else if(rawByte == STOP_BYTE){
00241                     PORTA |= BIT1;
00242                     /* Turn off reception */
00243                     SCI0CR2 &= SCICR2_RX_DISABLE;
00244                     SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
00245 
00246                     /* Bring the checksum back to where it should be */
00247                     unsigned char RXReceivedChecksum = (unsigned char)*(RXBufferCurrentPosition - 1);
00248                     RXCalculatedChecksum -= RXReceivedChecksum;
00249 
00250                     /* Check that the checksum matches */
00251                     if(RXCalculatedChecksum == RXReceivedChecksum){
00252                         /* If it's OK set process flag */
00253                         RXStateFlags |= RX_READY_TO_PROCESS;
00254                         PORTA |= BIT2;
00255                     }else{
00256                         PORTA |= BIT3;
00257                         /* Otherwise reset the state and record it */
00258                         resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00259                         Counters.commsChecksumMismatches++;
00260                     }
00261                 }else{
00262                     PORTA |= BIT4;
00263                     /* If it isn't special process it! */
00264                     receiveAndIncrement(rawByte);
00265                 }
00266             }else{
00267                 /* Do nothing : drop the byte */
00268                 PORTA |= BIT5;
00269             }
00270         }
00271     }
00272 
00273     /* If the TX interrupt is enabled check the register empty flag. */
00274     if((SCI0CR2 & SCICR2_TX_ISR_ENABLE) && (flags & SCISR1_TX_REGISTER_EMPTY)){
00275         /* Get the byte to be sent from the buffer */
00276         unsigned char rawValue = *TXBufferCurrentPositionSCI0;
00277 
00278         if(TXPacketLengthToSendSCI0 > 0){
00279             if(TXByteEscaped == 0){
00280                 /* If the raw value needs to be escaped */
00281                 if(rawValue == ESCAPE_BYTE){
00282                     SCI0DRL = ESCAPE_BYTE;
00283                     TXByteEscaped = ESCAPED_ESCAPE_BYTE;
00284                 }else if(rawValue == START_BYTE){
00285                     SCI0DRL = ESCAPE_BYTE;
00286                     TXByteEscaped = ESCAPED_START_BYTE;
00287                 }else if(rawValue == STOP_BYTE){
00288                     SCI0DRL = ESCAPE_BYTE;
00289                     TXByteEscaped = ESCAPED_STOP_BYTE;
00290                 }else{ /* Otherwise just send it */
00291                     sendAndIncrement(rawValue);
00292                 }
00293             }else{
00294                 sendAndIncrement(TXByteEscaped);
00295                 TXByteEscaped = 0;
00296             }
00297         }else{ /* Length is zero */
00298             /* Turn off transmission interrupt */
00299             SCI0CR2 &= SCICR2_TX_ISR_DISABLE;
00300             /* Send the stop byte */
00301             SCI0DRL = STOP_BYTE;
00302             /* Clear the TX in progress flag */
00303             TXBufferInUseFlags &= COM_CLEAR_SCI0_INTERFACE_ID;
00304         }
00305     }
00306 
00307     /* Record how long the operation took */
00308     RuntimeVars.serialISRRuntime = TCNT - start;
00309 }

Here is the call graph for this function:

void SecondaryRPMISR ( void   ) 

Use the rising and falling edges...................

Secondary RPM ISR

Todo:
TODO Docs here!

TODO Add a check for 1 skip pulse of the 8x track, to prevent possible incorrect sync.

TODO Possibily make virtual CAS 16-bit so was can get rid of floating points and use for syncing

Secondary RPM ISR

Todo:
TODO Docs here!

Secondary RPM ISR

Todo:
TODO Docs here!

Secondary RPM ISR

Similar to the primary one.

Todo:
TODO bring this documentation up to date.

TODO finish this off to a usable standard.

Secondary RPM ISR

Todo:
TODO Docs here!

Todo:
TODO fill in or remove the else

Definition at line 98 of file LT1-360-8.c.

References CLEAR_PRIMARY_SYNC, fixedConfig1::coreSettingsA, coreStatusA, Counters, Counter::crankSyncLosses, engineCyclePeriod, fixedConfigs1, ISRLatencyVars, isSynced, lastSecondaryOddTimeStamp, PORTJ, PORTM, PRIMARY_SYNC, primaryPulsesPerSecondaryPulse, primaryPulsesPerSecondaryPulseBuffer, PrimaryTeethDuringHigh, PrimaryTeethDuringLow, PTIT, RuntimeVars, SECONDARY_POLARITY, ISRLatencyVar::secondaryInputLatency, RuntimeVar::secondaryInputLeadingRuntime, RuntimeVar::secondaryInputTrailingRuntime, Counter::secondaryTeethSeen, TC1, TCNT, TFLG, TFLGOF, LongTime::timeLong, timerExtensionClock, and LongTime::timeShorts.

00098                           {
00099     /* Clear the interrupt flag for this input compare channel */
00100     TFLG = 0x02;
00101 
00102     /* Save all relevant available data here */
00103 //  unsigned short codeStartTimeStamp = TCNT;       /* Save the current timer count */
00104 //  unsigned short edgeTimeStamp = TC1;             /* Save the timestamp */
00105     unsigned char PTITCurrentState = PTIT;          /* Save the values on port T regardless of the state of DDRT */
00106 //  unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */
00107 
00108     PORTJ |= 0x40;  /* echo input condition */
00109     if (!isSynced){ /* If the CAS is not in sync get window counts and set virtual CAS position */
00110         if (PTITCurrentState & 0x02){  /* if signal is high that means we can count the lows */
00111             switch (PrimaryTeethDuringLow){
00112             case 23: /* wheel is at 0 deg TDC #1, set our virtual CAS to tooth 0 of 72 */
00113             {
00114 
00115                 break;
00116             }
00117             case 38: /* wheel is at 90 deg TDC #4, set our virtual CAS to tooth 18 of 72 */
00118             {
00119 
00120                 break;
00121             }
00122             case 33: /* wheel is at 180 deg TDC #6 set our virtual CAS to tooth 36 of 72 */
00123             {
00124 
00125                 break;
00126             }
00127             case 28: /* wheel is at 270 deg TDC #7 set our virtual CAS to tooth 54 of 72 */
00128             {
00129 
00130                 break;
00131             }
00132             default :
00133             {
00134             Counters.crankSyncLosses++; /* use crankSyncLosses variable to store number of invalid count cases while attempting to sync*/
00135                 break;
00136             }
00137             PrimaryTeethDuringLow = 0; /* In any case reset counter */
00138             }
00139         }else{    /* if the signal is low that means we can count the highs */
00140             switch (PrimaryTeethDuringHigh){
00141             case 7: /* wheel is at 52 deg, 7 deg ATDC #8 set our virtual CAS to tooth 10.4 of 72 */
00142             {
00143 
00144                 break;
00145             }
00146             case 12: /* wheel is at 147 deg, 12 deg ATDC #3 set our virtual CAS to tooth 29.4 of 72 */
00147             {
00148 
00149                 break;
00150             }
00151             case 17: /* wheel is at 242 deg, 17 deg ATDC #5 set our virtual CAS to tooth 48.4 of 72 */
00152             {
00153 
00154                 break;
00155             }
00156             case 22: /* wheel is at 337 deg, 22 deg ATDC #2 set our virtual CAS to tooth 67.4 of 72 */
00157             {
00158 
00159                 break;
00160             }
00161             default :
00162             {
00163                 Counters.crankSyncLosses++; /* use crankSyncLosses variable to store number of invalid/default count cases while attempting to sync*/
00164                 break;
00165             }
00166 
00167             }
00168             PrimaryTeethDuringHigh = 0;  /* In any case reset counter */
00169         }
00170     }else{    /* System is synced so use adjusted count numbers to check sync */
00172     }
00173 }

void StagedOffISR ( void   ) 

Definition at line 71 of file injectionISRs.c.

References PITINTE.

00071                        {
00072     // clear the flag
00073     PITINTE |= 0x08;
00074 
00075     // bit bang off the correct injector channel
00076     // TODO figure out which channel and switch it
00077     // TODO set the flag for that channel
00078 
00079     // if there are other staged channels pending, schedule them and adjust the data
00080     // TODO
00081 
00082     /* Clear the PIT3 flag */
00083     // TODO
00084 }

void StagedOnISR ( void   ) 

Definition at line 50 of file injectionISRs.c.

References fixedConfig1::coreSettingsA, fixedConfigs1, PITINTE, and STAGED_END.

00050                       {
00051     // clear the flag
00052     PITINTE |= 0x04;
00053 
00054     // bit bang on the correct injector channel
00055     // TODO figure out which channel and switch it
00056     // TODO set the flag for that channel
00057 
00058     // if there are other staged channels pending, schedule them and adjust the data
00059     // TODO
00060 
00061     /* If staged injection needs the end point scheduled, do it now (otherwise it will turn off naturally with the main injector) */
00062     if(!(fixedConfigs1.coreSettingsA & STAGED_END)){
00063         // TODO schedule the end of staged injection with PIT 3
00064     }
00065 
00066     /* Clear the PIT2 flag */
00067     // TODO
00068 }

void TimerOverflow ( void   ) 

ECT overflow handler.

When the ECT free running timer hits 65535 and rolls over, this is run. Its job is to extend the timer to an effective 32 bits for longer measuring much longer periods with the same resolution.

Author:
Fred Cooke

Definition at line 175 of file realtimeISRs.c.

References TFLGOF, and timerExtensionClock.

00175                     {
00176     /* Increment the timer extension variable */
00177     timerExtensionClock++;
00178 
00179     /* Clear the timer overflow interrupt flag */
00180     TFLGOF = 0x80;
00181 }

void UISR ( void   ) 

Unimplemented Interrupt Handler.

Unimplemented interrupt service routine for calls we weren't expecting. Currently this simply counts bad calls like any other event type.

Author:
Fred Cooke

Definition at line 49 of file miscISRs.c.

References Counter::callsToUISRs, and Counters.

00049                {
00050     /* Increment the unimplemented ISR execution counter */
00051     Counters.callsToUISRs++;
00052 }

void VRegAPIISR ( void   ) 

void XIRQISR ( void   ) 

XIRQ/PE0 pin ISR.

Interrupt handler for edge events on the XIRQ/PE0 pin. Not currently used.

Author:
Fred Cooke

Definition at line 217 of file miscISRs.c.

References Counter::callsToUISRs, and Counters.

00217                   {
00218     /* Clear the flag */
00219     // ?? TODO
00220 
00221     /* Increment the unimplemented ISR execution counter */
00222     Counters.callsToUISRs++;
00223 }


Generated on Mon Jan 26 00:17:07 2009 for FreeEMS by  doxygen 1.5.8