RabbitECUTeensyMCUXpresso/source/UserServices/TEPMHA.c

1411 lines
41 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: TEPM Hardware Abstraction */
/* DESCRIPTION: Timed Event Programs module provides services for the */
/* output of timed pulse-trains */
/* FILE NAME: TEPMHA.c */
/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */
/* */
/******************************************************************************/
#define _TEPMHA_C
#include "CPUAbstract.h"
#include <string.h>
#include "build.h"
#include "CEM.h"
#include "client.h"
#include "CPUAbstract.h"
#include "CQUEUE.h"
#include "declarations.h"
#include "stddef.h"
#include "types.h"
#include "IRQ.h"
#include "TEPM.h"
#include "TEPMHA.h"
#include "TEPMAPI.h"
#include "MSG.h"
#include "SIM.h"
#include "REGSET.h"
#include "RESM.h"
#include "IOAPI.h"
#include "SYSAPI.h"
//#pragma GCC optimize ("O0")
//#pragma optimize level=0
/* Private data declarations
-------------------------*/
const TEPM_tstTEPMChannel TEPMHA_rastTEPMChannel[] = TEPMHA_nChannelInfo;
const TEPM_tstTEPMReverseChannel TEPMHA_rastTEPMReverseChannel[] = TEPMHA_nChannelReverseInfo;
TEPMAPI_ttEventTime* TEPMHA_ptMasterClock;
#define TEPM_nTableCount sizeof(TEPMHA_rastTEPMChannel) / sizeof(TEPM_tstTEPMChannel)
/* Private function declarations
----------------------------*/
static void* TEPMHA_pvGetModule(IOAPI_tenEHIOResource);
#ifdef BUILD_SAM3X8E
static uint32 TEPMHA_pstGetFTMChannel(IOAPI_tenEHIOResource);
static void TEPMHA_vSyncModules(void);
static bool TEPMHA_boModuleIsTimer(void*);
static bool TEPMHA_boModuleIsPWM(void*);
static IOAPI_tenEHIOResource TEPMHA_enGetParentResourceFromVIO(IOAPI_tenEHIOResource);
#endif //BUILD_SAM3X8E
static TEPMHA_tenTimerModule TEPMHA_enGetEnumFromVIO(IOAPI_tenEHIOResource);
/* Public function definitions
---------------------------*/
void TEPMHA_vInitTEPMChannel(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMChannelCB* pstTEPMChannelCB)
{
#if defined(BUILD_MK60) || defined(BUILD_MK64)
vpuint32 vpuFTMReg;
uint32 u32ControlWord = 0;
tstTimerModule* pstTimerModule;
uint32 u32ChannelIDX;
uint32 u32TableIDX;
pstTimerModule = TEPMHA_pvGetModule(enEHIOResource);
u32ChannelIDX = TEPMHA_u32GetTimerHardwareChannel(enEHIOResource);
vpuFTMReg = (vpuint32)((uint32)pstTimerModule + (uint32)offsetof(tstTimerModule, CONTROLS[u32ChannelIDX]));
switch (pstTEPMChannelCB->enAction)
{
case TEPMAPI_enSetHigh:
u32ControlWord |=
(FTM_CnSC_MSA_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK); break;
case TEPMAPI_enSetLow:
u32ControlWord |=
(FTM_CnSC_MSA_MASK | FTM_CnSC_ELSB_MASK); break;
case TEPMAPI_enToggle: u32ControlWord |=
(FTM_CnSC_MSA_MASK | FTM_CnSC_ELSA_MASK); break;
case TEPMAPI_enCapRising: u32ControlWord |=
(FTM_CnSC_ELSA_MASK); break;
case TEPMAPI_enCapFalling: u32ControlWord |=
(FTM_CnSC_ELSB_MASK); break;
case TEPMAPI_enCapAny: u32ControlWord |=
(FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK); break;
default: break;
}
u32ControlWord = (TRUE == pstTEPMChannelCB->boInterruptEnable) ?
u32ControlWord | FTM_CnSC_CHIE_MASK : u32ControlWord;
*vpuFTMReg = u32ControlWord;
u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
if (TRUE == pstTEPMChannelCB->boInterruptEnable)
{
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32TableIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL);
}
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
tstTimerModule* pstTimerModule;
vpuint32 vpuFTMReg;
uint32 u32ChannelIDX;
uint32 u32ChannelSubIDX;
uint32 u32ControlWord = 0;
pwm_channel_t stPWMChannelCB;
tstPWMModule* pstPWMModule;
u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
if (TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType == TEPMHA_enCapCom)
{
/* If this resource is associated with a timer module */
pstTimerModule = (tstTimerModule*)TEPMHA_pvGetModule(enEHIOResource);
switch (pstTEPMChannelCB->enAction)
{
case TEPMAPI_enSetHigh:
{
u32ControlWord = pstTimerModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_CMR;
if (0 == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel)
{
u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4;
u32ControlWord |= TC_CMR_ACPA_SET;
u32ControlWord |= TC_CMR_WAVE;
tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord);
tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2);
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL);
}
else
{
u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4;
u32ControlWord |= TC_CMR_BCPB_SET;
u32ControlWord |= TC_CMR_WAVE;
tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord);
tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2);
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL);
}
break;
}
case TEPMAPI_enSetLow:
{
u32ControlWord = pstTimerModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_CMR;
if (0 == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel)
{
u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4;
u32ControlWord |= TC_CMR_WAVE; /* Waveform mode is enabled */
u32ControlWord |= TC_CMR_ACPA_CLEAR;
tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord);
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL);
tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2);
}
else
{
u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4;
u32ControlWord |= TC_CMR_WAVE; /* Waveform mode is enabled */
u32ControlWord |= TC_CMR_BCPB_CLEAR;
u32ControlWord |= TC_CMR_EEVT_XC0;
tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord);
//tc_enable_interrupt(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, TC_SR_CPBS);
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL);
tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2);
}
break;
}
case TEPMAPI_enToggle: u32ControlWord = 0; break;
case TEPMAPI_enCapRising:
{
u32ControlWord = TC_CMR_LDRA_RISING | TC_CMR_LDRB_RISING | TC_CMR_TCCLKS_TIMER_CLOCK4;
tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord);
tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2);
tc_enable_interrupt(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, TC_SR_LDRAS | TC_SR_LDRBS);
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_3, TEPM_vInterruptHandler, NULL);
TEPMHA_ptMasterClock = &(pstTimerModule->TC_CHANNEL[u32ChannelIDX].TC_CV);
break;
}
case TEPMAPI_enCapFalling: u32ControlWord = 0; break;
case TEPMAPI_enCapAny://matthew problem here
{
//u32ControlWord = TC_CMR_LDRA_RISING | TC_CMR_LDRB_FALLING | TC_CMR_TCCLKS_TIMER_CLOCK4;
u32ControlWord = TC_CMR_LDRA_EDGE | TC_CMR_LDRB_EDGE | TC_CMR_TCCLKS_TIMER_CLOCK4;
tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord);
tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2);
tc_enable_interrupt(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, TC_SR_LDRAS | TC_SR_LDRBS);
IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_3, TEPM_vInterruptHandler, NULL);
TEPMHA_ptMasterClock = &(pstTimerModule->TC_CHANNEL[u32ChannelIDX].TC_CV);
break;
}
default:
{
break;
}
TEPMHA_vSyncModules();
}
}
else if (TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType == TEPMHA_enPWM)
{
/* If this resource is associated with a PWM module */
pstPWMModule = (tstPWMModule*)TEPMHA_pvGetModule(enEHIOResource);
memset(&stPWMChannelCB, 0, sizeof(pwm_channel_t));
stPWMChannelCB.channel = TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel;
stPWMChannelCB.polarity = PWM_LOW;
//stPWMChannelCB.alignment = PWM_ALIGN_CENTER;
stPWMChannelCB.ul_prescaler = 0x0c;//pstTEPMChannelCB->enPreScalar;
pwm_channel_init(pstPWMModule, &stPWMChannelCB);
}
#endif //BUILD_SAM3X8E
}
SYSAPI_tenSVCResult TEPMHA_vInitTEPMResource(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMResourceCB* pstTEPMResourceCB)
{
tstTimerModule* pstTimerModule = NULL;
REGSET_tstReg32Val astTEPMReg32Val[2];
#if defined(BUILD_MK60) || defined(BUILD_MK64)
switch (enEHIOResource)
{
case EH_VIO_FTM0:
{
pstTimerModule = FTM0;
break;
}
case EH_VIO_FTM1:
{
pstTimerModule = FTM1;
break;
}
case EH_VIO_FTM2:
{
pstTimerModule = FTM2;
break;
}
case EH_VIO_FTM3:
{
pstTimerModule = FTM3;
break;
}
default:
{
pstTimerModule = NULL;
break;
}
}
TEPMHA_xRequestPortClock(pstTimerModule);
astTEPMReg32Val[0].reg = (vpuint32)(pstTimerModule + offsetof(tstTimerModule, SC));
astTEPMReg32Val[0].val = (uint32)(FTM_SC_PS(pstTEPMResourceCB->enPreScalar) | FTM_SC_CLKS(1) |
(pstTEPMResourceCB->enCountType << FTM_SC_CPWMS_SHIFT));
astTEPMReg32Val[0].writeMode = REGSET_enOverwrite;
astTEPMReg32Val[1].reg = NULL;
REGSET_vInitReg32(&astTEPMReg32Val[0]);
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
tstPWMModule* pstPWMModule = NULL;
pwm_clock_t stPWMClockConfig;
switch (enEHIOResource)
{
case EH_VIO_TC0:
{
pstTimerModule = TC0;
break;
}
case EH_VIO_TC1:
{
pstTimerModule = TC1;
break;
}
case EH_VIO_TC2:
{
pstTimerModule = TC2;
break;
}
case EH_VIO_PWM:
{
pstPWMModule = PWM;
break;
}
default:
{
break;
}
}
if (NULL != pstTimerModule)
{
TEPMHA_xRequestTimerClock(pstTimerModule);
}
else if (NULL != pstPWMModule)
{
TEPMHA_xRequestPWMClock(pstPWMModule);
stPWMClockConfig.ul_mck = SYS_FREQ_BUS;
stPWMClockConfig.ul_clka = SYS_FREQ_BUS / pstTEPMResourceCB->enPreScalar;
stPWMClockConfig.ul_clkb = SYS_FREQ_BUS / pstTEPMResourceCB->enPreScalar;
pwm_init(pstPWMModule, &stPWMClockConfig);
IRQ_vEnableIRQ(PWM_IRQn, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL);
}
#endif //BUILD_MK60
return SYSAPI_enOK;
}
void TEPMHA_vForceQueueTerminate(void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX)
{
volatile TEPMAPI_ttEventTime tEventTimeScheduled;
volatile TEPMAPI_ttEventTime tEventTimeRemains;
uint32 u32Temp;
tstTimerModule* pstTimerModule;
CPU_xEnterCritical();
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
pstTimerModule = (tstTimerModule*)pvModule;
u32Temp = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC & ~FTM_CnSC_CHIE_MASK;
u32Temp &= ~FTM_CnSC_CHF_MASK;
tEventTimeRemains = (0xffff & pstTimerModule->CONTROLS[u32ChannelIDX].CnV) -
(0xffff & pstTimerModule->CNT);
if (0 < tEventTimeRemains)
{
tEventTimeScheduled = pstTimerModule->CNT + 2;
tEventTimeScheduled &= TEPMHA_nCounterMask;
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp;
/* Force it now! */
while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != tEventTimeScheduled)
{
pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled;
}
/* Wait for it! Dangerous!!!*/
//while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != pstTimerModule->CNT){}
}
else
{
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp;
}
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
volatile u32Stat;
uint32 u32ControlWord;
pstTimerModule = (tstTimerModule*)pvModule;
sint32 s32ExitLoops = 100;
if (0 == u32SubChannelIDX)
{
TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, u32SubChannelIDX, tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 10);
tc_disable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPAS);
u32Stat = 0;
tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
while (0 != (0x80000000 & tEventTimeRemains))
{
tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
}
while ((0 == (u32Stat & TC_SR_CPAS)) && (0 < s32ExitLoops))
{
u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2);
s32ExitLoops--;
}
/*
u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR;
u32ControlWord &= ~TC_CMR_ACPA_TOGGLE;
u32ControlWord |= TC_CMR_ACPA_CLEAR;
pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord;
u32Stat = 0;
tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
* If already past then force again *
if ((UINT32_MAX / 2) < tEventTimeRemains)
{
tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120;
tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
* If is not too close then reschedule very close *
if (((UINT32_MAX / 2) > tEventTimeRemains) &&
(tEventTimeRemains > 50))
{
tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120;
tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
while (0 == (u32Stat & TC_SR_CPAS))
{
u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2);
tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
if ((UINT32_MAX / 2) < tEventTimeRemains) break;
}*/
}
else
{
TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, u32SubChannelIDX, tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 10);
tc_disable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPBS);
u32Stat = 0;
tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
while (0 == (0x80000000 & tEventTimeRemains))
{
tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
}
while ((0 == (u32Stat & TC_SR_CPBS)) && (0 < s32ExitLoops))
{
u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2);
s32ExitLoops--;
}
/*
u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR;
u32ControlWord &= ~TC_CMR_BCPB_TOGGLE;
u32ControlWord |= TC_CMR_BCPB_CLEAR;
pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord;
u32Stat = 0;
tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
* If already past then force again *
if ((UINT32_MAX / 2) < tEventTimeRemains)
{
tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120;
tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
* If is not too close then reschedule very close *
if (((UINT32_MAX / 2) > tEventTimeRemains) &&
(tEventTimeRemains > 50))
{
tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120;
tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
while (0 == (u32Stat & TC_SR_CPBS))
{
u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2);
tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
if ((UINT32_MAX / 2) < tEventTimeRemains) break;
}*/
}
#endif //BUILD_SAM3X8E
CPU_xExitCritical();
}
bool TEPMHA_boCheckFalseAlarm(void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX)
{
bool boFalseAlarm = FALSE;
#ifdef BUILD_SAM3X8E
uint32 u32Delay;
tstTimerModule* pstTimerModule = (tstTimerModule*)pvModule;
if (0 == u32SubChannelIDX)
{
u32Delay = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
if ((UINT32_MAX / 2) > u32Delay)
{
boFalseAlarm = TRUE;
}
}
else
{
u32Delay = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) -
tc_read_cv(pstTimerModule, u32ChannelIDX / 2);
if ((UINT32_MAX / 2) > u32Delay)
{
boFalseAlarm = TRUE;
}
}
#endif
return boFalseAlarm;
}
void TEPMHA_vCapComAction(TEPMAPI_tenAction enAction, void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX, TEPMAPI_ttEventTime tEventTimeScheduled)
{
uint32 u32Temp;
tstTimerModule* pstTimerModule;
switch (enAction)
{
case TEPMAPI_enSetHigh:
{
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
pstTimerModule = (tstTimerModule*)pvModule;
u32Temp = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_CHIE_MASK;
u32Temp &= ~FTM_CnSC_CHF_MASK;
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp;
while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != tEventTimeScheduled)
{
pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled;
}
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
uint32 u32ControlWord;
if (TRUE == TEPMHA_boModuleIsTimer(pvModule))
{
pstTimerModule = (tstTimerModule*)pvModule;
u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR;
if (0 == u32SubChannelIDX)
{
tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
u32ControlWord &= ~TC_CMR_ACPA_CLEAR;
u32ControlWord |= TC_CMR_ACPA_SET;
pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord;
tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPAS);
//tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
else if (1 == u32SubChannelIDX)
{
tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
u32ControlWord &= ~TC_CMR_BCPB_CLEAR;
u32ControlWord |= TC_CMR_BCPB_SET;
pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord;
tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPBS);
//tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
}
else if (TRUE == TEPMHA_boModuleIsPWM(pvModule))
{
tstPWMModule* pstPWMModule;
TEPMAPI_ttEventTime tEventTime;
uint32 u32Temp;
pwm_channel_t stPWMChannel;
pstPWMModule = (tstPWMModule*)pvModule;
//u32Temp = pwm_channel_get_status(pstPWMModule);
tEventTime = tEventTimeScheduled - *TEPMHA_ptMasterClock;
memset(&stPWMChannel, 0, sizeof(pwm_channel_t));
stPWMChannel.channel = u32ChannelIDX;
pwm_channel_enable(pstPWMModule, u32ChannelIDX);
//pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CCNT + 2;
while (pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CCNT > 5)
{
pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CDTY = 1;
pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = 10;
}
pwm_channel_update_period(pstPWMModule, &stPWMChannel, 6000u);
pwm_channel_update_duty(pstPWMModule, &stPWMChannel, 4000u);
//pwm_channel_update_period(pstPWMModule, &stPWMChannel, 5000u);
//pwm_channel_update_duty(pstPWMModule, &stPWMChannel, 2000u);
//pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CDTY = 5;
//pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = 10;
//pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = 5000;
//pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CDTY = 1000;
//if (0 == ((1 << u32ChannelIDX) & u32Temp))
{
}
}
#endif //BUILD_SAM3X8E
break;
}
case TEPMAPI_enSetLow:
{
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
pstTimerModule = (tstTimerModule*)pvModule;
u32Temp = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC | FTM_CnSC_CHIE_MASK;
u32Temp &= ~FTM_CnSC_CHF_MASK;
u32Temp &= ~(FTM_CnSC_ELSA_MASK);
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp;
while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != tEventTimeScheduled)
{
pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled;
}
//pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp;
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
if (TRUE == TEPMHA_boModuleIsTimer(pvModule))
{
pstTimerModule = (tstTimerModule*)pvModule;
u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR;
if (0 == u32SubChannelIDX)
{
u32ControlWord &= ~TC_CMR_ACPA_SET;
u32ControlWord |= TC_CMR_ACPA_CLEAR;
pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord;
tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPAS);
tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
else if (1 == u32SubChannelIDX)
{
u32ControlWord &= ~TC_CMR_BCPB_SET;
u32ControlWord |= TC_CMR_BCPB_CLEAR;
pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord;
tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPBS);
tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled);
}
}
else if (TRUE == TEPMHA_boModuleIsPWM(pvModule))
{
}
#endif //BUILD_SAM3X8E
break;
}
case TEPMAPI_enToggle:
{
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
pstTimerModule = (tstTimerModule*)pvModule;
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC |= (FTM_CnSC_ELSA_MASK | FTM_CnSC_CHIE_MASK);
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC &= ~FTM_CnSC_ELSB_MASK;
pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled;
#endif //BUILD_MK6X
break;
}
case TEPMAPI_enEndProgram:
{
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
pstTimerModule = (tstTimerModule*)pvModule;
pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC;
pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled;
#endif //BUILD_MK6X
break;
}
default:
{
break;
}
}
}
static void* TEPMHA_pvGetModule(IOAPI_tenEHIOResource enEHIOResource)
{
uint32 u32ChannelIDX;
void* pvModule;
u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
pvModule = TEPMHA_pvGetModuleFromEnum(TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule);
return pvModule;
}
void* TEPMHA_pvGetModuleFromEnum(TEPMHA_tenTimerModule enTimerModule)
{
void* pvModule;
#ifdef BUILD_MK60
switch (enTimerModule)
{
case FTM_enFTM0: pvModule = (tstTimerModule*)FTM0; break;
case FTM_enFTM1: pvModule = (tstTimerModule*)FTM1; break;
case FTM_enFTM2: pvModule = (tstTimerModule*)FTM2; break;
case FTM_enFTM3: pvModule = (tstTimerModule*)FTM3; break;
default: pvModule = NULL; break;
}
#endif //BUILD_MK60
#ifdef BUILD_MK64
switch (enTimerModule)
{
case FTM_enFTM0: pvModule = (tstTimerModule*)FTM0; break;
case FTM_enFTM1: pvModule = (tstTimerModule*)FTM1; break;
case FTM_enFTM2: pvModule = (tstTimerModule*)FTM2; break;
case FTM_enFTM3: pvModule = (tstTimerModule*)FTM3; break;
default: pvModule = NULL; break;
}
#endif //BUILD_MK64
#ifdef BUILD_SAM3X8E
switch (enTimerModule)
{
case TEPMHA_enTC0: pvModule = (void*)TC0; break;
case TEPMHA_enTC1: pvModule = (void*)TC1; break;
case TEPMHA_enTC2: pvModule = (void*)TC2; break;
case TEPMHA_enPWM0: pvModule = (void*)PWM; break;
default: pvModule = NULL; break;
}
#endif //BUILD_SAMX3X8E
return pvModule;
}
uint32 TEPMHA_u32GetFTMTableIndex(IOAPI_tenEHIOResource enEHIOResource)
{
uint32 u32TableIDX = 0;
#ifdef BUILD_MK60
if ((EH_IO_TMR16 >= enEHIOResource) && (EH_IO_TMR1 <= enEHIOResource))
{
u32ChannelIDX = enEHIOResource - EH_IO_TMR1;
}
else
{
switch (enEHIOResource)
{
case EH_IO_ADSE4: u32ChannelIDX = 16; break;
case EH_IO_GPSE9: u32ChannelIDX = 16; break;
case EH_IO_GPSE8: u32ChannelIDX = 16; break;
case EH_IO_ADSE5: u32ChannelIDX = 16; break;
case EH_IO_GPSE7: u32ChannelIDX = 16; break;
case EH_IO_CAN1T: u32ChannelIDX = 16; break;
case EH_IO_CAN1R: u32ChannelIDX = 16; break;
}
}
#endif //BUILD_MK60
#ifdef BUILD_MK64
if ((EH_IO_TMR18 >= enEHIOResource) && (EH_IO_TMR1 <= enEHIOResource))
{
u32TableIDX = enEHIOResource - EH_IO_TMR1;
}
else
{
u32TableIDX = ~0;
}
#endif //BUILD_MK64
#ifdef BUILD_SAM3X8E
if ((EH_IO_TMR12 >= enEHIOResource) && (EH_IO_TMR1 <= enEHIOResource))
{
u32ChannelIDX = enEHIOResource - EH_IO_TMR1;
}
else if (EH_IO_ADD5 == enEHIOResource)
{
u32ChannelIDX = 12;
}
else if (EH_IO_ADD7 == enEHIOResource)
{
u32ChannelIDX = 13;
}
else if (EH_IO_ADD8 == enEHIOResource)
{
u32ChannelIDX = 14;
}
else if (EH_IO_EXTINT == enEHIOResource)
{
u32ChannelIDX = 15;
}
#endif //BUILD_SAM3X8E
return u32TableIDX;
}
bool TEPMHA_boFlagIsSet(void* pvModule, uint32 u32ChannelIDX, puint32 pu32Flags, uint32 u32Sequence, uint32 u32Prio)
{
bool boFlagIsSet = false;
tstTimerModule* pstTimerModule;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
pstTimerModule = (tstTimerModule*)pvModule;
boFlagIsSet = (FTM_CnSC_CHF_MASK == (FTM_CnSC_CHF_MASK & pstTimerModule->CONTROLS[u32ChannelIDX].CnSC));
#endif //BUILD_MK60
#ifdef BUILD_SAM3X8E
static uint32 u32Seq[2];
static uint32 u32FlagsCache[9]; /* Once the flags are read they are cleared so cache them */
uint32 u32CacheIndex = 0;
uint32 u32CMR;
bool boWaveMode;
tstPWMModule* pstPWMModule;
if ((TC0 == (tstTimerModule*)pvModule) ||
(TC1 == (tstTimerModule*)pvModule) ||
(TC2 == (tstTimerModule*)pvModule))
{
pstTimerModule = (tstTimerModule*)pvModule;
switch ((uint32)pstTimerModule)
{
case (uint32)TC0: u32CacheIndex = (u32ChannelIDX / 2); break;
case (uint32)TC1: u32CacheIndex = 3 + (u32ChannelIDX / 2); break;
case (uint32)TC2: u32CacheIndex = 6 + (u32ChannelIDX / 2); break;
}
if (u32Seq[u32Prio] != u32Sequence)
{
u32FlagsCache[u32CacheIndex] = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_SR;
u32Seq[u32Prio] = u32Sequence;
}
u32CMR = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR;
if (0 == u32FlagsCache[u32CacheIndex])
{
u32FlagsCache[u32CacheIndex] = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_SR;
}
*pu32Flags = u32FlagsCache[u32CacheIndex];
boWaveMode = TC_CMR_WAVE == (u32CMR & TC_CMR_WAVE) ? TRUE : FALSE;
if (0 == (u32ChannelIDX & 0x1))
{
/* Is channel A? */
if (FALSE == boWaveMode)
{
boFlagIsSet = 0 != (*pu32Flags & (TC_SR_LDRAS | TC_SR_LDRBS)) ?
TRUE : FALSE;
}
else
{
boFlagIsSet = 0 != (*pu32Flags & TC_IMR_CPAS) ? TRUE : FALSE;
}
}
else
{
/* Is channel B? */
if (FALSE == boWaveMode)
{
/* There is no input capture on the physical B channel */
boFlagIsSet = FALSE;
}
else
{
boFlagIsSet = 0 != (*pu32Flags & TC_IMR_CPBS) ? TRUE : FALSE;
}
}
}
else if (PWM == (tstPWMModule*)pvModule)
{
boFlagIsSet = TRUE;
}
#endif //BUILD_SAM3X8E
return boFlagIsSet;
}
bool TEMPHA_boInterruptEnabled(void* pvModule, uint32 u32ChannelIDX)
{
bool boEnableSet = false;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
boEnableSet = (FTM_CnSC_CHIE_MASK == (FTM_CnSC_CHIE_MASK & ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC));
#endif
#ifdef BUILD_SAM3X8E
if (TRUE == TEPMHA_boModuleIsTimer(pvModule))
{
tstTimerModule* pstModule = (tstTimerModule*)pvModule;
if (0 == (u32ChannelIDX & 0x01))
{
boEnableSet = 0 != (pstModule->TC_CHANNEL[u32ChannelIDX / 2].TC_IMR & (TC_IMR_LDRAS | TC_IMR_CPAS)) ?
TRUE : FALSE;
}
else
{
boEnableSet = 0 != (pstModule->TC_CHANNEL[u32ChannelIDX / 2].TC_IMR & (TC_IMR_LDRBS | TC_IMR_CPBS)) ?
TRUE : FALSE;
}
}
else if (TRUE == TEPMHA_boModuleIsPWM(pvModule))
{
}
#endif //BUILD_SAM3X8E
return boEnableSet;
}
TEPMAPI_ttEventTime TEPMHA_tGetScheduledVal(void* pvModule, uint32 u32ChannelIDX, bool boInputMode, uint32 u32Flags)
{
TEPMAPI_ttEventTime tEventTime = 0;
#if defined(BUILD_MK60) || defined(BUILD_MK64)
tEventTime = ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnV;
#endif
#ifdef BUILD_SAM3X8E
if (TRUE == TEPMHA_boModuleIsTimer(pvModule))
{
if (TRUE == boInputMode)
{
if (0 != (u32Flags & TC_SR_LDRAS))
{
tEventTime = tc_read_ra((tstTimerModule*)pvModule, u32ChannelIDX / 2);
}
if (0 != (u32Flags & TC_SR_LDRBS))
{
tEventTime = tc_read_rb((tstTimerModule*)pvModule, u32ChannelIDX / 2);
}
}
else
{
if (0 == (u32ChannelIDX & 0x01))
{
tEventTime = tc_read_ra((tstTimerModule*)pvModule, u32ChannelIDX / 2);
}
else
{
tEventTime = tc_read_rb((tstTimerModule*)pvModule, u32ChannelIDX / 2);
}
}
}
else if (TRUE == TEPMHA_boModuleIsPWM(pvModule))
{
}
#endif //BUILD_SAM3X8E
return tEventTime;
}
IOAPI_tenTriState TEPMHA_enGetTimerDigitalState(IOAPI_tenEHIOResource enEHIOResource)
{
IOAPI_tenTriState enTriState = IOAPI_enError;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(MK10)
enTriState = IO_enGetDIOResourceState(enEHIOResource);
#endif
#ifdef BUILD_SAM3X8E
uint32 u32ChannelIDX;
void* pvModule;
u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
pvModule = TEPMHA_pvGetModuleFromEnum(TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule);
if (((EH_IO_TMR1 <= enEHIOResource) && (EH_IO_TMR12 >= enEHIOResource)) ||
(EH_IO_ADD5 == enEHIOResource) ||
(EH_IO_EXTINT == enEHIOResource) ||
(EH_IO_ADD6 == enEHIOResource) ||
(EH_IO_ADD7 == enEHIOResource))
{
if (TRUE == TEPMHA_boModuleIsTimer(pvModule))
{
tstTimerModule* pstModule = (tstTimerModule*)pvModule;
if (0 == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel)
{
enTriState = 0 != (pstModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_SR & TC_SR_MTIOA) ?
IOAPI_enHigh : IOAPI_enLow;
}
else
{
enTriState = 0 != (pstModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_SR & TC_SR_MTIOB) ?
IOAPI_enHigh : IOAPI_enLow;
}
}
}
#endif
return enTriState;
}
void TEMPHA_vResetTimerFlag(void* pvModule, uint32 u32ChannelIDX)
{
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC &= ~FTM_CnSC_CHF_MASK;
#endif
}
uint32 TEPMHA_u32GetFreeVal(void* pvModule, uint32 u32ChannelIDX)
{
uint32 u32FreeVal;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
u32FreeVal = ((tstTimerModule*)pvModule)->CNT;
#endif
#ifdef BUILD_SAM3X8E
if (TRUE == TEPMHA_boModuleIsTimer(pvModule))
{
u32FreeVal = ((tstTimerModule*)pvModule)->TC_CHANNEL[u32ChannelIDX / 2].TC_CV;
}
#endif
return u32FreeVal;
}
void TEPMHA_vDisconnectEnable(void* pvModule, uint32 u32ChannelIDX)
{
uint32 u32Temp;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
u32Temp = ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC;
u32Temp &= ~FTM_CnSC_CHIE_MASK;
((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC = u32Temp;
#endif //BUILD_MK6X
}
TEPMAPI_ttEventTime TEPMHA_u32GetTimerVal(IOAPI_tenEHIOResource enEHIOResource)
{
tstTimerModule* pstTimerModule;
TEPMAPI_ttEventTime tEventTime = 0;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
uint32 u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
pstTimerModule = (tstTimerModule*)TEPMHA_pvGetModuleFromEnum(TEPMHA_rastTEPMChannel[u32TableIDX].enModule);
tEventTime = pstTimerModule->CONTROLS[TEPMHA_rastTEPMChannel[u32TableIDX].u32Channel].CnSC;
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
pstTimerModule = TEPMHA_pvGetTimerModuleFromVIO(enEHIOResource);
tEventTime = pstTimerModule->TC_CHANNEL[0].TC_CV;
#endif //BUILD_SAM3X8E
return tEventTime;
}
void* TEPMHA_pvGetTimerModuleFromVIO(IOAPI_tenEHIOResource enEHIOResource)
{
void* pvModule;
switch(enEHIOResource)
{
#if defined(BUILD_MK60) || defined(BUILD_MK64)
case EH_VIO_FTM0: pvModule = (tstTimerModule*)FTM0; break;
case EH_VIO_FTM1: pvModule = (tstTimerModule*)FTM1; break;
case EH_VIO_FTM2: pvModule = (tstTimerModule*)FTM2; break;
case EH_VIO_FTM3: pvModule = (tstTimerModule*)FTM3; break;
#endif //BUILD_MK60X
#ifdef BUILD_SAM3X8E
case EH_VIO_TC0: pvModule = (tstTimerModule*)TC0; break;
case EH_VIO_TC1: pvModule = (tstTimerModule*)TC1; break;
case EH_VIO_TC2: pvModule = (tstTimerModule*)TC2; break;
case EH_VIO_TCC0: pvModule = (tstTimerModule*)TC0; break;
case EH_VIO_TCC1: pvModule = (tstTimerModule*)TC0; break;
case EH_VIO_TCC2: pvModule = (tstTimerModule*)TC0; break;
case EH_VIO_TCC3: pvModule = (tstTimerModule*)TC1; break;
case EH_VIO_TCC4: pvModule = (tstTimerModule*)TC1; break;
case EH_VIO_TCC5: pvModule = (tstTimerModule*)TC1; break;
case EH_VIO_TCC6: pvModule = (tstTimerModule*)TC2; break;
case EH_VIO_TCC7: pvModule = (tstTimerModule*)TC2; break;
case EH_VIO_TCC8: pvModule = (tstTimerModule*)TC2; break;
case EH_VIO_PWM: pvModule = (tstPWMModule*)PWM; break;
#endif
default: pvModule = NULL; break;
}
return pvModule;
}
#ifdef BUILD_SAM3X8E
static uint32 TEPMHA_pstGetFTMChannel(IOAPI_tenEHIOResource enEHIOResource)
{
uint32 u32ChannelIDX;
u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
return TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel;
}
#endif //BUILD_SAM3X8E
uint32 TEPMHA_u32GetTimerChannelsPerInterruptGroup(void* pvModule)
{
uint32 u32ChannelCount = 0;
#if defined(BUILD_MK60)
u32ChannelCount = 8;
#endif //BUILD_MK60
#if defined(BUILD_MK64)
if (FTM0 == pvModule) u32ChannelCount = 8;
if (FTM1 == pvModule) u32ChannelCount = 8;
if (FTM2 == pvModule) u32ChannelCount = 2;
if (FTM3 == pvModule) u32ChannelCount = 8;
#endif //BUILD_MK64
#ifdef BUILD_SAM3X8E
u32ChannelCount = 2;
#endif //BUILD_SAM3X8E
return u32ChannelCount;
}
IOAPI_tenEHIOResource TEPMHA_enGetTimerResourceFromVIOAndIndex(IOAPI_tenEHIOResource enEHIOResource, uint32 u32Channel)
{
IOAPI_tenEHIOResource enChannelEHIOResource = EH_IO_Invalid;
uint32 u32Temp;
#if defined(BUILD_MK60)
TEPMHA_tenTimerModule enModule = TEPMHA_enGetEnumFromVIO(enEHIOResource);
for (u32ChannelIDX = 0; u32ChannelIDX < TEPMHA_nEventChannels; u32ChannelIDX++)
{
if ((enModule == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule) &&
u32Channel == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel &&
(TEPMHA_enCapCom == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType))
{
enChannelEHIOResource = TEPMHA_rastTEPMChannel[u32ChannelIDX].enEHIOResource;
break;
}
}
#endif
#if defined (BUILD_MK64)
u32Temp = 8 * TEPMHA_enGetEnumFromVIO(enEHIOResource) + u32Channel;
enChannelEHIOResource = TEPMHA_rastTEPMReverseChannel[u32Temp].enEHIOResource;
#endif
#ifdef BUILD_SAM3X8E
uint32 u32ChannelIDX;
TEPMHA_tenTimerModule enModule = TEPMHA_enGetEnumFromVIO(enEHIOResource);
for (u32ChannelIDX = 0; u32ChannelIDX < TEPMHA_nEventChannels; u32ChannelIDX++)
{
if ((enModule == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule) &&
(u32Channel == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel + TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel) &&
(TEPMHA_enCapCom == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType))
{
enChannelEHIOResource = TEPMHA_rastTEPMChannel[u32ChannelIDX].enEHIOResource;
break;
}
}
#endif //BUILD_SAM3X8E
return enChannelEHIOResource;
}
#ifdef BUILD_SAM3X8E
static IOAPI_tenEHIOResource TEPMHA_enGetParentResourceFromVIO(IOAPI_tenEHIOResource enEHIOResource)
{
IOAPI_tenEHIOResource enParentVIOResource = EH_IO_Invalid;
switch (enEHIOResource)
{
case EH_VIO_TCC0: enParentVIOResource = EH_VIO_TC0; break;
case EH_VIO_TCC1: enParentVIOResource = EH_VIO_TC0; break;
case EH_VIO_TCC2: enParentVIOResource = EH_VIO_TC0; break;
case EH_VIO_TCC3: enParentVIOResource = EH_VIO_TC1; break;
case EH_VIO_TCC4: enParentVIOResource = EH_VIO_TC1; break;
case EH_VIO_TCC5: enParentVIOResource = EH_VIO_TC1; break;
case EH_VIO_TCC6: enParentVIOResource = EH_VIO_TC2; break;
case EH_VIO_TCC7: enParentVIOResource = EH_VIO_TC2; break;
case EH_VIO_TCC8: enParentVIOResource = EH_VIO_TC2; break;
default : enParentVIOResource = EH_IO_Invalid; break;
}
return enParentVIOResource;
}
#endif //BUILD_SAM3X8E
uint32 TEPMHA_u32GetTimerStartChannelInterruptGroup(IOAPI_tenEHIOResource enEHIOResource)
{
uint32 u32StartChannel;
#ifdef BUILD_SAM3X8E
switch (enEHIOResource)
{
case EH_VIO_TCC0: u32StartChannel = 0; break;
case EH_VIO_TCC1: u32StartChannel = 2; break;
case EH_VIO_TCC2: u32StartChannel = 4; break;
case EH_VIO_TCC3: u32StartChannel = 0; break;
case EH_VIO_TCC4: u32StartChannel = 2; break;
case EH_VIO_TCC5: u32StartChannel = 4; break;
case EH_VIO_TCC6: u32StartChannel = 0; break;
case EH_VIO_TCC7: u32StartChannel = 2; break;
case EH_VIO_TCC8: u32StartChannel = 4; break;
default : u32StartChannel = 0; break;
}
#endif //BUILD_SAM3X8E
#if defined(BUILD_MK60) || defined(BUILD_MK64)
u32StartChannel = 0;
#endif
return u32StartChannel;
}
uint32 TEPMHA_u32GetTimerHardwareSubChannel(uint32 u32TableIndex)
{
uint32 u32ChannelSubIDX = 0;
#ifdef BUILD_SAM3X8E
u32ChannelSubIDX = TEPMHA_rastTEPMChannel[u32TableIndex].u32SubChannel;
#endif //BUILD_SAM3X8E
return u32ChannelSubIDX;
}
uint32 TEPMHA_u32GetTimerHardwareChannel(IOAPI_tenEHIOResource enEHIOResource)
{
#if defined(BUILD_MK64) || defined(BUILD_MK60)
uint32 u32ChannelIDX = 0;
uint32 u32TableIDX = 0;
u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource);
u32ChannelIDX = TEPMHA_rastTEPMChannel[u32TableIDX].u32Channel;
return u32ChannelIDX;
#endif //BUILD_MK6X
}
TEPMHA_tenTimerModule TEPMHA_enTimerEnumFromModule(tstTimerModule* pstTimerModule)
{
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
TEPMHA_tenTimerModule enTimerModule = TEPMHA_enFTM0;
if (FTM1 == pstTimerModule) enTimerModule = TEPMHA_enFTM1;
if (FTM2 == pstTimerModule) enTimerModule = TEPMHA_enFTM2;
if (FTM3 == pstTimerModule) enTimerModule = TEPMHA_enFTM3;
#endif
#ifdef BUILD_SAM3X8E
TEPMHA_tenTimerModule enTimerModule = TEPMHA_enTC0;
if (TC0 == pstTimerModule)
{
enTimerModule = TEPMHA_enTC0;
}
else if (TC1 == pstTimerModule)
{
enTimerModule = TEPMHA_enTC1;
}
else if (TC2 == pstTimerModule)
{
enTimerModule = TEPMHA_enTC2;
}
#endif //BUILD_SAM3X8E
return enTimerModule;
}
#ifdef BUILD_SAM3X8E
static void TEPMHA_vSyncModules(void)
{
tc_sync_trigger((tstTimerModule*)TC0);
tc_sync_trigger((tstTimerModule*)TC1);
tc_sync_trigger((tstTimerModule*)TC2);
}
#endif //BUILD_SAM3X8E
#ifdef BUILD_SAM3X8E
static bool TEPMHA_boModuleIsTimer(void* pvModule)
{
bool boRetVal = FALSE;
if ((TC0 == (tstTimerModule*)pvModule) ||
(TC1 == (tstTimerModule*)pvModule) ||
(TC2 == (tstTimerModule*)pvModule))
{
boRetVal = TRUE;
}
return boRetVal;
}
#endif //BUILD_SAM3X8E
static TEPMHA_tenTimerModule TEPMHA_enGetEnumFromVIO(IOAPI_tenEHIOResource enEHIOResource)
{
TEPMHA_tenTimerModule enModule;
#ifdef BUILD_SAM3X8E
switch (enEHIOResource)
{
case EH_VIO_TC0:
case EH_VIO_TCC0:
case EH_VIO_TCC1:
case EH_VIO_TCC2:
{
enModule = TEPMHA_enTC0;
break;
}
case EH_VIO_TC1:
case EH_VIO_TCC3:
case EH_VIO_TCC4:
case EH_VIO_TCC5:
{
enModule = TEPMHA_enTC1;
break;
}
case EH_VIO_TC2:
case EH_VIO_TCC6:
case EH_VIO_TCC7:
case EH_VIO_TCC8:
{
enModule = TEPMHA_enTC2;
break;
}
case EH_VIO_PWM:
{
enModule = TEPMHA_enPWM0;
break;
}
default:
{
enModule = TEPMHA_enModuleInvalid;
break;
}
}
#endif //BUILD_SAM3X8E
#if defined(BUILD_MK60) || defined(BUILD_MK64)
enModule = (uint32)(enEHIOResource - EH_VIO_FTM0);
#endif //BUILD_MK6X
return enModule;
}
#ifdef BUILD_SAM3X8E
static bool TEPMHA_boModuleIsPWM(void* pvModule)
{
bool boRetVal = FALSE;
if (PWM == (tstPWMModule*)pvModule)
{
boRetVal = TRUE;
}
return boRetVal;
}
#endif //BUILD_SAM3X8E
uint32 TEPMHA_u32GetModulePhaseCorrect(TEPMHA_tenTimerModule enTimerModule, uint32 u32ChannelIDX)
{
uint32 u32PhaseCorrect = 0;
#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10)
switch (enTimerModule)
{
case TEPMHA_enFTM0:
{
u32PhaseCorrect = FTM0->CNT - FTM3->CNT;
break;
}
case TEPMHA_enFTM1:
{
u32PhaseCorrect = FTM1->CNT - FTM3->CNT;
break;
}
case TEPMHA_enFTM2:
{
u32PhaseCorrect = FTM2->CNT - FTM3->CNT;
break;
}
default:
{
u32PhaseCorrect = 0;
break;
}
}
#endif //BUILD_MK6X
#ifdef BUILD_SAM3X8E
(uint32)CEM_ttGetModulePhase(3 * enTimerEnumModule + u32ChannelIDX / 2);
#endif
return u32PhaseCorrect;
}
//#pragma GCC optimize ("O1")