/* * Copyright (c) 2020, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #if defined(__MSPM0_HAS_TIMER_A__) || defined(__MSPM0_HAS_TIMER_G__) typedef struct { DL_TIMER_CC_INDEX index; uint32_t ccpInput; uint32_t timerConfig; uint32_t ccpInputDir; } Timer_Input_Chan_Config; typedef struct { DL_TIMER_CC_INDEX index; } Timer_Input_Pair_Chan_Config; static void DL_Timer_getInChanConfig( DL_TIMER_INPUT_CHAN chan, Timer_Input_Chan_Config *config); static void DL_Timer_getInChanPairConfig( DL_TIMER_INPUT_CHAN chan, Timer_Input_Pair_Chan_Config *config); void DL_Timer_setClockConfig( GPTIMER_Regs *gptimer, const DL_Timer_ClockConfig *config) { gptimer->CLKSEL = (uint32_t)(config->clockSel); gptimer->CLKDIV = (uint32_t)(config->divideRatio); gptimer->COMMONREGS.CPS = (config->prescale); } void DL_Timer_getClockConfig( const GPTIMER_Regs *gptimer, DL_Timer_ClockConfig *config) { config->clockSel = (DL_TIMER_CLOCK)(gptimer->CLKSEL); config->divideRatio = (DL_TIMER_CLOCK_DIVIDE)(gptimer->CLKDIV); config->prescale = (uint8_t)(gptimer->COMMONREGS.CPS); } void DL_Timer_initTimerMode( GPTIMER_Regs *gptimer, const DL_Timer_TimerConfig *config) { DL_Timer_setLoadValue(gptimer, config->period); switch (config->timerMode) { /* All four cases below should set counter value to ZERO when enabled */ case DL_TIMER_TIMER_MODE_ONE_SHOT_UP: case DL_TIMER_TIMER_MODE_PERIODIC_UP: case DL_TIMER_TIMER_MODE_ONE_SHOT_UP_DOWN: case DL_TIMER_TIMER_MODE_PERIODIC_UP_DOWN: DL_Timer_setCounterValueAfterEnable( gptimer, DL_TIMER_COUNT_AFTER_EN_ZERO); break; /* The two cases below should set counter value to LOAD when enabled */ case DL_TIMER_TIMER_MODE_ONE_SHOT: case DL_TIMER_TIMER_MODE_PERIODIC: DL_Timer_setCounterValueAfterEnable( gptimer, DL_TIMER_COUNT_AFTER_EN_LOAD_VAL); break; default: /* Code should not reach this case */ break; } DL_Timer_setCaptureCompareValue( gptimer, config->counterVal, DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareCtl(gptimer, (uint32_t) config->genIntermInt, DL_TIMER_CC_ACOND_TIMCLK, DL_TIMER_CC_0_INDEX); gptimer->COUNTERREGS.CTRCTL = ((uint32_t) config->timerMode | (uint32_t) config->startTimer); } void DL_Timer_initCaptureMode( GPTIMER_Regs *gptimer, const DL_Timer_CaptureConfig *config) { Timer_Input_Chan_Config captConfig; DL_Timer_getInChanConfig(config->inputChan, &captConfig); DL_Timer_setCaptureCompareInput(gptimer, (uint32_t) config->inputInvMode, captConfig.ccpInput, captConfig.index); DL_Timer_setLoadValue(gptimer, config->period); switch (config->captureMode) { case DL_TIMER_CAPTURE_MODE_EDGE_TIME: case DL_TIMER_CAPTURE_MODE_EDGE_TIME_UP: DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_NONE | (uint32_t) config->edgeCaptMode), captConfig.index); break; case DL_TIMER_CAPTURE_MODE_PERIOD_CAPTURE: case DL_TIMER_CAPTURE_MODE_PERIOD_CAPTURE_UP: if (DL_TIMER_CAPTURE_EDGE_DETECTION_MODE_RISING == config->edgeCaptMode) { DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_RISE | (uint32_t) config->edgeCaptMode), captConfig.index); } else if (DL_TIMER_CAPTURE_EDGE_DETECTION_MODE_EDGE == config->edgeCaptMode) { DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_EDGE | (uint32_t) config->edgeCaptMode), captConfig.index); } else { DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_FALL | (uint32_t) config->edgeCaptMode), captConfig.index); } break; case DL_TIMER_CAPTURE_MODE_PULSE_WIDTH: case DL_TIMER_CAPTURE_MODE_PULSE_WIDTH_UP: if (DL_TIMER_CAPTURE_EDGE_DETECTION_MODE_RISING == config->edgeCaptMode) { DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_RISE | DL_TIMER_CC_CCOND_TRIG_FALL), captConfig.index); } else { DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_FALL | DL_TIMER_CC_CCOND_TRIG_RISE), captConfig.index); } break; default: break; } DL_Timer_setCCPDirection(gptimer, captConfig.ccpInputDir); switch (config->captureMode) { case DL_TIMER_CAPTURE_MODE_EDGE_TIME_UP: case DL_TIMER_CAPTURE_MODE_PERIOD_CAPTURE_UP: case DL_TIMER_CAPTURE_MODE_PULSE_WIDTH_UP: captConfig.timerConfig = ((uint32_t) captConfig.timerConfig | GPTIMER_CTRCTL_CM_UP); break; default: /* Default timer count is down counting mode. No need to change counting mode */ break; } DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, ((uint32_t) captConfig.timerConfig | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); } void DL_Timer_initCaptureTriggerMode( GPTIMER_Regs *gptimer, const DL_Timer_CaptureTriggerConfig *config) { DL_Timer_setLoadValue(gptimer, config->period); DL_Timer_setCaptureCompareInput(gptimer, DL_TIMER_CC_INPUT_INV_NOINVERT, DL_TIMER_CC_IN_SEL_TRIG, DL_TIMER_CC_0_INDEX); switch (config->captureMode) { case DL_TIMER_CAPTURE_MODE_EDGE_TIME: DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_NONE | DL_TIMER_CC_CCOND_TRIG_RISE), DL_TIMER_CC_0_INDEX); break; case DL_TIMER_CAPTURE_MODE_PERIOD_CAPTURE: DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_RISE | DL_TIMER_CC_CCOND_TRIG_RISE), DL_TIMER_CC_0_INDEX); break; case DL_TIMER_CAPTURE_MODE_PULSE_WIDTH: DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_TRIG_RISE | DL_TIMER_CC_CCOND_TRIG_FALL), DL_TIMER_CC_0_INDEX); break; default: break; } switch (config->captureMode) { case DL_TIMER_CAPTURE_MODE_EDGE_TIME_UP: case DL_TIMER_CAPTURE_MODE_PERIOD_CAPTURE_UP: case DL_TIMER_CAPTURE_MODE_PULSE_WIDTH_UP: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (GPTIMER_CTRCTL_CLC_CCCTL0_LCOND | GPTIMER_CTRCTL_CAC_CCCTL0_ACOND | GPTIMER_CTRCTL_CZC_CCCTL0_ZCOND | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_UP | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; default: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (GPTIMER_CTRCTL_CLC_CCCTL0_LCOND | GPTIMER_CTRCTL_CAC_CCCTL0_ACOND | GPTIMER_CTRCTL_CZC_CCCTL0_ZCOND | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; } } void DL_Timer_initCaptureCombinedMode( GPTIMER_Regs *gptimer, const DL_Timer_CaptureCombinedConfig *config) { Timer_Input_Chan_Config captConfig; Timer_Input_Pair_Chan_Config captPairConfig; DL_Timer_getInChanConfig(config->inputChan, &captConfig); DL_Timer_getInChanPairConfig(config->inputChan, &captPairConfig); DL_Timer_setLoadValue(gptimer, config->period); DL_Timer_setCaptureCompareInput(gptimer, (uint32_t) config->inputInvMode, captConfig.ccpInput, captConfig.index); DL_Timer_setCaptureCompareInput(gptimer, (uint32_t) config->inputInvMode, GPTIMER_IFCTL_01_ISEL_CCPX_INPUT_PAIR, captPairConfig.index); /* * Setting load condition to none due to GPTimer combined capture limitation */ DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_NONE | DL_TIMER_CC_CCOND_TRIG_FALL), captConfig.index); DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_CAPTURE, (DL_TIMER_CC_ZCOND_NONE | DL_TIMER_CC_ACOND_TIMCLK | DL_TIMER_CC_LCOND_NONE | DL_TIMER_CC_CCOND_TRIG_RISE), captPairConfig.index); DL_Timer_setCCPDirection(gptimer, captConfig.ccpInputDir); switch (config->captureMode) { case DL_TIMER_CAPTURE_COMBINED_MODE_PULSE_WIDTH_AND_PERIOD_UP: captConfig.timerConfig = ((uint32_t) captConfig.timerConfig | GPTIMER_CTRCTL_CM_UP); break; default: /* Default timer count is down counting mode. No need to change counting mode */ break; } DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, ((uint32_t) captConfig.timerConfig | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); } void DL_Timer_initCompareMode( GPTIMER_Regs *gptimer, const DL_Timer_CompareConfig *config) { Timer_Input_Chan_Config inChanConfig; DL_Timer_getInChanConfig(config->inputChan, &inChanConfig); DL_Timer_setCaptureCompareInput(gptimer, (uint32_t) config->inputInvMode, inChanConfig.ccpInput, inChanConfig.index); DL_Timer_setLoadValue(gptimer, config->count); DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_COMPARE, (DL_TIMER_CC_ZCOND_NONE | (uint32_t) config->edgeDetectMode | DL_TIMER_CC_LCOND_NONE | DL_TIMER_CC_CCOND_NOCAPTURE), inChanConfig.index); switch (config->compareMode) { case DL_TIMER_COMPARE_MODE_EDGE_COUNT: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, ((uint32_t) inChanConfig.timerConfig | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; case DL_TIMER_COMPARE_MODE_EDGE_COUNT_UP: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, ((uint32_t) inChanConfig.timerConfig | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_UP | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; case DL_TIMER_COMPARE_MODE_EDGE_COUNT_UP_DOWN: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, ((uint32_t) inChanConfig.timerConfig | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_UP_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; default: /* Code should not reach this case */ break; } } void DL_Timer_initCompareTriggerMode( GPTIMER_Regs *gptimer, const DL_Timer_CompareTriggerConfig *config) { DL_Timer_setCaptureCompareInput(gptimer, DL_TIMER_CC_INPUT_INV_NOINVERT, DL_TIMER_CC_IN_SEL_TRIG, DL_TIMER_CC_0_INDEX); DL_Timer_setLoadValue(gptimer, config->count); DL_Timer_setCaptureCompareCtl(gptimer, DL_TIMER_CC_MODE_COMPARE, (DL_TIMER_CC_ZCOND_NONE | (uint32_t) config->edgeDetectMode | DL_TIMER_CC_LCOND_NONE | DL_TIMER_CC_CCOND_NOCAPTURE), DL_TIMER_CC_0_INDEX); switch (config->compareMode) { case DL_TIMER_COMPARE_MODE_EDGE_COUNT: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (GPTIMER_CTRCTL_CLC_CCCTL0_LCOND | GPTIMER_CTRCTL_CAC_CCCTL0_ACOND | GPTIMER_CTRCTL_CZC_CCCTL0_ZCOND | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; case DL_TIMER_COMPARE_MODE_EDGE_COUNT_UP: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (GPTIMER_CTRCTL_CLC_CCCTL0_LCOND | GPTIMER_CTRCTL_CAC_CCCTL0_ACOND | GPTIMER_CTRCTL_CZC_CCCTL0_ZCOND | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_UP | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; case DL_TIMER_COMPARE_MODE_EDGE_COUNT_UP_DOWN: DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (GPTIMER_CTRCTL_CLC_CCCTL0_LCOND | GPTIMER_CTRCTL_CAC_CCCTL0_ACOND | GPTIMER_CTRCTL_CZC_CCCTL0_ZCOND | GPTIMER_CTRCTL_CVAE_LDVAL | GPTIMER_CTRCTL_CM_UP_DOWN | GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); break; default: /* Code should not reach this case */ break; } } static void DL_Timer_initTwoCCPWMMode( GPTIMER_Regs *gptimer, const DL_Timer_PWMConfig *config) { switch (config->pwmMode) { case DL_TIMER_PWM_MODE_EDGE_ALIGN: DL_Timer_setLoadValue(gptimer, (config->period - (uint32_t) 1)); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_LACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_LACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_1_INDEX); break; case DL_TIMER_PWM_MODE_EDGE_ALIGN_UP: DL_Timer_setLoadValue(gptimer, (config->period - (uint32_t) 1)); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_ZACT_CCP_HIGH | DL_TIMER_CC_CUACT_CCP_LOW), DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_ZACT_CCP_HIGH | DL_TIMER_CC_CUACT_CCP_LOW), DL_TIMER_CC_1_INDEX); DL_Timer_setCounterValueAfterEnable( gptimer, DL_TIMER_COUNT_AFTER_EN_ZERO); break; default: // DL_TIMER_PWM_MODE_CENTER_ALIGN DL_Timer_setLoadValue(gptimer, (config->period >> 1)); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_CUACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_CUACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_1_INDEX); break; } DL_Timer_setCaptureCompareCtl( gptimer, DL_TIMER_CC_MODE_COMPARE, 0, DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareCtl( gptimer, DL_TIMER_CC_MODE_COMPARE, 0, DL_TIMER_CC_1_INDEX); DL_Timer_setCaptureCompareOutCtl(gptimer, DL_TIMER_CC_OCTL_INIT_VAL_LOW, DL_TIMER_CC_OCTL_INV_OUT_DISABLED, DL_TIMER_CC_OCTL_SRC_FUNCVAL, DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareOutCtl(gptimer, DL_TIMER_CC_OCTL_INIT_VAL_LOW, DL_TIMER_CC_OCTL_INV_OUT_DISABLED, DL_TIMER_CC_OCTL_SRC_FUNCVAL, DL_TIMER_CC_1_INDEX); DL_Timer_setCaptureCompareInput(gptimer, DL_TIMER_CC_INPUT_INV_NOINVERT, DL_TIMER_CC_IN_SEL_CCPX, DL_TIMER_CC_0_INDEX); DL_Timer_setCaptureCompareInput(gptimer, DL_TIMER_CC_INPUT_INV_NOINVERT, DL_TIMER_CC_IN_SEL_CCPX, DL_TIMER_CC_1_INDEX); DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (GPTIMER_CTRCTL_REPEAT_REPEAT_1 | (uint32_t) config->pwmMode | (uint32_t) config->startTimer), (GPTIMER_CTRCTL_CZC_MASK | GPTIMER_CTRCTL_CAC_MASK | GPTIMER_CTRCTL_CLC_MASK | GPTIMER_CTRCTL_CVAE_MASK | GPTIMER_CTRCTL_CM_MASK | GPTIMER_CTRCTL_REPEAT_MASK | GPTIMER_CTRCTL_EN_MASK)); } void DL_Timer_setCaptureCompareValue( GPTIMER_Regs *gptimer, uint32_t value, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CC_01[0]; pReg += (uint32_t) ccIndex; *pReg = (value); } uint32_t DL_Timer_getCaptureCompareValue( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CC_01[0]; pReg += (uint32_t) ccIndex; return (*pReg & GPTIMER_CC_01_CCVAL_MASK); } void DL_Timer_setCaptureCompareCtl(GPTIMER_Regs *gptimer, uint32_t ccMode, uint32_t ccCondMask, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg(pReg, (ccMode | ccCondMask), (GPTIMER_CCCTL_01_COC_MASK | GPTIMER_CCCTL_01_ZCOND_MASK | GPTIMER_CCCTL_01_LCOND_MASK | GPTIMER_CCCTL_01_ACOND_MASK | GPTIMER_CCCTL_01_CCOND_MASK)); } uint32_t DL_Timer_getCaptureCompareCtl( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; return ( *pReg & (GPTIMER_CCCTL_01_COC_MASK | GPTIMER_CCCTL_01_ZCOND_MASK | GPTIMER_CCCTL_01_LCOND_MASK | GPTIMER_CCCTL_01_ACOND_MASK | GPTIMER_CCCTL_01_CCOND_MASK)); } void DL_Timer_setSecondCompSrcDn(GPTIMER_Regs *gptimer, DL_TIMER_SEC_COMP_DOWN_EVT secCompDn, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg( pReg, (uint32_t) secCompDn, (GPTIMER_CCCTL_01_CC2SELD_MASK)); } DL_TIMER_SEC_COMP_DOWN_EVT DL_Timer_getSecondCompSrcDn( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; uint32_t secCompDn = *pReg & GPTIMER_CCCTL_01_CC2SELD_MASK; return ((DL_TIMER_SEC_COMP_DOWN_EVT)(secCompDn)); } void DL_Timer_setSecondCompSrcUp(GPTIMER_Regs *gptimer, DL_TIMER_SEC_COMP_UP_EVT secCompUp, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg( pReg, (uint32_t) secCompUp, (GPTIMER_CCCTL_01_CC2SELU_MASK)); } DL_TIMER_SEC_COMP_UP_EVT DL_Timer_getSecondCompSrcUp( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; uint32_t secCompUp = *pReg & GPTIMER_CCCTL_01_CC2SELU_MASK; return ((DL_TIMER_SEC_COMP_UP_EVT)(secCompUp)); } void DL_Timer_setSecondCompActionDn(GPTIMER_Regs *gptimer, DL_TIMER_SEC_COMP_DOWN_ACT_SEL secCompDnAct, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg( pReg, (uint32_t) secCompDnAct, (GPTIMER_CCACT_01_CC2DACT_MASK)); } DL_TIMER_SEC_COMP_DOWN_ACT_SEL DL_Timer_getSecondCompActionDn( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; uint32_t secCompDnAct = *pReg & GPTIMER_CCACT_01_CC2DACT_MASK; return ((DL_TIMER_SEC_COMP_DOWN_ACT_SEL)(secCompDnAct)); } void DL_Timer_setSecondCompActionUp(GPTIMER_Regs *gptimer, DL_TIMER_SEC_COMP_UP_ACT_SEL secCompUpAct, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg( pReg, (uint32_t) secCompUpAct, (GPTIMER_CCACT_01_CC2UACT_MASK)); } DL_TIMER_SEC_COMP_UP_ACT_SEL DL_Timer_getSecondCompActionUp( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; uint32_t secCompUpAct = *pReg & GPTIMER_CCACT_01_CC2UACT_MASK; return ((DL_TIMER_SEC_COMP_UP_ACT_SEL)(secCompUpAct)); } void DL_Timer_enableSuppressionOfCompEvent( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; *pReg |= (GPTIMER_CCCTL_01_SCERCNEZ_ENABLED); } void DL_Timer_disableSuppressionOfCompEvent( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; *pReg &= ~(GPTIMER_CCCTL_01_SCERCNEZ_ENABLED); } void DL_Timer_setCaptCompUpdateMethod(GPTIMER_Regs *gptimer, DL_TIMER_CC_UPDATE_METHOD ccUpdtMode, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg( pReg, (uint32_t) ccUpdtMode, GPTIMER_CCCTL_01_CCUPD_MASK); } DL_TIMER_CC_UPDATE_METHOD DL_Timer_getCaptCompUpdateMethod( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; uint32_t ccUpdtMode = *pReg & GPTIMER_CCCTL_01_CCUPD_MASK; return ((DL_TIMER_CC_UPDATE_METHOD)(ccUpdtMode)); } void DL_Timer_setCaptCompActUpdateMethod(GPTIMER_Regs *gptimer, DL_TIMER_CCACT_UPDATE_METHOD ccActUpdtMode, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg( pReg, (uint32_t) ccActUpdtMode, GPTIMER_CCCTL_01_CCACTUPD_MASK); } DL_TIMER_CCACT_UPDATE_METHOD DL_Timer_getCaptCompActUpdateMethod( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCCTL_01[0]; pReg += (uint32_t) ccIndex; uint32_t ccActUpdtMode = *pReg & GPTIMER_CCCTL_01_CCACTUPD_MASK; return ((DL_TIMER_CCACT_UPDATE_METHOD)(ccActUpdtMode)); } void DL_Timer_setCaptureCompareOutCtl(GPTIMER_Regs *gptimer, uint32_t ccpIV, uint32_t ccpOInv, uint32_t ccpO, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.OCTL_01[0]; pReg += (uint32_t) ccIndex; *pReg = (ccpIV | ccpOInv | ccpO); } uint32_t DL_Timer_getCaptureCompareOutCtl( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.OCTL_01[0]; pReg += (uint32_t) ccIndex; return (*pReg); } void DL_Timer_setCaptureCompareAction( GPTIMER_Regs *gptimer, uint32_t actionsMask, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg(pReg, (uint32_t) actionsMask, (GPTIMER_CCACT_01_SWFRCACT_CMPL_MASK | GPTIMER_CCACT_01_SWFRCACT_MASK | GPTIMER_CCACT_01_FEXACT_MASK | GPTIMER_CCACT_01_FENACT_MASK | GPTIMER_CCACT_01_CC2UACT_MASK | GPTIMER_CCACT_01_CC2DACT_MASK | GPTIMER_CCACT_01_CUACT_MASK | GPTIMER_CCACT_01_CDACT_MASK | GPTIMER_CCACT_01_LACT_MASK | GPTIMER_CCACT_01_ZACT_MASK)); } uint32_t DL_Timer_getCaptureCompareAction( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; return ( *pReg & (GPTIMER_CCACT_01_SWFRCACT_CMPL_MASK | GPTIMER_CCACT_01_SWFRCACT_MASK | GPTIMER_CCACT_01_FEXACT_MASK | GPTIMER_CCACT_01_FENACT_MASK | GPTIMER_CCACT_01_CC2UACT_MASK | GPTIMER_CCACT_01_CC2DACT_MASK | GPTIMER_CCACT_01_CUACT_MASK | GPTIMER_CCACT_01_CDACT_MASK | GPTIMER_CCACT_01_LACT_MASK | GPTIMER_CCACT_01_ZACT_MASK)); } void DL_Timer_overrideCCPOut(GPTIMER_Regs *gptimer, DL_TIMER_FORCE_OUT out, DL_TIMER_FORCE_CMPL_OUT outComp, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.CCACT_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg(pReg, ((uint32_t) out | ((uint32_t) outComp)), (GPTIMER_CCACT_01_SWFRCACT_CMPL_MASK | GPTIMER_CCACT_01_SWFRCACT_MASK)); } void DL_Timer_setCaptureCompareInput(GPTIMER_Regs *gptimer, uint32_t inv, uint32_t isel, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg(pReg, (inv | isel), (GPTIMER_IFCTL_01_INV_MASK | GPTIMER_IFCTL_01_ISEL_MASK)); } uint32_t DL_Timer_getCaptureCompareInput( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; return (*pReg & (GPTIMER_IFCTL_01_INV_MASK | GPTIMER_IFCTL_01_ISEL_MASK)); } void DL_Timer_setCaptureCompareInputFilter(GPTIMER_Regs *gptimer, uint32_t cpv, uint32_t fp, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; DL_Common_updateReg(pReg, (cpv | fp), (GPTIMER_IFCTL_01_CPV_MASK | GPTIMER_IFCTL_01_FP_MASK)); } uint32_t DL_Timer_getCaptureCompareInputFilter( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; return (*pReg & (GPTIMER_IFCTL_01_CPV_MASK | GPTIMER_IFCTL_01_FP_MASK)); } void DL_Timer_enableCaptureCompareInputFilter( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; *pReg |= (GPTIMER_IFCTL_01_FE_ENABLED); } void DL_Timer_disableCaptureCompareInputFilter( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; *pReg &= ~(GPTIMER_IFCTL_01_FE_ENABLED); } bool DL_Timer_isCaptureCompareInputFilterEnabled( GPTIMER_Regs *gptimer, DL_TIMER_CC_INDEX ccIndex) { volatile uint32_t *pReg; pReg = &gptimer->COUNTERREGS.IFCTL_01[0]; pReg += (uint32_t) ccIndex; return (GPTIMER_IFCTL_01_FE_ENABLED == (*pReg & GPTIMER_IFCTL_01_FE_MASK)); } bool DL_Timer_saveConfiguration( const GPTIMER_Regs *gptimer, DL_Timer_backupConfig *ptr) { bool saveState = !ptr->backupRdy; if (saveState) { /* Generic Events configuration */ ptr->sub0PortConf = gptimer->FSUB_0; ptr->sub1PortConf = gptimer->FSUB_1; ptr->pub0PortConf = gptimer->FPUB_0; ptr->pub1PortConf = gptimer->FPUB_1; /* Clock configuration */ ptr->clkDivConf = gptimer->CLKDIV; ptr->clockPscConf = gptimer->COMMONREGS.CPS; ptr->clkSelConf = gptimer->CLKSEL; ptr->countClkConf = gptimer->COMMONREGS.CCLKCTL; /* Interrupt and Event Configuration */ ptr->intEvnt0Conf = gptimer->CPU_INT.IMASK; ptr->intEvnt1Conf = gptimer->GEN_EVENT0.IMASK; ptr->intEvnt2Conf = gptimer->GEN_EVENT1.IMASK; /* Cross-trigger configuration */ ptr->crossTrigCtl = gptimer->COMMONREGS.CTTRIGCTL; ptr->crossTrigConf = gptimer->COMMONREGS.CTTRIG; /* Timer configuration */ ptr->cntVal = gptimer->COUNTERREGS.CTR; ptr->cntCtlConf = gptimer->COUNTERREGS.CTRCTL; ptr->loadVal = gptimer->COUNTERREGS.LOAD; ptr->tSelConf = gptimer->COUNTERREGS.TSEL; ptr->ccpDirConf = gptimer->COMMONREGS.CCPD; ptr->outDisConf = gptimer->COMMONREGS.ODIS; /* Capture or Compare configuration */ ptr->cc0Val = gptimer->COUNTERREGS.CC_01[0]; ptr->cc1Val = gptimer->COUNTERREGS.CC_01[1]; ptr->cc2Val = gptimer->COUNTERREGS.CC_23[0]; ptr->cc3Val = gptimer->COUNTERREGS.CC_23[1]; ptr->cc0Ctl = gptimer->COUNTERREGS.CCCTL_01[0]; ptr->cc1Ctl = gptimer->COUNTERREGS.CCCTL_01[1]; ptr->cc2Ctl = gptimer->COUNTERREGS.CCCTL_23[0]; ptr->cc3Ctl = gptimer->COUNTERREGS.CCCTL_23[1]; ptr->cc0OutCtl = gptimer->COUNTERREGS.OCTL_01[0]; ptr->cc1OutCtl = gptimer->COUNTERREGS.OCTL_01[1]; ptr->cc2OutCtl = gptimer->COUNTERREGS.OCTL_23[0]; ptr->cc3OutCtl = gptimer->COUNTERREGS.OCTL_23[1]; ptr->cc0ActCtl = gptimer->COUNTERREGS.CCACT_01[0]; ptr->cc1ActCtl = gptimer->COUNTERREGS.CCACT_01[1]; ptr->cc2ActCtl = gptimer->COUNTERREGS.CCACT_23[0]; ptr->cc3ActCtl = gptimer->COUNTERREGS.CCACT_23[1]; ptr->in0FiltCtl = gptimer->COUNTERREGS.IFCTL_01[0]; ptr->in1FiltCtl = gptimer->COUNTERREGS.IFCTL_01[1]; ptr->in2FiltCtl = gptimer->COUNTERREGS.IFCTL_23[0]; ptr->in3FiltCtl = gptimer->COUNTERREGS.IFCTL_23[1]; ptr->backupRdy = true; } return saveState; } bool DL_Timer_restoreConfiguration( GPTIMER_Regs *gptimer, DL_Timer_backupConfig *ptr, bool restoreCounter) { bool stateRestored = ptr->backupRdy; if (stateRestored) { ptr->backupRdy = false; /* Generic Events Configuration */ gptimer->FSUB_0 = ptr->sub0PortConf; gptimer->FSUB_1 = ptr->sub1PortConf; gptimer->FPUB_0 = ptr->pub0PortConf; gptimer->FPUB_1 = ptr->pub1PortConf; /* Clock Configuration */ gptimer->CLKSEL = ptr->clkSelConf; gptimer->CLKDIV = ptr->clkDivConf; /** * Since the only difference between TIMG and TIMH is the prescaler * register, restore function will ommit restoring prescaler by * comparing to gptimer pointer to the TIMH0 expected base address * (i.e. 0x40880000U) in MSPM0G devices. MSPM0L devices don't have a * TIMH instances.*/ if (((uint32_t) &gptimer) == 0x40880000U) { gptimer->COMMONREGS.CPS = ptr->clockPscConf; } else { // Configuration of prescaler is ommited } gptimer->COMMONREGS.CCLKCTL = ptr->countClkConf; /* Timer Configuration */ if (true == restoreCounter) { gptimer->COUNTERREGS.CTR = ptr->cntVal; } gptimer->COUNTERREGS.LOAD = ptr->loadVal; gptimer->COUNTERREGS.TSEL = ptr->tSelConf; gptimer->COMMONREGS.CCPD = ptr->ccpDirConf; gptimer->COMMONREGS.ODIS = ptr->outDisConf; /* Capture or Compare Configuration */ gptimer->COUNTERREGS.CC_01[0] = ptr->cc0Val; gptimer->COUNTERREGS.CC_01[1] = ptr->cc1Val; gptimer->COUNTERREGS.CC_23[0] = ptr->cc2Val; gptimer->COUNTERREGS.CC_23[1] = ptr->cc3Val; gptimer->COUNTERREGS.CCCTL_01[0] = ptr->cc0Ctl; gptimer->COUNTERREGS.CCCTL_01[1] = ptr->cc1Ctl; gptimer->COUNTERREGS.CCCTL_23[0] = ptr->cc2Ctl; gptimer->COUNTERREGS.CCCTL_23[1] = ptr->cc3Ctl; gptimer->COUNTERREGS.OCTL_01[0] = ptr->cc0OutCtl; gptimer->COUNTERREGS.OCTL_01[1] = ptr->cc1OutCtl; gptimer->COUNTERREGS.OCTL_23[0] = ptr->cc2OutCtl; gptimer->COUNTERREGS.OCTL_23[1] = ptr->cc3OutCtl; gptimer->COUNTERREGS.CCACT_01[0] = ptr->cc0ActCtl; gptimer->COUNTERREGS.CCACT_01[1] = ptr->cc1ActCtl; gptimer->COUNTERREGS.CCACT_23[0] = ptr->cc2ActCtl; gptimer->COUNTERREGS.CCACT_23[1] = ptr->cc3ActCtl; gptimer->COUNTERREGS.IFCTL_01[0] = ptr->in0FiltCtl; gptimer->COUNTERREGS.IFCTL_01[1] = ptr->in1FiltCtl; gptimer->COUNTERREGS.IFCTL_23[0] = ptr->in2FiltCtl; gptimer->COUNTERREGS.IFCTL_23[1] = ptr->in3FiltCtl; /* Cross-trigger Configuration */ gptimer->COMMONREGS.CTTRIGCTL = ptr->crossTrigCtl; gptimer->COMMONREGS.CTTRIG = ptr->crossTrigConf; /* Interrupt and Event Configuration */ gptimer->CPU_INT.IMASK = ptr->intEvnt0Conf; gptimer->GEN_EVENT0.IMASK = ptr->intEvnt1Conf; gptimer->GEN_EVENT1.IMASK = ptr->intEvnt2Conf; /* Restores Timer counter state until the end to prevent unexpected * behavior */ gptimer->COUNTERREGS.CTRCTL = ptr->cntCtlConf; } return stateRestored; } void DL_Timer_initFourCCPWMMode( GPTIMER_Regs *gptimer, const DL_Timer_PWMConfig *config) { DL_Timer_PWMConfig pwmConfig; if (true == config->isTimerWithFourCC) { switch (config->pwmMode) { case DL_TIMER_PWM_MODE_EDGE_ALIGN: DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_LACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_2_INDEX); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_LACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_3_INDEX); break; case DL_TIMER_PWM_MODE_EDGE_ALIGN_UP: DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_ZACT_CCP_HIGH | DL_TIMER_CC_CUACT_CCP_LOW), DL_TIMER_CC_2_INDEX); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_ZACT_CCP_HIGH | DL_TIMER_CC_CUACT_CCP_LOW), DL_TIMER_CC_3_INDEX); break; default: // DL_TIMER_PWM_MODE_CENTER_ALIGN DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_CUACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_2_INDEX); DL_Timer_setCaptureCompareAction(gptimer, (DL_TIMER_CC_CUACT_CCP_HIGH | DL_TIMER_CC_CDACT_CCP_LOW), DL_TIMER_CC_3_INDEX); break; } DL_Timer_setCaptureCompareCtl( gptimer, DL_TIMER_CC_MODE_COMPARE, 0, DL_TIMER_CC_2_INDEX); DL_Timer_setCaptureCompareCtl( gptimer, DL_TIMER_CC_MODE_COMPARE, 0, DL_TIMER_CC_3_INDEX); DL_Timer_setCaptureCompareOutCtl(gptimer, DL_TIMER_CC_OCTL_INIT_VAL_LOW, DL_TIMER_CC_OCTL_INV_OUT_DISABLED, DL_TIMER_CC_OCTL_SRC_FUNCVAL, DL_TIMER_CC_2_INDEX); DL_Timer_setCaptureCompareOutCtl(gptimer, DL_TIMER_CC_OCTL_INIT_VAL_LOW, DL_TIMER_CC_OCTL_INV_OUT_DISABLED, DL_TIMER_CC_OCTL_SRC_FUNCVAL, DL_TIMER_CC_3_INDEX); DL_Timer_setCaptureCompareInput(gptimer, DL_TIMER_CC_INPUT_INV_NOINVERT, DL_TIMER_CC_IN_SEL_CCPX, DL_TIMER_CC_2_INDEX); DL_Timer_setCaptureCompareInput(gptimer, DL_TIMER_CC_INPUT_INV_NOINVERT, DL_TIMER_CC_IN_SEL_CCPX, DL_TIMER_CC_3_INDEX); } pwmConfig.period = config->period; pwmConfig.pwmMode = config->pwmMode; pwmConfig.startTimer = config->startTimer; DL_Timer_initTwoCCPWMMode(gptimer, &pwmConfig); } #ifdef __MSPM0_HAS_TIMER_A__ void DL_Timer_setFaultSourceConfig(GPTIMER_Regs *gptimer, uint32_t source) { DL_Common_updateReg(&gptimer->COUNTERREGS.FCTL, (source >> 16) & (GPTIMER_FCTL_FSENAC0_MASK | GPTIMER_FCTL_FSENAC1_MASK | GPTIMER_FCTL_FSENAC2_MASK | GPTIMER_FCTL_FSENEXT0_MASK | GPTIMER_FCTL_FSENEXT1_MASK | GPTIMER_FCTL_FSENEXT2_MASK), (GPTIMER_FCTL_FSENAC0_MASK | GPTIMER_FCTL_FSENAC1_MASK | GPTIMER_FCTL_FSENAC2_MASK | GPTIMER_FCTL_FSENEXT0_MASK | GPTIMER_FCTL_FSENEXT1_MASK | GPTIMER_FCTL_FSENEXT2_MASK)); DL_Common_updateReg(&gptimer->COMMONREGS.FSCTL, source, (GPTIMER_FSCTL_FAC0EN_MASK | GPTIMER_FSCTL_FAC1EN_MASK | GPTIMER_FSCTL_FAC2EN_MASK | GPTIMER_FSCTL_FEX0EN_MASK | GPTIMER_FSCTL_FEX1EN_MASK | GPTIMER_FSCTL_FEX2EN_MASK)); } uint32_t DL_Timer_getFaultSourceConfig(const GPTIMER_Regs *gptimer) { uint32_t faultMode; uint32_t faultSense; faultMode = gptimer->COMMONREGS.FSCTL; faultSense = gptimer->COUNTERREGS.FCTL; return (((faultSense & (GPTIMER_FCTL_FSENAC0_MASK | GPTIMER_FCTL_FSENAC1_MASK | GPTIMER_FCTL_FSENAC2_MASK | GPTIMER_FCTL_FSENEXT0_MASK | GPTIMER_FCTL_FSENEXT1_MASK | GPTIMER_FCTL_FSENEXT2_MASK)) << 16) | (faultMode & ((GPTIMER_FSCTL_FAC0EN_MASK | GPTIMER_FSCTL_FAC1EN_MASK | GPTIMER_FSCTL_FAC2EN_MASK | GPTIMER_FSCTL_FEX0EN_MASK | GPTIMER_FSCTL_FEX1EN_MASK | GPTIMER_FSCTL_FEX2EN_MASK)))); } bool DL_TimerA_saveConfiguration( const GPTIMER_Regs *gptimer, DL_TimerA_backupConfig *ptr) { bool saveState = !ptr->backupRdy; if (saveState) { /* Generic Events configuration */ ptr->sub0PortConf = gptimer->FSUB_0; ptr->sub1PortConf = gptimer->FSUB_1; ptr->pub0PortConf = gptimer->FPUB_0; ptr->pub1PortConf = gptimer->FPUB_1; /* Clock configuration */ ptr->clkDivConf = gptimer->CLKDIV; ptr->clockPscConf = gptimer->COMMONREGS.CPS; ptr->clkSelConf = gptimer->CLKSEL; ptr->countClkConf = gptimer->COMMONREGS.CCLKCTL; /* Interrupt and Event Configuration */ ptr->intEvnt0Conf = gptimer->CPU_INT.IMASK; ptr->intEvnt1Conf = gptimer->GEN_EVENT0.IMASK; ptr->intEvnt2Conf = gptimer->GEN_EVENT1.IMASK; /* Cross-trigger configuration */ ptr->crossTrigCtl = gptimer->COMMONREGS.CTTRIGCTL; ptr->crossTrigConf = gptimer->COMMONREGS.CTTRIG; /* Timer configuration */ ptr->cntVal = gptimer->COUNTERREGS.CTR; ptr->cntCtlConf = gptimer->COUNTERREGS.CTRCTL; ptr->loadVal = gptimer->COUNTERREGS.LOAD; ptr->phaseVal = gptimer->COUNTERREGS.PL; ptr->tSelConf = gptimer->COUNTERREGS.TSEL; ptr->ccpDirConf = gptimer->COMMONREGS.CCPD; ptr->outDisConf = gptimer->COMMONREGS.ODIS; /* Capture or Compare configuration */ ptr->cc0Val = gptimer->COUNTERREGS.CC_01[0]; ptr->cc1Val = gptimer->COUNTERREGS.CC_01[1]; ptr->cc2Val = gptimer->COUNTERREGS.CC_23[0]; ptr->cc3Val = gptimer->COUNTERREGS.CC_23[1]; ptr->cc0Ctl = gptimer->COUNTERREGS.CCCTL_01[0]; ptr->cc1Ctl = gptimer->COUNTERREGS.CCCTL_01[1]; ptr->cc2Ctl = gptimer->COUNTERREGS.CCCTL_23[0]; ptr->cc3Ctl = gptimer->COUNTERREGS.CCCTL_23[1]; ptr->cc0OutCtl = gptimer->COUNTERREGS.OCTL_01[0]; ptr->cc1OutCtl = gptimer->COUNTERREGS.OCTL_01[1]; ptr->cc2OutCtl = gptimer->COUNTERREGS.OCTL_23[0]; ptr->cc3OutCtl = gptimer->COUNTERREGS.OCTL_23[1]; ptr->cc0ActCtl = gptimer->COUNTERREGS.CCACT_01[0]; ptr->cc1ActCtl = gptimer->COUNTERREGS.CCACT_01[1]; ptr->cc2ActCtl = gptimer->COUNTERREGS.CCACT_23[0]; ptr->cc3ActCtl = gptimer->COUNTERREGS.CCACT_23[1]; ptr->in0FiltCtl = gptimer->COUNTERREGS.IFCTL_01[0]; ptr->in1FiltCtl = gptimer->COUNTERREGS.IFCTL_01[1]; ptr->in2FiltCtl = gptimer->COUNTERREGS.IFCTL_23[0]; ptr->in3FiltCtl = gptimer->COUNTERREGS.IFCTL_23[1]; /* Dead Band Configuration */ ptr->dbCtlConf = gptimer->COUNTERREGS.DBCTL; /* Repeat Counter Configuration */ ptr->rcConf = gptimer->COUNTERREGS.RCLD; /* Fault Configuration */ ptr->faultSrcHndlConf = gptimer->COUNTERREGS.FCTL; ptr->faultInCtl = gptimer->COUNTERREGS.FIFCTL; ptr->backupRdy = true; } return saveState; } bool DL_TimerA_restoreConfiguration( GPTIMER_Regs *gptimer, DL_TimerA_backupConfig *ptr, bool restoreCounter) { bool stateRestored = ptr->backupRdy; if (stateRestored) { ptr->backupRdy = false; /* Generic Events Configuration */ gptimer->FSUB_0 = ptr->sub0PortConf; gptimer->FSUB_1 = ptr->sub1PortConf; gptimer->FPUB_0 = ptr->pub0PortConf; gptimer->FPUB_1 = ptr->pub1PortConf; /* Clock Configuration */ gptimer->CLKSEL = ptr->clkSelConf; gptimer->CLKDIV = ptr->clkDivConf; gptimer->COMMONREGS.CPS = ptr->clockPscConf; gptimer->COMMONREGS.CCLKCTL = ptr->countClkConf; /* Timer Configuration */ if (true == restoreCounter) { gptimer->COUNTERREGS.CTR = ptr->cntVal; } gptimer->COUNTERREGS.LOAD = ptr->loadVal; gptimer->COUNTERREGS.PL = ptr->phaseVal; gptimer->COUNTERREGS.TSEL = ptr->tSelConf; gptimer->COMMONREGS.CCPD = ptr->ccpDirConf; gptimer->COMMONREGS.ODIS = ptr->outDisConf; /* Capture or Compare Configuration */ gptimer->COUNTERREGS.CC_01[0] = ptr->cc0Val; gptimer->COUNTERREGS.CC_01[1] = ptr->cc1Val; gptimer->COUNTERREGS.CC_23[0] = ptr->cc2Val; gptimer->COUNTERREGS.CC_23[1] = ptr->cc3Val; gptimer->COUNTERREGS.CCCTL_01[0] = ptr->cc0Ctl; gptimer->COUNTERREGS.CCCTL_01[1] = ptr->cc1Ctl; gptimer->COUNTERREGS.CCCTL_23[0] = ptr->cc2Ctl; gptimer->COUNTERREGS.CCCTL_23[1] = ptr->cc3Ctl; gptimer->COUNTERREGS.OCTL_01[0] = ptr->cc0OutCtl; gptimer->COUNTERREGS.OCTL_01[1] = ptr->cc1OutCtl; gptimer->COUNTERREGS.OCTL_23[0] = ptr->cc2OutCtl; gptimer->COUNTERREGS.OCTL_23[1] = ptr->cc3OutCtl; gptimer->COUNTERREGS.CCACT_01[0] = ptr->cc0ActCtl; gptimer->COUNTERREGS.CCACT_01[1] = ptr->cc1ActCtl; gptimer->COUNTERREGS.CCACT_23[0] = ptr->cc2ActCtl; gptimer->COUNTERREGS.CCACT_23[1] = ptr->cc3ActCtl; gptimer->COUNTERREGS.IFCTL_01[0] = ptr->in0FiltCtl; gptimer->COUNTERREGS.IFCTL_01[1] = ptr->in1FiltCtl; gptimer->COUNTERREGS.IFCTL_23[0] = ptr->in2FiltCtl; gptimer->COUNTERREGS.IFCTL_23[1] = ptr->in3FiltCtl; /* Cross-trigger Configuration */ gptimer->COMMONREGS.CTTRIGCTL = ptr->crossTrigCtl; gptimer->COMMONREGS.CTTRIG = ptr->crossTrigConf; /* Dead Band Configuration */ gptimer->COUNTERREGS.DBCTL = ptr->dbCtlConf; /* Repeat Counter Configuration */ ptr->rcConf = gptimer->COUNTERREGS.RCLD; /* Fault Configuration */ ptr->faultSrcHndlConf = gptimer->COUNTERREGS.FCTL; ptr->faultInCtl = gptimer->COUNTERREGS.FIFCTL; /* Interrupt and Event Configuration */ gptimer->CPU_INT.IMASK = ptr->intEvnt0Conf; gptimer->GEN_EVENT0.IMASK = ptr->intEvnt1Conf; gptimer->GEN_EVENT1.IMASK = ptr->intEvnt2Conf; /* Restores Timer counter state until the end to prevent unexpected * behavior */ gptimer->COUNTERREGS.CTRCTL = ptr->cntCtlConf; } return stateRestored; } #endif /* __MSPM0_HAS_TIMER_A__ */ static void DL_Timer_getInChanConfig( DL_TIMER_INPUT_CHAN chan, Timer_Input_Chan_Config *config) { switch (chan) { case DL_TIMER_INPUT_CHAN_0: config->index = (DL_TIMER_CC_0_INDEX); config->ccpInput = (DL_TIMER_CC_IN_SEL_CCP0); config->timerConfig = (GPTIMER_CTRCTL_CLC_CCCTL0_LCOND | GPTIMER_CTRCTL_CAC_CCCTL0_ACOND | GPTIMER_CTRCTL_CZC_CCCTL0_ZCOND | GPTIMER_CTRCTL_CM_DOWN); config->ccpInputDir = DL_TIMER_CC0_INPUT; break; case DL_TIMER_INPUT_CHAN_1: config->index = (DL_TIMER_CC_1_INDEX); config->ccpInput = (DL_TIMER_CC_IN_SEL_CCPX); config->timerConfig = (GPTIMER_CTRCTL_CLC_CCCTL1_LCOND | GPTIMER_CTRCTL_CAC_CCCTL1_ACOND | GPTIMER_CTRCTL_CZC_CCCTL1_ZCOND | GPTIMER_CTRCTL_CM_DOWN); config->ccpInputDir = (DL_TIMER_CC1_INPUT); break; case DL_TIMER_INPUT_CHAN_2: config->index = (DL_TIMER_CC_2_INDEX); config->ccpInput = (DL_TIMER_CC_IN_SEL_CCP0); config->timerConfig = (GPTIMER_CTRCTL_CLC_CCCTL2_LCOND | GPTIMER_CTRCTL_CAC_CCCTL2_ACOND | GPTIMER_CTRCTL_CZC_CCCTL2_ZCOND | GPTIMER_CTRCTL_CM_DOWN); config->ccpInputDir = (DL_TIMER_CC2_INPUT); break; case DL_TIMER_INPUT_CHAN_3: config->index = (DL_TIMER_CC_3_INDEX); config->ccpInput = (DL_TIMER_CC_IN_SEL_CCPX); config->timerConfig = (GPTIMER_CTRCTL_CLC_CCCTL3_LCOND | GPTIMER_CTRCTL_CAC_CCCTL3_ACOND | GPTIMER_CTRCTL_CZC_CCCTL3_ZCOND | GPTIMER_CTRCTL_CM_DOWN); config->ccpInputDir = (DL_TIMER_CC3_INPUT); break; default: /* This case shouldn't be reached */ break; } } static void DL_Timer_getInChanPairConfig( DL_TIMER_INPUT_CHAN chan, Timer_Input_Pair_Chan_Config *config) { switch (chan) { case DL_TIMER_INPUT_CHAN_0: config->index = (DL_TIMER_CC_1_INDEX); break; case DL_TIMER_INPUT_CHAN_1: config->index = (DL_TIMER_CC_0_INDEX); break; case DL_TIMER_INPUT_CHAN_2: config->index = (DL_TIMER_CC_3_INDEX); break; case DL_TIMER_INPUT_CHAN_3: config->index = (DL_TIMER_CC_2_INDEX); break; default: /* This case shouldn't be reached */ break; } } void DL_Timer_configQEIHallInputMode(GPTIMER_Regs *gptimer) { /* Set channels for capture mode */ gptimer->COUNTERREGS.CCCTL_01[0] = GPTIMER_CCCTL_01_COC_CAPTURE | GPTIMER_CCCTL_01_CCOND_CC_TRIG_EDGE; gptimer->COUNTERREGS.CCCTL_01[1] = GPTIMER_CCCTL_01_COC_CAPTURE | GPTIMER_CCCTL_01_CCOND_CC_TRIG_EDGE; /* Set channels as input */ DL_Timer_setCCPDirection( gptimer, (DL_TIMER_CC0_INPUT | DL_TIMER_CC1_INPUT)); /* Select XOR option for Hall signals */ gptimer->COUNTERREGS.IFCTL_01[0] = DL_TIMER_CC_IN_SEL_CCP_XOR; gptimer->COUNTERREGS.IFCTL_01[1] = DL_TIMER_CC_IN_SEL_CCP_XOR; } #endif /* __MSPM0_HAS_TIMER_A__ || __MSPM0_HAS_TIMER_G__ */