FreeEMS  0.2.0-SNAPSHOT-282-g9efc524
Macros | Functions
MitsiAndMazda-CAS-4and2.c File Reference

Reads Mitsi 4 and 2 CAS units. More...

#include "inc/MitsiAndMazda-CAS-4and2.h"
Include dependency graph for MitsiAndMazda-CAS-4and2.c:

Go to the source code of this file.

Macros

#define DECODER_IMPLEMENTATION_C

Functions

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

Detailed Description

Reads Mitsi 4 and 2 CAS units.

Two interrupts share state and cross communicate to find and maintain sync and position information.

Development thread: http://forum.diyefi.org/viewtopic.php?f=56&t=1110

Definition in file MitsiAndMazda-CAS-4and2.c.

Macro Definition Documentation

#define DECODER_IMPLEMENTATION_C

Definition at line 27 of file MitsiAndMazda-CAS-4and2.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 31 of file MitsiAndMazda-CAS-4and2.c.

{} // This decoder works with the defaults
void perDecoderReset ( void  )

Definition at line 32 of file MitsiAndMazda-CAS-4and2.c.

References doubleHighSeen.

{
}
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 51 of file MitsiAndMazda-CAS-4and2.c.

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

{
/* Clear the interrupt flag for this input compare channel */
TFLG = 0x01;
/* Save all relevant available data here */
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 */
/* 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 */
}else{
}
unsigned long thisEventTimeStamp = timeStamp.timeLong;
unsigned long thisInterEventPeriod = 0;
thisInterEventPeriod = thisEventTimeStamp - lastEventTimeStamp;
}
// Always sample in this ISR
// Set flag to say calc required
// Reset the clock for reading timeout
// Determine the correct event based on post transition state
unsigned char correctEvent = 0;
if(PTITCurrentState & 0x01){
if(!(PTITCurrentState & 0x02)){
correctEvent = 10;
}else{ // Occurs three times
}
}else{
if(PTITCurrentState & 0x02){
// Only this one is not intercepted by a clear
if(doubleHighSeen == 1){
correctEvent = 6;
}
}else{ // Clear on double low
}
}
unsigned char lastEvent = 0;
}
// ...and check that it's correct
if(correctEvent != 0){
if(KeyUserDebugs.currentEvent != correctEvent){
return;
} // Else do nothing, we're running!
}
}else if(correctEvent != 0){
KeyUserDebugs.currentEvent = correctEvent;
lastEvent = KeyUserDebugs.currentEvent - 1;
}
unsigned short thisTicksPerDegree = 0;
unsigned short thisAngle = 0;
thisAngle = eventAngles[KeyUserDebugs.currentEvent] + totalEventAngleRange - 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;
}else{
if(PTITCurrentState & 0x01){
// TODO Calculate RPM from last primaryLeadingEdgeTimeStamp
}else{
// TODO Calculate RPM from last primaryTrailingEdgeTimeStamp
}
}
}/*else*/ if(KeyUserDebugs.decoderFlags & LAST_TIMESTAMP_VALID){ // TODO temp for testing just do rpm this way, fill above out later.
*ticksPerDegreeRecord = thisTicksPerDegree;
}
}
SCHEDULE_ECT_OUTPUTS();
OUTPUT_COARSE_BBS();
lastTicksPerDegree = thisTicksPerDegree;
}
// Always
lastEventTimeStamp = thisEventTimeStamp;
}

Here is the call graph for this function:

void SecondaryRPMISR ( 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 177 of file MitsiAndMazda-CAS-4and2.c.

References decoderSetting::accelerationInputEventTimeTolerance, ADCBuffers, BIT1, CALC_FUEL_IGN, CAM_SYNC, Clocks, 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, lastTicksPerDegree, NBIT1, OK_TO_SCHEDULE, PORTB, PTIT, resetToNonRunningState(), sampleEachADC(), SECONDARY_EVENT_ARRIVED_TOO_EARLY, SECONDARY_EVENT_ARRIVED_TOO_LATE, KeyUserDebug::secondaryTeethSeen, SET_SYNC_LEVEL_TO, STATE_MISMATCH_IN_SECONDARY_RPM_ISR, Counter::syncedADCreadings, TC1, TFLG, TFLGOF, ticks_per_degree_multiplier, ticksPerDegreeRecord, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, and timeStamp.

{
// Reads the inner slot on the disk.
/* Clear the interrupt flag for this input compare channel */
TFLG = 0x02;
/* Save all relevant available data here */
edgeTimeStamp = TC1; /* Save the timestamp */
unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */
// remember that this is both edges, though... 8 per cycle, 4 per rev for the outter wheel, 2/1 for this wheel.
/* Install the low word */
/* 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 */
}else{
}
unsigned long thisEventTimeStamp = timeStamp.timeLong;
unsigned long thisInterEventPeriod = 0;
thisInterEventPeriod = thisEventTimeStamp - lastEventTimeStamp;
}
// Determine the correct event based on post transition state (and toggle debug pins)
unsigned char correctEvent = 0;
if(PTITCurrentState & 0x02){
if(PTITCurrentState & 0x01){
correctEvent = 11;
}else{
correctEvent = 4;
}
} // else the leading edge of the slot is ambiguous
// Only sample if not synced, cleans up readings.
// Set flag to say calc required
// Reset the clock for reading timeout
}
unsigned char lastEvent = 0;
// ...and check that it's correct
if(correctEvent != 0){
if(KeyUserDebugs.currentEvent != correctEvent){
return;
} // Else do nothing, we're running!
}
}else if(correctEvent != 0){
KeyUserDebugs.currentEvent = correctEvent;
lastEvent = KeyUserDebugs.currentEvent - 1;
}
unsigned short thisTicksPerDegree = 0;
unsigned short thisAngle = eventAngles[KeyUserDebugs.currentEvent] - eventAngles[lastEvent];
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;
}
*ticksPerDegreeRecord = thisTicksPerDegree;
}
}
SCHEDULE_ECT_OUTPUTS();
OUTPUT_COARSE_BBS();
lastTicksPerDegree = thisTicksPerDegree;
}
// Always
lastEventTimeStamp = thisEventTimeStamp;
}

Here is the call graph for this function: