1026 lines
30 KiB
C
1026 lines
30 KiB
C
/******************************************************************************/
|
|
/* Copyright (c) 2016 MD Automotive Controls. Original Work. */
|
|
/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */
|
|
/******************************************************************************/
|
|
/* CONTEXT:KERNEL */
|
|
/* PACKAGE TITLE: XXX */
|
|
/* DESCRIPTION: XXX */
|
|
/* FILE NAME: XXX.c */
|
|
/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */
|
|
/* */
|
|
/******************************************************************************/
|
|
#define _CEM_C
|
|
|
|
#include "CEM.h"
|
|
#include "declarations.h"
|
|
#include "EST.h"//matthew breaking layers
|
|
#include "SETUP.h"//matthew breaking layers
|
|
#include "os.h"
|
|
#include "tepmha.h"
|
|
#include "KERNELIO.h"
|
|
|
|
uint16 CEM_au16RisingCrankEdge[80];
|
|
uint16 CEM_au16FallingCrankEdge[80];
|
|
uint16 CEM_au16AllEdge[160];
|
|
bool CEM_aboSyncEdge[160];
|
|
uint16 CEM_au16SyncPoints[36];
|
|
uint8 CEM_u8RisingEdgesCount;
|
|
uint8 CEM_u8FallingEdgesCount;
|
|
uint32 CEM_u8CrankEdgeCounter;
|
|
bool CEM_boCrankEdgeFirstRising;
|
|
uint32 CEM_u32CrankEdgeTimeoutCount;
|
|
uint8 CEM_au8AutocorrPeak[4];
|
|
uint8 CEM_au8ConfirmedAutocorrPeak[4];
|
|
IOAPI_tenEdgePolarity CEM_enEdgePolarity;
|
|
TEPMAPI_tstTimerMeasurements CEM_stTimerMeasurements[TEPMHA_nEventChannels];
|
|
bool CEM_boEdgesReady;
|
|
uint32 CEM_au32TimerOffsets[9];
|
|
CEM_tenTriggerType CEM_enTriggerType;
|
|
uint8 CEM_u8SimpleMissingSync;
|
|
TEPMAPI_tstSimpleCamSync stSimpleCamSync;
|
|
extern IOAPI_tenEHIOResource TEPM_astTEPMVVTInputs[];
|
|
TEPMAPI_ttEventTime CEM_atLastVVTTimer[4];
|
|
TEPMAPI_ttEventTime CEM_atLastVVTHighTime[4];
|
|
TEPMAPI_ttEventTime CEM_atLastVVTLowTime[4];
|
|
|
|
static void CEM_vSequenceReset(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime, uint32 u32OriginGlobalCycleFraction, bool boLatePhase);
|
|
static TEPMAPI_ttEventTime CEM_tCalculateGlobalTime(TEPMAPI_ttEventTime tEventTime, uint16 u16LastGapFraction, bool boGlobalTimeEnable);
|
|
static void CEM_vProcessAllEdges(void);
|
|
static void CEM_vPhaseError(int);
|
|
static bool CEM_boGetLatePhaseSimpleCamSync(void);
|
|
|
|
void CEM_vStart(uint32* const u32Stat)
|
|
{
|
|
CEM_u32GlobalCycleFraction = 0;
|
|
CEM_u32GlobalCycleTime = 0x0000ffff;
|
|
CEM_u32GlobalCycleOriginCount = 0;
|
|
CEM_u32CrankEdgeTimeoutCount = 0;
|
|
CEM_tEventTimeLast = ~0;
|
|
CEM_u8CrankEdgeCounter = 0xff;
|
|
CEM_boEdgesReady = FALSE;
|
|
CTS_boCTSReady = FALSE;
|
|
CEM_u8SimpleMissingSync = 0;
|
|
CEM_u32CrankErrorCounts = 0;
|
|
//CEM_u8PhaseRepeats = 1;//matthew must be dynamic!!!
|
|
|
|
memset((void*)&CEM_au16RisingCrankEdge, 0, sizeof(CEM_au16RisingCrankEdge));
|
|
memset((void*)&CEM_au16FallingCrankEdge, 0, sizeof(CEM_au16FallingCrankEdge));
|
|
CEM_u8RisingEdgesCount = 0;
|
|
CEM_u8FallingEdgesCount = 0;
|
|
CEM_u32SyncPoints = 0;
|
|
CEM_boCrankEdgeFirstRising = FALSE;
|
|
CEM_au8AutocorrPeak[0] = 128;
|
|
CEM_au8AutocorrPeak[1] = 128;
|
|
CEM_au8AutocorrPeak[2] = 128;
|
|
CEM_au8AutocorrPeak[3] = 128;
|
|
CEM_au8ConfirmedAutocorrPeak[0] = 128;
|
|
CEM_au8ConfirmedAutocorrPeak[1] = 128;
|
|
CEM_au8ConfirmedAutocorrPeak[2] = 128;
|
|
CEM_au8ConfirmedAutocorrPeak[3] = 128;
|
|
}
|
|
|
|
void CEM_vRun(uint32* const u32Stat)
|
|
{
|
|
if (10 < CEM_u32CrankEdgeTimeoutCount)
|
|
{
|
|
CEM_tEventTimeLast = ~0;
|
|
CEM_u32GlobalCycleOriginCount = 0;
|
|
}
|
|
else
|
|
{
|
|
CEM_u32CrankEdgeTimeoutCount++;
|
|
}
|
|
}
|
|
|
|
void CEM_vTerminate(uint32* const u32Stat)
|
|
{
|
|
|
|
}
|
|
|
|
bool CEM_boPopulateSyncPointsArray(puint16 const pu16EdgeFractionArray)
|
|
{
|
|
bool boRetVal = true;
|
|
|
|
CEM_u32SyncPoints = 0;
|
|
|
|
while (((0 != *(pu16EdgeFractionArray + CEM_u32SyncPoints)) && (36 > CEM_u32SyncPoints)) | (0 == CEM_u32SyncPoints))
|
|
{
|
|
CEM_au16SyncPoints[CEM_u32SyncPoints] = *(pu16EdgeFractionArray + CEM_u32SyncPoints);
|
|
CEM_u32SyncPoints++;
|
|
}
|
|
|
|
CEM_u32SequenceFraction = 0x2000ul / CEM_u32SyncPoints;
|
|
|
|
return boRetVal;
|
|
}
|
|
|
|
|
|
bool CEM_boPopulateCrankEdgeArrays(puint16 const pu16EdgeFractionArray, const bool boFirstRising, IOAPI_tenEdgePolarity enEdgePolarity, uint32_t u32TriggerType)
|
|
{
|
|
uint32 u32EdgeCount = 0;
|
|
bool boStat = FALSE;
|
|
uint8 u8EdgeCount = 0;
|
|
CEM_u8RisingEdgesCount = 0;
|
|
CEM_u8FallingEdgesCount = 0;
|
|
|
|
CEM_boCrankEdgeFirstRising = boFirstRising;
|
|
CEM_enEdgePolarity = enEdgePolarity;
|
|
|
|
while (((0 != *(pu16EdgeFractionArray + u32EdgeCount)) && (80 > u8EdgeCount)) | (0 == u32EdgeCount))
|
|
{
|
|
if (IOAPI_enEdgeBoth == enEdgePolarity)
|
|
{
|
|
if (TRUE == boFirstRising)
|
|
{
|
|
CEM_au16RisingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
}
|
|
else
|
|
{
|
|
CEM_au16FallingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
}
|
|
CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
u32EdgeCount++;
|
|
|
|
if (TRUE == boFirstRising)
|
|
{
|
|
CEM_au16FallingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
}
|
|
else
|
|
{
|
|
CEM_au16RisingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
}
|
|
CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
u32EdgeCount++;
|
|
CEM_u8RisingEdgesCount++;
|
|
CEM_u8FallingEdgesCount++;
|
|
}
|
|
if (IOAPI_enEdgeFalling == enEdgePolarity)
|
|
{
|
|
CEM_au16FallingCrankEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
u32EdgeCount++;
|
|
CEM_u8FallingEdgesCount++;
|
|
}
|
|
if (IOAPI_enEdgeRising == enEdgePolarity)
|
|
{
|
|
CEM_au16RisingCrankEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount);
|
|
u32EdgeCount++;
|
|
CEM_u8RisingEdgesCount++;
|
|
}
|
|
}
|
|
|
|
CEM_enTriggerType = (0 != u32TriggerType) ? CEM_enTypeSuzukiM15A + u32TriggerType - 1 : 0;
|
|
|
|
CEM_vProcessAllEdges();
|
|
boStat = TRUE;
|
|
CEM_boEdgesReady = TRUE;
|
|
|
|
return boStat;
|
|
}
|
|
|
|
static void CEM_vProcessAllEdges(void)
|
|
{
|
|
uint32 u32OldData;
|
|
uint32 u32DeltaCount = 0;
|
|
sint32 s32Temp;
|
|
|
|
for (uint32 u32ArrayIDX = 0; u32ArrayIDX < (CEM_xEdgesCount - 1); u32ArrayIDX++)
|
|
{
|
|
u32OldData = CEM_au16AllEdge[u32ArrayIDX];
|
|
CEM_au16AllEdge[u32ArrayIDX] = CEM_au16AllEdge[u32ArrayIDX + 1] - u32OldData;
|
|
}
|
|
|
|
CEM_au16AllEdge[CEM_xEdgesCount - 1] = ~CEM_au16AllEdge[CEM_xEdgesCount - 1] + 1;
|
|
|
|
CEM_aboSyncEdge[0] = TRUE;
|
|
|
|
for (uint32 u32ArrayIDX = 1; u32ArrayIDX < CEM_xEdgesCount; u32ArrayIDX++)
|
|
{
|
|
s32Temp = CEM_au16AllEdge[u32ArrayIDX] - CEM_au16AllEdge[u32ArrayIDX - 1];
|
|
|
|
if (1 < s32Temp)
|
|
{
|
|
u32DeltaCount++;
|
|
CEM_u8SimpleMissingSync = (u32ArrayIDX + 1) % CEM_xEdgesCount;
|
|
}
|
|
|
|
CEM_aboSyncEdge[u32ArrayIDX] = TRUE;
|
|
}
|
|
|
|
if (CEM_enTriggerType < CEM_enTypeSuzukiM15A)
|
|
{
|
|
CEM_enTriggerType = (1 == u32DeltaCount) && (8 < CEM_xEdgesCount) ? CEM_enOneGroupMissing : CEM_enAutocorrelationMode;
|
|
}
|
|
|
|
if (CEM_enTriggerType == CEM_enOneGroupMissing)
|
|
{
|
|
CEM_aboSyncEdge[CEM_u8SimpleMissingSync] = FALSE;
|
|
CEM_aboSyncEdge[CEM_u8SimpleMissingSync - 1] = FALSE;
|
|
}
|
|
}
|
|
|
|
void CEM_vSetSyncPhaseRepeats(uint32 u32SyncPhaseRepeats)
|
|
{
|
|
CEM_u8PhaseRepeats = (uint8)u32SyncPhaseRepeats;
|
|
}
|
|
|
|
|
|
TEPMAPI_ttEventTime CEM_ttGetModulePhase(uint32 u32ChannelIDX)
|
|
{
|
|
TEPMAPI_ttEventTime tPhaseOffset = 0;
|
|
|
|
tPhaseOffset = CEM_au32TimerOffsets[u32ChannelIDX];
|
|
|
|
return tPhaseOffset;
|
|
}
|
|
|
|
void CEM_vPrimaryEventCB(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime)
|
|
{
|
|
uint16 u16LastGapFraction;
|
|
TEPMAPI_ttEventTime tLastGapTime;
|
|
static uint32 au32AutoCorr[CEM_nEdgesMax];
|
|
static uint32 au32InputArray[CEM_nEdgesMax];
|
|
static bool aboConfirmedFlags[4] = {0, 0, 0, 0};
|
|
static uint8 au8ErrorCount[4];
|
|
uint8 u8PhasePrev;
|
|
uint32 u32Temp;
|
|
static uint32 u32EdgeCount = 0;
|
|
bool boPhaseLocked = FALSE;
|
|
static bool boLatePhase;
|
|
static uint8 u8SameGapCount;
|
|
|
|
if (FALSE == CEM_boEdgesReady) return;
|
|
|
|
u8PhasePrev = CEM_u8CrankEdgeCounter;
|
|
|
|
/* Sanity check the edges count */
|
|
if (CEM_xEdgesCount > CEM_nEdgesMax) return;
|
|
|
|
u32EdgeCount++;
|
|
|
|
#ifdef CEM_CHECK_POL
|
|
/* Sanity check edge polarity */
|
|
if (IOAPI_enEdgeFalling == CEM_enEdgePolarity)
|
|
{
|
|
enTriState = TEPM_enGetTimerDigitalState(enEHIOResource);
|
|
|
|
/* Invert the polarity because the circuit inverts */
|
|
if (IOAPI_enLow == enTriState)
|
|
{
|
|
u32EdgePolAbortCount++;
|
|
return;
|
|
}
|
|
}
|
|
else if (IOAPI_enEdgeRising == CEM_enEdgePolarity)
|
|
{
|
|
enTriState = TEPM_enGetTimerDigitalState(enEHIOResource);
|
|
|
|
/* Invert the polarity because the circuit inverts */
|
|
if (IOAPI_enHigh == enTriState)
|
|
{
|
|
u32EdgePolAbortCount++;
|
|
return;
|
|
}
|
|
}
|
|
#endif //CEM_CHECK_POL
|
|
|
|
#ifdef BUILD_SAM3X8E
|
|
CEM_au32TimerOffsets[8] = ((tstTimerModule*)TC2)->TC_CHANNEL[2].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[7] = ((tstTimerModule*)TC2)->TC_CHANNEL[1].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[6] = ((tstTimerModule*)TC2)->TC_CHANNEL[0].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[5] = ((tstTimerModule*)TC1)->TC_CHANNEL[2].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[4] = ((tstTimerModule*)TC1)->TC_CHANNEL[1].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[3] = ((tstTimerModule*)TC1)->TC_CHANNEL[0].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[2] = ((tstTimerModule*)TC0)->TC_CHANNEL[2].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[1] = ((tstTimerModule*)TC0)->TC_CHANNEL[1].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV;
|
|
CEM_au32TimerOffsets[0] = 0;
|
|
#endif //BUILD_SAM3X8E
|
|
|
|
/* Increment the confirmed channels */
|
|
uint32 u32PhaseMin = 0;
|
|
uint32 u32PhaseMax = (CEM_xEdgesCount / CEM_u8PhaseRepeats) - 1;
|
|
|
|
|
|
if (CEM_enAutocorrelationMode == CEM_enTriggerType)
|
|
{
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
if (TRUE == aboConfirmedFlags[u8ArrayIDX])
|
|
{
|
|
CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]++;
|
|
|
|
if (u32PhaseMax < CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX])
|
|
{
|
|
CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX] -= (CEM_xEdgesCount / CEM_u8PhaseRepeats);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX] = 128;
|
|
}
|
|
|
|
u32PhaseMin += (CEM_xEdgesCount / CEM_u8PhaseRepeats);
|
|
u32PhaseMax += (CEM_xEdgesCount / CEM_u8PhaseRepeats);
|
|
u32PhaseMin = u32PhaseMin % CEM_xEdgesCount;
|
|
u32PhaseMax = u32PhaseMax % CEM_xEdgesCount;
|
|
}
|
|
}
|
|
|
|
u16LastGapFraction = CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount] / CEM_u8PhaseRepeats;
|
|
tLastGapTime = CEM_tCalculateGlobalTime(tEventTime, u16LastGapFraction, CEM_aboSyncEdge[CEM_u8CrankEdgeCounter]);
|
|
|
|
if (CEM_enAutocorrelationMode == CEM_enTriggerType)
|
|
{
|
|
/* Increment the edge counter if possible */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
if (TRUE == aboConfirmedFlags[u8ArrayIDX])
|
|
{
|
|
CEM_u8CrankEdgeCounter = (CEM_u8CrankEdgeCounter + 1) % CEM_xEdgesCount;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
CEM_tEventTimeLast = tEventTime;
|
|
CEM_u32CrankEdgeTimeoutCount = 0;
|
|
|
|
/* Shift the input array */
|
|
puint32 pu32 = au32InputArray;
|
|
pu32 += (CEM_nEdgesMax - CEM_xEdgesCount);
|
|
memcpy(pu32, pu32 + 1, sizeof(uint32) * CEM_xEdgesCount);
|
|
|
|
/* Buffer the new gap time */
|
|
au32InputArray[CEM_nEdgesMax - 1] = tLastGapTime;
|
|
|
|
/* If enough edges have arrived to proceed */
|
|
if ((5 / CEM_u8PhaseRepeats) <= u32EdgeCount)//matthew
|
|
{
|
|
switch (CEM_enTriggerType)
|
|
{
|
|
case CEM_enAutocorrelationMode:
|
|
{
|
|
CEM_au8AutocorrPeak[0] = 0x80;
|
|
CEM_au8AutocorrPeak[1] = 0x80;
|
|
CEM_au8AutocorrPeak[2] = 0x80;
|
|
CEM_au8AutocorrPeak[3] = 0x80;
|
|
|
|
/* Calculate the autocorrelation array */
|
|
memset((void*)&au32AutoCorr, 0, CEM_nEdgesMax * sizeof(uint32));
|
|
uint32 u32ControlArrayIDX = 0;
|
|
|
|
for (uint32 u32AutocorrPhase = 0; u32AutocorrPhase < CEM_xEdgesCount; u32AutocorrPhase++)
|
|
{
|
|
uint32 u32InputArrayIDX = CEM_nEdgesMax - CEM_xEdgesCount;
|
|
|
|
for (uint32 u32ShiftCount = 0; u32ShiftCount < CEM_xEdgesCount; u32ShiftCount++)
|
|
{
|
|
u32Temp = (au32InputArray[u32InputArrayIDX] * (uint32)CEM_au16AllEdge[u32ControlArrayIDX]);
|
|
u32Temp /= 0x100u;
|
|
au32AutoCorr[u32AutocorrPhase] += u32Temp;
|
|
u32ControlArrayIDX = (u32ControlArrayIDX + 1) % CEM_xEdgesCount;
|
|
u32InputArrayIDX++;
|
|
}
|
|
u32ControlArrayIDX++;
|
|
}
|
|
|
|
/* Find the autocorrelation peak */
|
|
uint32 u32AutoPeak = 0;
|
|
|
|
for (uint32 u32ArrayIDX = 0; u32ArrayIDX < CEM_xEdgesCount; u32ArrayIDX++)
|
|
{
|
|
if (u32AutoPeak < au32AutoCorr[u32ArrayIDX])
|
|
{
|
|
u32AutoPeak = au32AutoCorr[u32ArrayIDX];
|
|
}
|
|
}
|
|
|
|
/* Set the auto-peaks indices array */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < CEM_xEdgesCount; u8ArrayIDX++)
|
|
{
|
|
if (u32AutoPeak == au32AutoCorr[u8ArrayIDX])
|
|
{
|
|
if (128u == CEM_au8AutocorrPeak[0])
|
|
{
|
|
CEM_au8AutocorrPeak[0] = u8ArrayIDX;
|
|
}
|
|
else if (128u == CEM_au8AutocorrPeak[1])
|
|
{
|
|
CEM_au8AutocorrPeak[1] = u8ArrayIDX;
|
|
}
|
|
else if (128u == CEM_au8AutocorrPeak[2])
|
|
{
|
|
CEM_au8AutocorrPeak[2] = u8ArrayIDX;
|
|
}
|
|
else if (128u == CEM_au8AutocorrPeak[3])
|
|
{
|
|
CEM_au8AutocorrPeak[3] = u8ArrayIDX;
|
|
}
|
|
}
|
|
}
|
|
|
|
u32PhaseMin = 0;
|
|
u32PhaseMax = (CEM_xEdgesCount / CEM_u8PhaseRepeats) - 1;
|
|
|
|
/* Buffer the confirmed array if is not initialized */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
if (128u > CEM_au8AutocorrPeak[u8ArrayIDX])
|
|
{
|
|
if (127 < CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX])
|
|
{
|
|
if ((u32PhaseMin <= CEM_au8AutocorrPeak[u8ArrayIDX]) &&
|
|
(u32PhaseMax >= CEM_au8AutocorrPeak[u8ArrayIDX]))
|
|
{
|
|
CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX] = CEM_au8AutocorrPeak[u8ArrayIDX];
|
|
|
|
if (0xff == CEM_u8CrankEdgeCounter)
|
|
{
|
|
CEM_u8CrankEdgeCounter = CEM_au8AutocorrPeak[u8ArrayIDX];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
u32PhaseMin += (CEM_xEdgesCount / CEM_u8PhaseRepeats);
|
|
u32PhaseMax += (CEM_xEdgesCount / CEM_u8PhaseRepeats);
|
|
u32PhaseMin = u32PhaseMin % CEM_xEdgesCount;
|
|
u32PhaseMax = u32PhaseMax % CEM_xEdgesCount;
|
|
}
|
|
|
|
/* Clear the confirmed flags */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
aboConfirmedFlags[u8ArrayIDX] = FALSE;
|
|
}
|
|
|
|
/* Check if the confirmed array is still confirmed */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
for (uint8 u8ConfirmedArrayIDX = 0; u8ConfirmedArrayIDX < 4; u8ConfirmedArrayIDX++)
|
|
{
|
|
if (CEM_au8ConfirmedAutocorrPeak[u8ConfirmedArrayIDX] == CEM_au8AutocorrPeak[u8ArrayIDX])
|
|
{
|
|
aboConfirmedFlags[u8ConfirmedArrayIDX] = TRUE;
|
|
au8ErrorCount[u8ConfirmedArrayIDX] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Increment error counter of unconfirmed */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
if (FALSE == aboConfirmedFlags[u8ArrayIDX])
|
|
{
|
|
au8ErrorCount[u8ArrayIDX] = (au8ErrorCount[u8ArrayIDX] + 1) % 0x80;
|
|
}
|
|
}
|
|
|
|
/* Check for phase lock on any index */
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
if (CEM_u8CrankEdgeCounter == CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]) {boPhaseLocked = TRUE;}
|
|
}
|
|
|
|
/* Buffer and edge count if we are phase locked */
|
|
if (FALSE == boPhaseLocked)
|
|
{
|
|
for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++)
|
|
{
|
|
if (TRUE == aboConfirmedFlags[u8ArrayIDX])
|
|
{
|
|
CEM_u8CrankEdgeCounter = CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX];
|
|
}
|
|
}
|
|
}
|
|
|
|
CEM_u32GlobalCycleFraction += CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount];
|
|
|
|
/* Are we at a calculation edge? */
|
|
if (0 == CEM_u8CrankEdgeCounter)
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
|
|
if (1 == CEM_u8PhaseRepeats)
|
|
{
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[2])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[3])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CEM_enOneGroupMissing:
|
|
case CEM_enTypeWVEA888:
|
|
{
|
|
CEM_u32GlobalCycleFraction += CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount];
|
|
|
|
if (au32InputArray[CEM_nEdgesMax - 1] > au32InputArray[CEM_nEdgesMax - 2] * 2)
|
|
{
|
|
if ((CEM_u8CrankEdgeCounter != CEM_u8SimpleMissingSync) &&
|
|
(100 < u32EdgeCount))
|
|
{
|
|
CEM_vPhaseError(CEM_u8CrankEdgeCounter);
|
|
}
|
|
|
|
CEM_u8CrankEdgeCounter = CEM_u8SimpleMissingSync;
|
|
}
|
|
|
|
/* Sync over 720 degrees */
|
|
if (CEM_enTypeWVEA888 == CEM_enTriggerType)
|
|
{
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1])
|
|
{
|
|
if (0x10000 <= CEM_u32GlobalCycleFraction)
|
|
{
|
|
if ((CEM_atLastVVTHighTime[0] < (CEM_u32GlobalCycleTime / 8))
|
|
&& (CEM_atLastVVTHighTime[0] > (CEM_u32GlobalCycleTime / 32)))
|
|
{
|
|
boLatePhase = false;
|
|
}
|
|
else if ((CEM_atLastVVTLowTime[0] < (CEM_u32GlobalCycleTime / 8))
|
|
&& (CEM_atLastVVTLowTime[0] > (CEM_u32GlobalCycleTime / 32)))
|
|
{
|
|
boLatePhase = true;
|
|
}
|
|
else
|
|
{
|
|
boLatePhase = !boLatePhase;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CEM_atLastVVTHighTime[0] < (CEM_u32GlobalCycleTime / 8))
|
|
{
|
|
boLatePhase = false;
|
|
}
|
|
else if (CEM_atLastVVTLowTime[0] < (CEM_u32GlobalCycleTime / 8))
|
|
{
|
|
boLatePhase = true;
|
|
}
|
|
else
|
|
{
|
|
boLatePhase = !boLatePhase;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (CEM_u8CrankEdgeCounter == stSimpleCamSync.u32CamSyncSampleToothCount)
|
|
{
|
|
boLatePhase = CEM_boGetLatePhaseSimpleCamSync();
|
|
}
|
|
|
|
if (0 == CEM_u8CrankEdgeCounter)
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
|
|
if (1 == CEM_u8PhaseRepeats)
|
|
{
|
|
if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[1])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0x4000, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[2])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0x8000, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[3])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0xc000, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
}
|
|
else if (2 == CEM_u8PhaseRepeats)
|
|
{
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[2])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[3])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
}
|
|
|
|
if ((25 == CEM_u8CrankEdgeCounter) || (53 == CEM_u8CrankEdgeCounter))
|
|
{
|
|
TEPM_vStartEventProgramKernelQueues(FALSE, 0x80);
|
|
}
|
|
|
|
CEM_u8CrankEdgeCounter = (CEM_u8CrankEdgeCounter + 1) % CEM_xEdgesCount;
|
|
|
|
break;
|
|
}
|
|
case CEM_enTypeSuzukiM15A:
|
|
{
|
|
CEM_u32GlobalCycleFraction += CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount];
|
|
|
|
if (au32InputArray[CEM_nEdgesMax - 1] > (au32InputArray[CEM_nEdgesMax - 2] * 2))
|
|
{
|
|
/* Crank sensor gap */
|
|
if (((CEM_u8CrankEdgeCounter != 21) && (CEM_u8CrankEdgeCounter != 7)) &&
|
|
(100 < u32EdgeCount))
|
|
{
|
|
CEM_vPhaseError(CEM_u8CrankEdgeCounter);
|
|
}
|
|
|
|
CEM_u8CrankEdgeCounter++;
|
|
|
|
u8SameGapCount = 0;
|
|
|
|
CEM_u8CrankEdgeCounter = 30 <= CEM_u8CrankEdgeCounter ? 1 : CEM_u8CrankEdgeCounter;
|
|
}
|
|
else if (au32InputArray[CEM_nEdgesMax - 1] < (au32InputArray[CEM_nEdgesMax - 2] / 2))
|
|
/* Crank sensor end gap */
|
|
{
|
|
if (((CEM_u8CrankEdgeCounter != 22) && (CEM_u8CrankEdgeCounter != 9)) &&
|
|
(100 < u32EdgeCount))
|
|
{
|
|
CEM_vPhaseError(CEM_u8CrankEdgeCounter);
|
|
}
|
|
|
|
if (0 < u8SameGapCount)
|
|
{
|
|
CEM_u8CrankEdgeCounter = 10;
|
|
}
|
|
else
|
|
{
|
|
CEM_u8CrankEdgeCounter = 23;
|
|
CEM_u32GlobalCycleFraction = CEM_au16AllEdge[0] + CEM_au16AllEdge[1];
|
|
}
|
|
|
|
u8SameGapCount = 0;
|
|
}
|
|
else
|
|
{
|
|
/* Crank sensor same gap */
|
|
u8SameGapCount++;
|
|
CEM_u8CrankEdgeCounter++;
|
|
}
|
|
|
|
|
|
if (31 == CEM_u8CrankEdgeCounter)
|
|
{
|
|
CEM_u32GlobalCycleFraction &= 0x10000;
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
CEM_u8CrankEdgeCounter = 1;
|
|
}
|
|
|
|
if (1 == CEM_u8PhaseRepeats)
|
|
{
|
|
if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[1])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0x4000, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[2])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0x8000, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[3])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, 0xc000, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
}
|
|
else if (2 == CEM_u8PhaseRepeats)
|
|
{
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[2])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[3])
|
|
{
|
|
CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase);
|
|
TEPM_vSynchroniseEventProgramKernelQueues();
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if ((1u != ((CEM_u8CrankEdgeCounter - u8PhasePrev) % CEM_xEdgesCount)) && (TRUE == boPhaseLocked))
|
|
{
|
|
CEM_vPhaseError(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool CEM_boGetLatePhaseSimpleCamSync(void)
|
|
{
|
|
bool boLatePhase;
|
|
IOAPI_tenTriState enTriState;
|
|
|
|
enTriState = IO_enGetDIOResourceState(stSimpleCamSync.enEHIOResource);
|
|
|
|
if (true == stSimpleCamSync.boCamSyncHighLate)
|
|
{
|
|
boLatePhase = (IOAPI_enHigh == enTriState);
|
|
}
|
|
else
|
|
{
|
|
boLatePhase = (IOAPI_enLow == enTriState);
|
|
}
|
|
|
|
return boLatePhase;
|
|
}
|
|
|
|
static void CEM_vPhaseError(int code_in)
|
|
{
|
|
/* TODO
|
|
volatile static int code;
|
|
code = code_in;
|
|
*/
|
|
CEM_u32CrankErrorCounts++;
|
|
}
|
|
|
|
|
|
static TEPMAPI_ttEventTime CEM_tCalculateGlobalTime(TEPMAPI_ttEventTime tEventTime, uint16 u16LastGapFraction, bool boGlobalTimeEnable)
|
|
{
|
|
TEPMAPI_ttEventTime tTemp;
|
|
TEPMAPI_ttEventTime tGlobalTimeNew = 0;
|
|
uint32 u32Temp;
|
|
|
|
tTemp = (tEventTime - CEM_tEventTimeLast) & TEPMHA_nCounterMask;
|
|
|
|
if (0xffff >= tTemp)
|
|
{
|
|
tGlobalTimeNew = (0x10000u * tTemp) / (uint32)u16LastGapFraction;
|
|
//tGlobalTimeNew = 220000;
|
|
}
|
|
else if (0xfffff >= tTemp)
|
|
{
|
|
u16LastGapFraction = u16LastGapFraction >> 4;
|
|
tGlobalTimeNew = (0x1000u * tTemp) / (uint32)u16LastGapFraction;
|
|
}
|
|
else if (0xffffff >= tTemp)
|
|
{
|
|
u16LastGapFraction = u16LastGapFraction >> 8;
|
|
tGlobalTimeNew = (0x100u * tTemp) / (uint32)u16LastGapFraction;
|
|
}
|
|
else if (0xfffffff >= tTemp)
|
|
{
|
|
u16LastGapFraction = u16LastGapFraction >> 12;
|
|
tGlobalTimeNew = (0x10u * tTemp) / (uint32)u16LastGapFraction;
|
|
}
|
|
else
|
|
{
|
|
CEM_u32GlobalCycleTime = ~0u;
|
|
}
|
|
|
|
if (TRUE == boGlobalTimeEnable)
|
|
{
|
|
if (TRUE == TPS_boThrottleClosed)
|
|
{
|
|
u32Temp = USERCAL_stRAMCAL.u16ESTFilterClosed * CEM_u32GlobalCycleTime;
|
|
u32Temp += ((0x100 - USERCAL_stRAMCAL.u16ESTFilterClosed) * tGlobalTimeNew);
|
|
u32Temp /= 0x100;
|
|
}
|
|
else
|
|
{
|
|
u32Temp = USERCAL_stRAMCAL.u16ESTFilterOpen * tGlobalTimeNew;
|
|
u32Temp += ((0x100 - (uint8)USERCAL_stRAMCAL.u16ESTFilterOpen) * CEM_u32GlobalCycleTime);
|
|
u32Temp /= 0x100;
|
|
}
|
|
|
|
CEM_u32GlobalCycleTime = u32Temp;
|
|
|
|
if (tGlobalTimeNew < CEM_u32GlobalCycleTime)
|
|
{
|
|
CEM_u32GlobalCycleTime--;
|
|
}
|
|
else if (tGlobalTimeNew > CEM_u32GlobalCycleTime)
|
|
{
|
|
CEM_u32GlobalCycleTime++;
|
|
}
|
|
}
|
|
|
|
return tTemp;
|
|
}
|
|
|
|
static void CEM_vSequenceReset(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime, uint32 u32OriginGlobalCycleFraction, bool boLatePhase)
|
|
{
|
|
uint32 u32Temp;
|
|
static uint32 u32SequenceIDX;
|
|
static IOAPI_tenTriState enTriState;
|
|
IOAPI_tenEHIOResource enLinkedResource;
|
|
|
|
CEM_tSyncTimeLast = tEventTime;
|
|
|
|
u32SequenceIDX++;
|
|
u32Temp = CEM_u32GlobalCycleTime / (4 * CEM_u8PhaseRepeats);
|
|
u32Temp = 0x10000 > u32Temp ? u32Temp : 0xffff;
|
|
|
|
if (1 == CEM_u8PhaseRepeats)
|
|
{
|
|
if (0 == u32OriginGlobalCycleFraction)
|
|
{
|
|
u32SequenceIDX = 0;
|
|
|
|
CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction;
|
|
CEM_u32GlobalCycleOriginCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (0 == u32OriginGlobalCycleFraction)
|
|
{
|
|
if (((0x10000 <= CEM_u32GlobalCycleFraction) && (false == boLatePhase)) ||
|
|
((0x10000 > CEM_u32GlobalCycleFraction) && (true == boLatePhase)))
|
|
{
|
|
CEM_u32CamErrorCounts++;
|
|
CEM_u32CamRunningErrorCounts = 5 > CEM_u32CamRunningErrorCounts ? CEM_u32CamRunningErrorCounts + 1 : 5;
|
|
}
|
|
|
|
|
|
if (5 == CEM_u32CamRunningErrorCounts)
|
|
/* Many cam errors */
|
|
{
|
|
//if (0 == (CEM_u32GlobalCycleOriginCount % 8))
|
|
if (true)
|
|
/* Try swap phase */
|
|
{
|
|
if (0x10000 > CEM_u32GlobalCycleFraction)
|
|
{
|
|
u32SequenceIDX = 4;
|
|
CEM_u32GlobalCycleFraction = 0x10000 + u32OriginGlobalCycleFraction;
|
|
}
|
|
else
|
|
{
|
|
u32SequenceIDX = 0;
|
|
CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction;
|
|
}
|
|
|
|
CEM_u32CamRunningErrorCounts = 0;
|
|
}
|
|
else
|
|
/* Keep phase and reset */
|
|
{
|
|
if (0x10000 <= CEM_u32GlobalCycleFraction)
|
|
{
|
|
u32SequenceIDX = 0;
|
|
CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction;
|
|
}
|
|
else
|
|
{
|
|
u32SequenceIDX = 4;
|
|
CEM_u32GlobalCycleFraction = 0x10000 + u32OriginGlobalCycleFraction;
|
|
}
|
|
}
|
|
}
|
|
else if ((0x10000 <= CEM_u32GlobalCycleFraction) && (true == boLatePhase))
|
|
{
|
|
u32SequenceIDX = 0;
|
|
CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction;
|
|
}
|
|
else
|
|
{
|
|
CEM_u32GlobalCycleFraction = 0x10000 + u32OriginGlobalCycleFraction;
|
|
}
|
|
|
|
CEM_u32GlobalCycleOriginCount++;
|
|
|
|
if (0 == (CEM_u32GlobalCycleOriginCount % 8))
|
|
{
|
|
CEM_u32CamRunningErrorCounts = 0 < CEM_u32CamRunningErrorCounts ? CEM_u32CamRunningErrorCounts - 1 : 0;
|
|
}
|
|
|
|
/* grab the primary linked resource for the phase tell-tale to slave uP */
|
|
enLinkedResource = TEPM_enGetPrimaryLinkedResource();
|
|
|
|
/* set the phase tell-tale */
|
|
enTriState = true == boLatePhase ? IOAPI_enHigh : IOAPI_enLow;
|
|
IO_vAssertDIOResource(enLinkedResource, enTriState);
|
|
}
|
|
}
|
|
|
|
|
|
if (1 < CEM_u32GlobalCycleOriginCount)//matthew
|
|
{
|
|
TEPM_vStartEventProgramKernelQueues(FALSE, u32SequenceIDX);
|
|
}
|
|
|
|
if ((0 == (0xffff & CEM_u32GlobalCycleFraction)) || (0x8000 == (0xffff & CEM_u32GlobalCycleFraction)))
|
|
{
|
|
TEPM_vInitiateUserCallBack(enEHIOResource, (uint16)u32Temp);
|
|
}
|
|
}
|
|
|
|
void CEM_vPhaseEventCB(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime)
|
|
{
|
|
IOAPI_tenTriState enTriState;
|
|
|
|
|
|
if (enEHIOResource == TEPM_astTEPMVVTInputs[0])
|
|
{
|
|
enTriState = IO_enGetDIOResourceState(enEHIOResource);
|
|
|
|
if (IOAPI_enLow == enTriState)
|
|
{
|
|
CEM_atLastVVTLowTime[0] = TEPMHA_nCounterMask & (tEventTime - CEM_atLastVVTTimer[0]);
|
|
}
|
|
else
|
|
{
|
|
CEM_atLastVVTHighTime[0] = TEPMHA_nCounterMask & (tEventTime - CEM_atLastVVTTimer[0]);
|
|
}
|
|
|
|
CEM_atLastVVTTimer[0] = tEventTime;
|
|
}
|
|
else if (enEHIOResource == TEPM_astTEPMVVTInputs[1])
|
|
{
|
|
|
|
}
|
|
else if (enEHIOResource == TEPM_astTEPMVVTInputs[2])
|
|
{
|
|
|
|
}
|
|
else if (enEHIOResource == TEPM_astTEPMVVTInputs[3])
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void CEM_vSetupSimpleCamSync(IOAPI_tenEHIOResource enEHIOResource, bool boCamSyncHighLate, uint32 u32CamSyncSampletoothCount)
|
|
{
|
|
stSimpleCamSync.enEHIOResource = enEHIOResource;
|
|
stSimpleCamSync.boCamSyncHighLate = boCamSyncHighLate;
|
|
stSimpleCamSync.u32CamSyncSampleToothCount = u32CamSyncSampletoothCount;
|
|
}
|
|
|
|
void CEM_vFreqEventCB(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime)
|
|
{
|
|
static uint32 u32OldOSTick;
|
|
volatile static uint32 samples[100];
|
|
static uint32 counter;
|
|
static uint32 u32TimeOld;
|
|
static uint32 u32Temp;
|
|
static uint32 u32ErrCount;
|
|
|
|
samples[counter] = (tEventTime - u32TimeOld) & TEPMHA_nCounterMask;
|
|
|
|
u32Temp -= 5;
|
|
u32Temp *= 2;
|
|
|
|
if ((u32Temp < samples[counter]) &&
|
|
(2 > u32ErrCount))
|
|
{
|
|
samples[counter] /= 2;
|
|
u32ErrCount++;
|
|
}
|
|
else
|
|
{
|
|
u32ErrCount = 0;
|
|
}
|
|
|
|
u32Temp = samples[counter];
|
|
|
|
if (OS_u32TickCounter > (u32OldOSTick + 1))
|
|
{
|
|
TEPM_vInitiateUserCallBack(enEHIOResource, samples[counter]);
|
|
u32OldOSTick = OS_u32TickCounter;
|
|
}
|
|
|
|
counter = (counter + 1) % 100;
|
|
u32TimeOld = tEventTime;
|
|
}
|