FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
Macros | Functions | Variables
HallOrOptical-Distributor-XofY.c File Reference

Echos the input on the first ignition output. More...

#include "../inc/defaultSecondaryRPMISR.c"
Include dependency graph for HallOrOptical-Distributor-XofY.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define angleOfSingleIteration   (180 * ANGLE_FACTOR)
#define E0   0
#define E2   (E0 + angleOfSingleIteration)
#define E3   (E1 + angleOfSingleIteration)
#define E4   (E0 + (2 * angleOfSingleIteration))
#define E5   (E1 + (2 * angleOfSingleIteration))
#define E6   (E0 + (3 * angleOfSingleIteration))
#define E7   (E1 + (3 * angleOfSingleIteration))

Functions

void decoderInitPreliminary ()
void perDecoderReset ()
void PrimaryRPMISR ()
 RPM ISRs, IC timer for engine position and RPM.

Variables

const unsigned short eventAngles [] = {E0, E1, E2, E3, E4, E5, E6, E7}
const unsigned char eventValidForCrankSync [] = {0,0,0,0,0,0,0,0}

Detailed Description

Echos the input on the first ignition output.

This decoder is for any 4 tooth/slot hall or optical cam speed sensor and to be used for distributor and/or 4 shot batch injection only.

To build a version of this decoder with a specific angle pair for your hall or optical distributor, just define the DECODER_IMPLEMENTATION_C flag, include the four required headers, define the angle for E1, and define the unique decoder name string!

To effectively reverse the polarity, just subtract your angle from 180 and it will then be correct, assuming that either angle is correct.

Definition in file HallOrOptical-Distributor-XofY.c.

Macro Definition Documentation

#define angleOfSingleIteration   (180 * ANGLE_FACTOR)

Definition at line 47 of file HallOrOptical-Distributor-XofY.c.

Referenced by PrimaryRPMISR().

#define E0   0

Definition at line 49 of file HallOrOptical-Distributor-XofY.c.

#define E2   (E0 + angleOfSingleIteration)

Definition at line 51 of file HallOrOptical-Distributor-XofY.c.

#define E3   (E1 + angleOfSingleIteration)

Definition at line 52 of file HallOrOptical-Distributor-XofY.c.

#define E4   (E0 + (2 * angleOfSingleIteration))

Definition at line 53 of file HallOrOptical-Distributor-XofY.c.

#define E5   (E1 + (2 * angleOfSingleIteration))

Definition at line 54 of file HallOrOptical-Distributor-XofY.c.

#define E6   (E0 + (3 * angleOfSingleIteration))

Definition at line 55 of file HallOrOptical-Distributor-XofY.c.

#define E7   (E1 + (3 * angleOfSingleIteration))

Definition at line 56 of file HallOrOptical-Distributor-XofY.c.

Function Documentation

void decoderInitPreliminary ( void  )
Todo:
TODO Perhaps use some of the space freed by shrinking all timing tables for this: /unsigned long wheelEventTimeStamps[numberOfWheelEvents]; // For logging wheel patterns as observed

Definition at line 68 of file HallOrOptical-Distributor-XofY.c.

References TCTL4.

{
TCTL4 = 0x03; /* Capture on both edges of T0 only, capture off for 1,2,3 */
} // This decoder works with the defaults
void perDecoderReset ( void  )

Definition at line 71 of file HallOrOptical-Distributor-XofY.c.

{} // Nothing special to reset for this code
void PrimaryRPMISR ( void  )

RPM ISRs, IC timer for engine position and RPM.

There are multiple copies of this interrupt handler, each is linked with the rest of the code once such that if there are N decoder implementations and/or variants, then there are N loadable binaries produced after a full build.

For details on any specific decoder implementation, see the documentation for that specific file.

Definition at line 74 of file HallOrOptical-Distributor-XofY.c.

References decoderSetting::accelerationInputEventTimeTolerance, ADCBuffers, angleOfSingleIteration, BIT0, CALC_FUEL_IGN, Clocks, COMBUSTION_SYNC, coreStatusA, Counters, KeyUserDebug::currentEvent, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, decoderSetting::decelerationInputEventTimeTolerance, DECODER_BENCHMARKS, KeyUserDebug::decoderFlags, fixedConfig2::decoderSettings, edgeTimeStamp, eventAngles, fixedConfigs2, KeyUserDebug::inputEventTimeTolerance, KeyUserDebugs, LAST_PERIOD_VALID, LAST_TIMESTAMP_VALID, lastEventTimeStamp, lastPrimaryEventTimeStamp, lastSecondaryEventTimeStamp, lastTicksPerDegree, NBIT0, PORTB, PRIMARY_EVENT_ARRIVED_TOO_EARLY, PRIMARY_EVENT_ARRIVED_TOO_LATE, KeyUserDebug::primaryTeethSeen, PTIT, resetToNonRunningState(), sampleEachADC(), SET_SYNC_LEVEL_TO, Counter::syncedADCreadings, TC0, TFLG, TFLGOF, ticks_per_degree_multiplier, ticksPerDegreeRecord, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, and timeStamp.

{
/* Clear the interrupt flag for this input compare channel */
TFLG = 0x01;
/* Save all relevant available data here */
unsigned short edgeTimeStamp = TC0; /* Save the edge time stamp */
unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */
/* Install the low word */
timeStamp.timeShorts[1] = edgeTimeStamp;
/* Find out what our timer value means and put it in the high word */
if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
timeStamp.timeShorts[0] = timerExtensionClock + 1;
}else{
}
unsigned long thisEventTimeStamp = timeStamp.timeLong;
unsigned char lastEvent = 0;
unsigned short thisTicksPerDegree = 0;
if(PTITCurrentState & 0x01){
// temporary data from inputs
unsigned long primaryLeadingEdgeTimeStamp = timeStamp.timeLong;
unsigned long timeBetweenSuccessivePrimaryPulses = primaryLeadingEdgeTimeStamp - lastPrimaryEventTimeStamp;
lastPrimaryEventTimeStamp = primaryLeadingEdgeTimeStamp;
thisTicksPerDegree = (unsigned short)((ticks_per_degree_multiplier * timeBetweenSuccessivePrimaryPulses) / angleOfSingleIteration);
*ticksPerDegreeRecord = thisTicksPerDegree;
// TODO Once sampling/RPM is configurable, use this tooth for a lower MAP reading.
/* Set flag to say calc required */
/* Reset the clock for reading timeout */
lastEvent = 0;
}else{
// temporary data from inputs
unsigned long secondaryLeadingEdgeTimeStamp = timeStamp.timeLong;
unsigned long timeBetweenSuccessiveSecondaryPulses = secondaryLeadingEdgeTimeStamp - lastSecondaryEventTimeStamp;
lastSecondaryEventTimeStamp = secondaryLeadingEdgeTimeStamp;
thisTicksPerDegree = (unsigned short)((ticks_per_degree_multiplier * timeBetweenSuccessiveSecondaryPulses) / angleOfSingleIteration);
*ticksPerDegreeRecord = thisTicksPerDegree;
// TODO make this stuff behave correctly, this one will only run at startup, and the other will always run, but do it by generic config and split this stuff out into a shared function, soon.
/* Set flag to say calc required */
/* Reset the clock for reading timeout */
lastEvent = 1;
}
unsigned long thisInterEventPeriod = 0;
thisInterEventPeriod = thisEventTimeStamp - lastEventTimeStamp;
}
// This should check during gain of sync too and prevent gaining sync if the numbers aren't right, however this is a step up for the Hotel at this time.
unsigned short thisAngle = 0;
// Fix this to work for all:
// thisAngle = eventAngles[KeyUserDebugs.currentEvent] + totalEventAngleRange - eventAngles[lastEvent] ; // Optimisable... leave readable for now! :-p J/K learn from this...
thisAngle = eventAngles[KeyUserDebugs.currentEvent] + angleOfSingleIteration - eventAngles[lastEvent] ; // Optimisable... leave readable for now! :-p J/K learn from this...
}else{
}
thisTicksPerDegree = (unsigned short)((ticks_per_degree_multiplier * thisInterEventPeriod) / thisAngle); // with current scale range for 60/12000rpm is largest ticks per degree = 3472, smallest = 17 with largish error
unsigned short ratioBetweenThisAndLast = (unsigned short)(((unsigned long)lastTicksPerDegree * 1000) / thisTicksPerDegree);
KeyUserDebugs.inputEventTimeTolerance = ratioBetweenThisAndLast;
return;
return;
}
}
}
SCHEDULE_ECT_OUTPUTS();
OUTPUT_COARSE_BBS();
/* TODO this delays outputs until the fourth ISR execution, but we could
* get them one execution or 1/8 of a rev sooner if we did a preliminary
* calc from the previous edge instead of the previous same edge now, and
*
* The proper way to do this is set sync when we have it and not set data
* as having been recorded until we know the data is good. That way the
* scheduler can keep things unscheduled until the time is right.
*/
}
lastTicksPerDegree = thisTicksPerDegree;
}
// Always
lastEventTimeStamp = thisEventTimeStamp;
}

Here is the call graph for this function:

Variable Documentation

const unsigned short eventAngles[] = {E0, E1, E2, E3, E4, E5, E6, E7}

Definition at line 64 of file HallOrOptical-Distributor-XofY.c.

const unsigned char eventValidForCrankSync[] = {0,0,0,0,0,0,0,0}

Definition at line 65 of file HallOrOptical-Distributor-XofY.c.