FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
Macros | Functions
decoderInterface.c File Reference

shared functions used by all decoders More...

#include "inc/freeEMS.h"
#include "inc/decoderInterface.h"
Include dependency graph for decoderInterface.c:

Go to the source code of this file.


#define newStartIsAfterOutputEndTimeAndCanSelfSet   (diff > LONGHALF)


void descheduleAll ()
 Loop over all schedules descheduling them as we go.
void resetToNonRunningState (unsigned char uniqueLossID)
 Reset key state.
void schedulePortTPin (unsigned char outputEventNumber, LongTime timeStamp)
 Schedule an ignition output event on port T.

Detailed Description

shared functions used by all decoders

To maximise code reuse and minimise bugs it is strongly recommended that you use these pre-canned functions to do work required in your decoder.

Definition in file decoderInterface.c.

Macro Definition Documentation


Definition at line 38 of file decoderInterface.c.

#define newStartIsAfterOutputEndTimeAndCanSelfSet   (diff > LONGHALF)

Referenced by schedulePortTPin().

Function Documentation

void descheduleAll ( void  )

Loop over all schedules descheduling them as we go.

Definition at line 44 of file decoderInterface.c.

References MAX_NUMBER_OF_OUTPUT_EVENTS, and outputEventInputEventNumbers.

Referenced by initVariables(), and resetToNonRunningState().

unsigned char i;
for(i = 0; i < MAX_NUMBER_OF_OUTPUT_EVENTS; i++){

Here is the caller graph for this function:

void resetToNonRunningState ( unsigned char  uniqueLossID)

Reset key state.

Reset all important variables to their non-running state.

TODO bring this up to date and/or find a better way to do it.
uniqueLossID0 is reserved for system use, within your decoder never use the same value twice.

Definition at line 60 of file decoderInterface.c.

References CAM_SYNC, COMBUSTION_SYNC, CRANK_SYNC, KeyUserDebug::currentEvent, KeyUserDebug::decoderFlags, fixedConfig2::decoderSettings, descheduleAll(), fixedConfigs2, FLAG_AND_INC_FLAGGABLE, FLAG_DECODER_SYNC_LOSSES_OFFSET, FLAG_DECODER_SYNC_STATE_CLEARS_OFFSET, FLAG_DECODER_SYNCS_NOT_CONFIRMED_OFFSET, KeyUserDebugs, OK_TO_SCHEDULE, perDecoderReset(), decoderSetting::syncConfirmationsRunning, syncConfirmationsRunningCounter, decoderSetting::syncConfirmationsStarting, syncConfirmationsStartingCounter, KeyUserDebug::syncLostOnThisEvent, KeyUserDebug::syncLostWithThisID, KeyUserDebug::syncResetCalls, ticksPerDegree0, and ticksPerDegree1.

Referenced by main(), PLLLockISR(), PrimaryRPMISR(), SecondaryRPMISR(), and SelfClockISR().

// Reset the safe re-sync counters.
if(fixedConfigs2.decoderSettings.syncConfirmationsRunning == 0xFF){ // Prevent overflow to zero
}else{ // Ensure at least 1 cycle is confirmed
/* Reset RPM to zero */
// Keep track of lost sync in counters
// record unique loss ID
// record current event and then clear it
/* Clear all sync flags to lost state */
KeyUserDebugs.decoderFlags = 0; // Nothing should use this except for us anyway!
// Unschedule everything right now

Here is the call graph for this function:

Here is the caller graph for this function:

void schedulePortTPin ( unsigned char  outputEventNumber,
LongTime  timeStamp 

Schedule an ignition output event on port T.

If you do not handle the skipEventFlags then excess advance may occur!
TODO Make this more understandable as right now it is difficult to grok.

Definition at line 108 of file decoderInterface.c.

References Counters, decoderMaxCodeTime, ectMainActiveMasks, ectMainControlRegisters, ectMainEndTimes, ectMainGoHighMasks, ectMainOnMasks, ectMainStartOffsetHolding, ectMainTimeRegisters, ectSwitchOffCodeTime, fixedConfigs1, newStartIsAfterOutputEndTimeAndCanSelfSet, outputEventDelayFinalPeriod, outputEventDelayFinalPeriodHolding, outputEventExtendNumberOfRepeats, outputEventExtendNumberOfRepeatsHolding, outputEventExtendRepeatPeriod, outputEventExtendRepeatPeriodHolding, schedulingSetting::outputEventPinNumbers, outputEventPulseWidthsHolding, outputEventPulseWidthsMath, Counter::pinScheduledAgainToStayOn, Counter::pinScheduledAlready, Counter::pinScheduledFromCold, Counter::pinScheduledToDoNothing, Counter::pinScheduledToSelfSchedule, Counter::pinScheduledToToggleError, SCHEDULE_ONE_ECT_OUTPUT, fixedConfig1::schedulingSettings, selfSetTimer, skipEventFlags, TIE, LongTime::timeLong, and LongTime::timeShorts.

Referenced by main(), and PrimaryRPMISR().

unsigned char pin = fixedConfigs1.schedulingSettings.outputEventPinNumbers[outputEventNumber];
unsigned short postReferenceEventDelay = 0;
if(skipEventFlags & (1UL << outputEventNumber)){
postReferenceEventDelay = decoderMaxCodeTime;
skipEventFlags &= ~(1UL << outputEventNumber); // Clear the flag
postReferenceEventDelay = outputEventDelayFinalPeriod[outputEventNumber];
// determine the long and short start times
unsigned short startTime = timeStamp.timeShorts[1] + postReferenceEventDelay;
// remove this temporarily too, no need for it without the later conditional code
unsigned long startTimeLong = timeStamp.timeLong + postReferenceEventDelay;
/// @todo TODO Make this more understandable as right now it is difficult to grok.
// determine whether or not to reschedule or self schedule assuming pin is currently scheduled
unsigned long diff = (ectMainEndTimes[pin] + ectSwitchOffCodeTime) - startTimeLong;
#define newStartIsAfterOutputEndTimeAndCanSelfSet (diff > LONGHALF)
fresh code again, five states, 6 possible behaviours:
not enabled - sched!!! always
enabled and low, ready to turn on - if too close, do nothing, or if far enough away, resched
enabled and high, ready to turn off - if too close, resched to turn on, if far enough away, self sched
// Is it enabled and about to do *something*?
if(TIE & ectMainOnMasks[pin]){
// If configured to do something specific
// If that something is go high
// if too close, do nothing, or if far enough away, resched
// for now just always do nothing as it's going to fire, and whatever configured got it close enough...
}else{ // Otherwise it's go low
// if too close, resched to turn, ie, stay on... , if far enough away, self sched
// self sched
selfSetTimer |= ectMainOnMasks[pin]; // setup a bit to let the timer interrupt know to set its own new start from a var
}else{ // Configured to do nothing, or toggle
// ie, do nothing
// if too close, do nothing, or if far enough away, resched
// for now just always do nothing as it's going to fire, and whatever configured got it close enough...
}else{ // not enabled, schedule as normal
#ifdef XGATE // This has to be here because the timing of the ECT stuff is critical and it must run first.
#include "xgateScheduler.c"
#endif // Also, this should always run so can't be inside the above if/else block.

Here is the caller graph for this function: