Boen_Shi 8be2866433 feat(base): 初始化 MSPM0 开发环境
- 添加头文件和配置文件支持
- 更新.gitignore忽略编译和IDE相关文件
- 添加基础的bsp代码
2026-07-16 14:45:26 +08:00

1347 lines
50 KiB
C

/*
* 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 <ti/driverlib/dl_timera.h>
#include <ti/driverlib/dl_timerg.h>
#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__ */