added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 144:ef7eb2e8f9f7 12 * list of conditions and the following disclaimer in the documentation and/or
<> 144:ef7eb2e8f9f7 13 * other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 14 *
<> 144:ef7eb2e8f9f7 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 144:ef7eb2e8f9f7 16 * contributors may be used to endorse or promote products derived from this
<> 144:ef7eb2e8f9f7 17 * software without specific prior written permission.
<> 144:ef7eb2e8f9f7 18 *
<> 144:ef7eb2e8f9f7 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30
<> 144:ef7eb2e8f9f7 31 #include "fsl_tpm.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 /*******************************************************************************
<> 144:ef7eb2e8f9f7 34 * Definitions
<> 144:ef7eb2e8f9f7 35 ******************************************************************************/
<> 144:ef7eb2e8f9f7 36 #define TPM_COMBINE_SHIFT (8U)
<> 144:ef7eb2e8f9f7 37
<> 144:ef7eb2e8f9f7 38 /*******************************************************************************
<> 144:ef7eb2e8f9f7 39 * Prototypes
<> 144:ef7eb2e8f9f7 40 ******************************************************************************/
<> 144:ef7eb2e8f9f7 41 /*!
<> 144:ef7eb2e8f9f7 42 * @brief Gets the instance from the base address
<> 144:ef7eb2e8f9f7 43 *
<> 144:ef7eb2e8f9f7 44 * @param base TPM peripheral base address
<> 144:ef7eb2e8f9f7 45 *
<> 144:ef7eb2e8f9f7 46 * @return The TPM instance
<> 144:ef7eb2e8f9f7 47 */
<> 144:ef7eb2e8f9f7 48 static uint32_t TPM_GetInstance(TPM_Type *base);
<> 144:ef7eb2e8f9f7 49
<> 144:ef7eb2e8f9f7 50 /*******************************************************************************
<> 144:ef7eb2e8f9f7 51 * Variables
<> 144:ef7eb2e8f9f7 52 ******************************************************************************/
<> 144:ef7eb2e8f9f7 53 /*! @brief Pointers to TPM bases for each instance. */
<> 144:ef7eb2e8f9f7 54 static TPM_Type *const s_tpmBases[] = TPM_BASE_PTRS;
<> 144:ef7eb2e8f9f7 55
<> 144:ef7eb2e8f9f7 56 /*! @brief Pointers to TPM clocks for each instance. */
<> 144:ef7eb2e8f9f7 57 static const clock_ip_name_t s_tpmClocks[] = TPM_CLOCKS;
<> 144:ef7eb2e8f9f7 58
<> 144:ef7eb2e8f9f7 59 /*******************************************************************************
<> 144:ef7eb2e8f9f7 60 * Code
<> 144:ef7eb2e8f9f7 61 ******************************************************************************/
<> 144:ef7eb2e8f9f7 62 static uint32_t TPM_GetInstance(TPM_Type *base)
<> 144:ef7eb2e8f9f7 63 {
<> 144:ef7eb2e8f9f7 64 uint32_t instance;
<> 144:ef7eb2e8f9f7 65 uint32_t tpmArrayCount = (sizeof(s_tpmBases) / sizeof(s_tpmBases[0]));
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 /* Find the instance index from base address mappings. */
<> 144:ef7eb2e8f9f7 68 for (instance = 0; instance < tpmArrayCount; instance++)
<> 144:ef7eb2e8f9f7 69 {
<> 144:ef7eb2e8f9f7 70 if (s_tpmBases[instance] == base)
<> 144:ef7eb2e8f9f7 71 {
<> 144:ef7eb2e8f9f7 72 break;
<> 144:ef7eb2e8f9f7 73 }
<> 144:ef7eb2e8f9f7 74 }
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 assert(instance < tpmArrayCount);
<> 144:ef7eb2e8f9f7 77
<> 144:ef7eb2e8f9f7 78 return instance;
<> 144:ef7eb2e8f9f7 79 }
<> 144:ef7eb2e8f9f7 80
<> 144:ef7eb2e8f9f7 81 void TPM_Init(TPM_Type *base, const tpm_config_t *config)
<> 144:ef7eb2e8f9f7 82 {
<> 144:ef7eb2e8f9f7 83 assert(config);
<> 144:ef7eb2e8f9f7 84
<> 144:ef7eb2e8f9f7 85 /* Enable the module clock */
<> 144:ef7eb2e8f9f7 86 CLOCK_EnableClock(s_tpmClocks[TPM_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 #if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL
<> 144:ef7eb2e8f9f7 89 /* TPM reset is available on certain SoC's */
<> 144:ef7eb2e8f9f7 90 TPM_Reset(base);
<> 144:ef7eb2e8f9f7 91 #endif
<> 144:ef7eb2e8f9f7 92
<> 144:ef7eb2e8f9f7 93 /* Set the clock prescale factor */
<> 144:ef7eb2e8f9f7 94 base->SC = TPM_SC_PS(config->prescale);
<> 144:ef7eb2e8f9f7 95
<> 144:ef7eb2e8f9f7 96 /* Setup the counter operation */
<> 144:ef7eb2e8f9f7 97 base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_GTBEEN(config->useGlobalTimeBase) |
<> 144:ef7eb2e8f9f7 98 TPM_CONF_CROT(config->enableReloadOnTrigger) | TPM_CONF_CSOT(config->enableStartOnTrigger) |
<> 144:ef7eb2e8f9f7 99 TPM_CONF_CSOO(config->enableStopOnOverflow) |
<> 144:ef7eb2e8f9f7 100 #if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
<> 144:ef7eb2e8f9f7 101 TPM_CONF_CPOT(config->enablePauseOnTrigger) |
<> 144:ef7eb2e8f9f7 102 #endif
<> 144:ef7eb2e8f9f7 103 #if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
<> 144:ef7eb2e8f9f7 104 TPM_CONF_TRGSRC(config->triggerSource) |
<> 144:ef7eb2e8f9f7 105 #endif
<> 144:ef7eb2e8f9f7 106 TPM_CONF_TRGSEL(config->triggerSelect);
<> 144:ef7eb2e8f9f7 107 if (config->enableDebugMode)
<> 144:ef7eb2e8f9f7 108 {
<> 144:ef7eb2e8f9f7 109 base->CONF |= TPM_CONF_DBGMODE_MASK;
<> 144:ef7eb2e8f9f7 110 }
<> 144:ef7eb2e8f9f7 111 else
<> 144:ef7eb2e8f9f7 112 {
<> 144:ef7eb2e8f9f7 113 base->CONF &= ~TPM_CONF_DBGMODE_MASK;
<> 144:ef7eb2e8f9f7 114 }
<> 144:ef7eb2e8f9f7 115 }
<> 144:ef7eb2e8f9f7 116
<> 144:ef7eb2e8f9f7 117 void TPM_Deinit(TPM_Type *base)
<> 144:ef7eb2e8f9f7 118 {
<> 144:ef7eb2e8f9f7 119 /* Stop the counter */
<> 144:ef7eb2e8f9f7 120 base->SC &= ~TPM_SC_CMOD_MASK;
<> 144:ef7eb2e8f9f7 121 /* Gate the TPM clock */
<> 144:ef7eb2e8f9f7 122 CLOCK_DisableClock(s_tpmClocks[TPM_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 123 }
<> 144:ef7eb2e8f9f7 124
<> 144:ef7eb2e8f9f7 125 void TPM_GetDefaultConfig(tpm_config_t *config)
<> 144:ef7eb2e8f9f7 126 {
<> 144:ef7eb2e8f9f7 127 assert(config);
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 /* TPM clock divide by 1 */
<> 144:ef7eb2e8f9f7 130 config->prescale = kTPM_Prescale_Divide_1;
<> 144:ef7eb2e8f9f7 131 /* Use internal TPM counter as timebase */
<> 144:ef7eb2e8f9f7 132 config->useGlobalTimeBase = false;
<> 144:ef7eb2e8f9f7 133 /* TPM counter continues in doze mode */
<> 144:ef7eb2e8f9f7 134 config->enableDoze = false;
<> 144:ef7eb2e8f9f7 135 /* TPM counter pauses when in debug mode */
<> 144:ef7eb2e8f9f7 136 config->enableDebugMode = false;
<> 144:ef7eb2e8f9f7 137 /* TPM counter will not be reloaded on input trigger */
<> 144:ef7eb2e8f9f7 138 config->enableReloadOnTrigger = false;
<> 144:ef7eb2e8f9f7 139 /* TPM counter continues running after overflow */
<> 144:ef7eb2e8f9f7 140 config->enableStopOnOverflow = false;
<> 144:ef7eb2e8f9f7 141 /* TPM counter starts immediately once it is enabled */
<> 144:ef7eb2e8f9f7 142 config->enableStartOnTrigger = false;
<> 144:ef7eb2e8f9f7 143 #if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
<> 144:ef7eb2e8f9f7 144 config->enablePauseOnTrigger = false;
<> 144:ef7eb2e8f9f7 145 #endif
<> 144:ef7eb2e8f9f7 146 /* Choose trigger select 0 as input trigger for controlling counter operation */
<> 144:ef7eb2e8f9f7 147 config->triggerSelect = kTPM_Trigger_Select_0;
<> 144:ef7eb2e8f9f7 148 #if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
<> 144:ef7eb2e8f9f7 149 /* Choose external trigger source to control counter operation */
<> 144:ef7eb2e8f9f7 150 config->triggerSource = kTPM_TriggerSource_External;
<> 144:ef7eb2e8f9f7 151 #endif
<> 144:ef7eb2e8f9f7 152 }
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 status_t TPM_SetupPwm(TPM_Type *base,
<> 144:ef7eb2e8f9f7 155 const tpm_chnl_pwm_signal_param_t *chnlParams,
<> 144:ef7eb2e8f9f7 156 uint8_t numOfChnls,
<> 144:ef7eb2e8f9f7 157 tpm_pwm_mode_t mode,
<> 144:ef7eb2e8f9f7 158 uint32_t pwmFreq_Hz,
<> 144:ef7eb2e8f9f7 159 uint32_t srcClock_Hz)
<> 144:ef7eb2e8f9f7 160 {
<> 144:ef7eb2e8f9f7 161 assert(chnlParams);
<> 144:ef7eb2e8f9f7 162 assert(pwmFreq_Hz);
<> 144:ef7eb2e8f9f7 163 assert(numOfChnls);
<> 144:ef7eb2e8f9f7 164 assert(srcClock_Hz);
<> 144:ef7eb2e8f9f7 165
<> 144:ef7eb2e8f9f7 166 uint32_t mod;
<> 144:ef7eb2e8f9f7 167 uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK)));
<> 144:ef7eb2e8f9f7 168 uint16_t cnv;
<> 144:ef7eb2e8f9f7 169 uint8_t i;
<> 144:ef7eb2e8f9f7 170
<> 144:ef7eb2e8f9f7 171 #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
<> 144:ef7eb2e8f9f7 172 /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/
<> 144:ef7eb2e8f9f7 173 base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
<> 144:ef7eb2e8f9f7 174 #endif
<> 144:ef7eb2e8f9f7 175
<> 144:ef7eb2e8f9f7 176 switch (mode)
<> 144:ef7eb2e8f9f7 177 {
<> 144:ef7eb2e8f9f7 178 case kTPM_EdgeAlignedPwm:
<> 144:ef7eb2e8f9f7 179 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 180 case kTPM_CombinedPwm:
<> 144:ef7eb2e8f9f7 181 #endif
<> 144:ef7eb2e8f9f7 182 base->SC &= ~TPM_SC_CPWMS_MASK;
<> 144:ef7eb2e8f9f7 183 mod = (tpmClock / pwmFreq_Hz) - 1;
<> 144:ef7eb2e8f9f7 184 break;
<> 144:ef7eb2e8f9f7 185 case kTPM_CenterAlignedPwm:
<> 144:ef7eb2e8f9f7 186 base->SC |= TPM_SC_CPWMS_MASK;
<> 144:ef7eb2e8f9f7 187 mod = tpmClock / (pwmFreq_Hz * 2);
<> 144:ef7eb2e8f9f7 188 break;
<> 144:ef7eb2e8f9f7 189 default:
<> 144:ef7eb2e8f9f7 190 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 191 }
<> 144:ef7eb2e8f9f7 192
<> 144:ef7eb2e8f9f7 193 /* Return an error in case we overflow the registers, probably would require changing
<> 144:ef7eb2e8f9f7 194 * clock source to get the desired frequency */
<> 144:ef7eb2e8f9f7 195 if (mod > 65535U)
<> 144:ef7eb2e8f9f7 196 {
<> 144:ef7eb2e8f9f7 197 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199 /* Set the PWM period */
<> 144:ef7eb2e8f9f7 200 base->MOD = mod;
<> 144:ef7eb2e8f9f7 201
<> 144:ef7eb2e8f9f7 202 /* Setup each TPM channel */
<> 144:ef7eb2e8f9f7 203 for (i = 0; i < numOfChnls; i++)
<> 144:ef7eb2e8f9f7 204 {
<> 144:ef7eb2e8f9f7 205 /* Return error if requested dutycycle is greater than the max allowed */
<> 144:ef7eb2e8f9f7 206 if (chnlParams->dutyCyclePercent > 100)
<> 144:ef7eb2e8f9f7 207 {
<> 144:ef7eb2e8f9f7 208 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 209 }
<> 144:ef7eb2e8f9f7 210 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 211 if (mode == kTPM_CombinedPwm)
<> 144:ef7eb2e8f9f7 212 {
<> 144:ef7eb2e8f9f7 213 uint16_t cnvFirstEdge;
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 /* This check is added for combined mode as the channel number should be the pair number */
<> 144:ef7eb2e8f9f7 216 if (chnlParams->chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2))
<> 144:ef7eb2e8f9f7 217 {
<> 144:ef7eb2e8f9f7 218 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 219 }
<> 144:ef7eb2e8f9f7 220
<> 144:ef7eb2e8f9f7 221 /* Return error if requested value is greater than the max allowed */
<> 144:ef7eb2e8f9f7 222 if (chnlParams->firstEdgeDelayPercent > 100)
<> 144:ef7eb2e8f9f7 223 {
<> 144:ef7eb2e8f9f7 224 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 225 }
<> 144:ef7eb2e8f9f7 226 /* Configure delay of the first edge */
<> 144:ef7eb2e8f9f7 227 if (chnlParams->firstEdgeDelayPercent == 0)
<> 144:ef7eb2e8f9f7 228 {
<> 144:ef7eb2e8f9f7 229 /* No delay for the first edge */
<> 144:ef7eb2e8f9f7 230 cnvFirstEdge = 0;
<> 144:ef7eb2e8f9f7 231 }
<> 144:ef7eb2e8f9f7 232 else
<> 144:ef7eb2e8f9f7 233 {
<> 144:ef7eb2e8f9f7 234 cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100;
<> 144:ef7eb2e8f9f7 235 }
<> 144:ef7eb2e8f9f7 236 /* Configure dutycycle */
<> 144:ef7eb2e8f9f7 237 if (chnlParams->dutyCyclePercent == 0)
<> 144:ef7eb2e8f9f7 238 {
<> 144:ef7eb2e8f9f7 239 /* Signal stays low */
<> 144:ef7eb2e8f9f7 240 cnv = 0;
<> 144:ef7eb2e8f9f7 241 cnvFirstEdge = 0;
<> 144:ef7eb2e8f9f7 242 }
<> 144:ef7eb2e8f9f7 243 else
<> 144:ef7eb2e8f9f7 244 {
<> 144:ef7eb2e8f9f7 245 cnv = (mod * chnlParams->dutyCyclePercent) / 100;
<> 144:ef7eb2e8f9f7 246 /* For 100% duty cycle */
<> 144:ef7eb2e8f9f7 247 if (cnv >= mod)
<> 144:ef7eb2e8f9f7 248 {
<> 144:ef7eb2e8f9f7 249 cnv = mod + 1;
<> 144:ef7eb2e8f9f7 250 }
<> 144:ef7eb2e8f9f7 251 }
<> 144:ef7eb2e8f9f7 252
<> 144:ef7eb2e8f9f7 253 /* Set the combine bit for the channel pair */
<> 144:ef7eb2e8f9f7 254 base->COMBINE |= (1U << (TPM_COMBINE_COMBINE0_SHIFT + (TPM_COMBINE_SHIFT * chnlParams->chnlNumber)));
<> 144:ef7eb2e8f9f7 255
<> 144:ef7eb2e8f9f7 256 /* When switching mode, disable channel n first */
<> 144:ef7eb2e8f9f7 257 base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &=
<> 144:ef7eb2e8f9f7 258 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 259
<> 144:ef7eb2e8f9f7 260 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 261 while ((base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &
<> 144:ef7eb2e8f9f7 262 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 263 {
<> 144:ef7eb2e8f9f7 264 }
<> 144:ef7eb2e8f9f7 265
<> 144:ef7eb2e8f9f7 266 /* Set the requested PWM mode for channel n, PWM output requires mode select to be set to 2 */
<> 144:ef7eb2e8f9f7 267 base->CONTROLS[chnlParams->chnlNumber * 2].CnSC |=
<> 144:ef7eb2e8f9f7 268 ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
<> 144:ef7eb2e8f9f7 269
<> 144:ef7eb2e8f9f7 270 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 271 while (!(base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &
<> 144:ef7eb2e8f9f7 272 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 273 {
<> 144:ef7eb2e8f9f7 274 }
<> 144:ef7eb2e8f9f7 275 /* Set the channel pair values */
<> 144:ef7eb2e8f9f7 276 base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge;
<> 144:ef7eb2e8f9f7 277
<> 144:ef7eb2e8f9f7 278 /* When switching mode, disable channel n + 1 first */
<> 144:ef7eb2e8f9f7 279 base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &=
<> 144:ef7eb2e8f9f7 280 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 281
<> 144:ef7eb2e8f9f7 282 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 283 while ((base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &
<> 144:ef7eb2e8f9f7 284 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 285 {
<> 144:ef7eb2e8f9f7 286 }
<> 144:ef7eb2e8f9f7 287
<> 144:ef7eb2e8f9f7 288 /* Set the requested PWM mode for channel n + 1, PWM output requires mode select to be set to 2 */
<> 144:ef7eb2e8f9f7 289 base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC |=
<> 144:ef7eb2e8f9f7 290 ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
<> 144:ef7eb2e8f9f7 291
<> 144:ef7eb2e8f9f7 292 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 293 while (!(base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &
<> 144:ef7eb2e8f9f7 294 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 295 {
<> 144:ef7eb2e8f9f7 296 }
<> 144:ef7eb2e8f9f7 297 /* Set the channel pair values */
<> 144:ef7eb2e8f9f7 298 base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
<> 144:ef7eb2e8f9f7 299 }
<> 144:ef7eb2e8f9f7 300 else
<> 144:ef7eb2e8f9f7 301 {
<> 144:ef7eb2e8f9f7 302 #endif
<> 144:ef7eb2e8f9f7 303 if (chnlParams->dutyCyclePercent == 0)
<> 144:ef7eb2e8f9f7 304 {
<> 144:ef7eb2e8f9f7 305 /* Signal stays low */
<> 144:ef7eb2e8f9f7 306 cnv = 0;
<> 144:ef7eb2e8f9f7 307 }
<> 144:ef7eb2e8f9f7 308 else
<> 144:ef7eb2e8f9f7 309 {
<> 144:ef7eb2e8f9f7 310 cnv = (mod * chnlParams->dutyCyclePercent) / 100;
<> 144:ef7eb2e8f9f7 311 /* For 100% duty cycle */
<> 144:ef7eb2e8f9f7 312 if (cnv >= mod)
<> 144:ef7eb2e8f9f7 313 {
<> 144:ef7eb2e8f9f7 314 cnv = mod + 1;
<> 144:ef7eb2e8f9f7 315 }
<> 144:ef7eb2e8f9f7 316 }
<> 144:ef7eb2e8f9f7 317
<> 144:ef7eb2e8f9f7 318 /* When switching mode, disable channel first */
<> 144:ef7eb2e8f9f7 319 base->CONTROLS[chnlParams->chnlNumber].CnSC &=
<> 144:ef7eb2e8f9f7 320 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 321
<> 144:ef7eb2e8f9f7 322 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 323 while ((base->CONTROLS[chnlParams->chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 324 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 325 {
<> 144:ef7eb2e8f9f7 326 }
<> 144:ef7eb2e8f9f7 327
<> 144:ef7eb2e8f9f7 328 /* Set the requested PWM mode, PWM output requires mode select to be set to 2 */
<> 144:ef7eb2e8f9f7 329 base->CONTROLS[chnlParams->chnlNumber].CnSC |=
<> 144:ef7eb2e8f9f7 330 ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
<> 144:ef7eb2e8f9f7 331
<> 144:ef7eb2e8f9f7 332 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 333 while (!(base->CONTROLS[chnlParams->chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 334 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 335 {
<> 144:ef7eb2e8f9f7 336 }
<> 144:ef7eb2e8f9f7 337 base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
<> 144:ef7eb2e8f9f7 338 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 339 }
<> 144:ef7eb2e8f9f7 340 #endif
<> 144:ef7eb2e8f9f7 341
<> 144:ef7eb2e8f9f7 342 chnlParams++;
<> 144:ef7eb2e8f9f7 343 }
<> 144:ef7eb2e8f9f7 344
<> 144:ef7eb2e8f9f7 345 return kStatus_Success;
<> 144:ef7eb2e8f9f7 346 }
<> 144:ef7eb2e8f9f7 347
<> 144:ef7eb2e8f9f7 348 void TPM_UpdatePwmDutycycle(TPM_Type *base,
<> 144:ef7eb2e8f9f7 349 tpm_chnl_t chnlNumber,
<> 144:ef7eb2e8f9f7 350 tpm_pwm_mode_t currentPwmMode,
<> 144:ef7eb2e8f9f7 351 uint8_t dutyCyclePercent)
<> 144:ef7eb2e8f9f7 352 {
<> 144:ef7eb2e8f9f7 353 assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
<> 144:ef7eb2e8f9f7 354
<> 144:ef7eb2e8f9f7 355 uint16_t cnv, mod;
<> 144:ef7eb2e8f9f7 356
<> 144:ef7eb2e8f9f7 357 mod = base->MOD;
<> 144:ef7eb2e8f9f7 358 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 359 if (currentPwmMode == kTPM_CombinedPwm)
<> 144:ef7eb2e8f9f7 360 {
<> 144:ef7eb2e8f9f7 361 uint16_t cnvFirstEdge;
<> 144:ef7eb2e8f9f7 362
<> 144:ef7eb2e8f9f7 363 /* This check is added for combined mode as the channel number should be the pair number */
<> 144:ef7eb2e8f9f7 364 if (chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2))
<> 144:ef7eb2e8f9f7 365 {
<> 144:ef7eb2e8f9f7 366 return;
<> 144:ef7eb2e8f9f7 367 }
<> 144:ef7eb2e8f9f7 368 cnv = (mod * dutyCyclePercent) / 100;
<> 144:ef7eb2e8f9f7 369 cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV;
<> 144:ef7eb2e8f9f7 370 /* For 100% duty cycle */
<> 144:ef7eb2e8f9f7 371 if (cnv >= mod)
<> 144:ef7eb2e8f9f7 372 {
<> 144:ef7eb2e8f9f7 373 cnv = mod + 1;
<> 144:ef7eb2e8f9f7 374 }
<> 144:ef7eb2e8f9f7 375 base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
<> 144:ef7eb2e8f9f7 376 }
<> 144:ef7eb2e8f9f7 377 else
<> 144:ef7eb2e8f9f7 378 {
<> 144:ef7eb2e8f9f7 379 #endif
<> 144:ef7eb2e8f9f7 380 cnv = (mod * dutyCyclePercent) / 100;
<> 144:ef7eb2e8f9f7 381 /* For 100% duty cycle */
<> 144:ef7eb2e8f9f7 382 if (cnv >= mod)
<> 144:ef7eb2e8f9f7 383 {
<> 144:ef7eb2e8f9f7 384 cnv = mod + 1;
<> 144:ef7eb2e8f9f7 385 }
<> 144:ef7eb2e8f9f7 386 base->CONTROLS[chnlNumber].CnV = cnv;
<> 144:ef7eb2e8f9f7 387 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 388 }
<> 144:ef7eb2e8f9f7 389 #endif
<> 144:ef7eb2e8f9f7 390 }
<> 144:ef7eb2e8f9f7 391
<> 144:ef7eb2e8f9f7 392 void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level)
<> 144:ef7eb2e8f9f7 393 {
<> 144:ef7eb2e8f9f7 394 assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
<> 144:ef7eb2e8f9f7 395
<> 144:ef7eb2e8f9f7 396 uint32_t reg = base->CONTROLS[chnlNumber].CnSC & ~(TPM_CnSC_CHF_MASK);
<> 144:ef7eb2e8f9f7 397
<> 144:ef7eb2e8f9f7 398 /* When switching mode, disable channel first */
<> 144:ef7eb2e8f9f7 399 base->CONTROLS[chnlNumber].CnSC &=
<> 144:ef7eb2e8f9f7 400 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 401
<> 144:ef7eb2e8f9f7 402 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 403 while ((base->CONTROLS[chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 404 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 405 {
<> 144:ef7eb2e8f9f7 406 }
<> 144:ef7eb2e8f9f7 407
<> 144:ef7eb2e8f9f7 408 /* Clear the field and write the new level value */
<> 144:ef7eb2e8f9f7 409 reg &= ~(TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 410 reg |= ((uint32_t)level << TPM_CnSC_ELSA_SHIFT) & (TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 411
<> 144:ef7eb2e8f9f7 412 base->CONTROLS[chnlNumber].CnSC = reg;
<> 144:ef7eb2e8f9f7 413
<> 144:ef7eb2e8f9f7 414 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 415 reg &= (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 416 while (reg != (base->CONTROLS[chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 417 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 418 {
<> 144:ef7eb2e8f9f7 419 }
<> 144:ef7eb2e8f9f7 420 }
<> 144:ef7eb2e8f9f7 421
<> 144:ef7eb2e8f9f7 422 void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode)
<> 144:ef7eb2e8f9f7 423 {
<> 144:ef7eb2e8f9f7 424 assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
<> 144:ef7eb2e8f9f7 427 /* Clear quadrature Decoder mode for channel 0 or 1*/
<> 144:ef7eb2e8f9f7 428 if ((chnlNumber == 0) || (chnlNumber == 1))
<> 144:ef7eb2e8f9f7 429 {
<> 144:ef7eb2e8f9f7 430 base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
<> 144:ef7eb2e8f9f7 431 }
<> 144:ef7eb2e8f9f7 432 #endif
<> 144:ef7eb2e8f9f7 433
<> 144:ef7eb2e8f9f7 434 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 435 /* Clear the combine bit for chnlNumber */
<> 144:ef7eb2e8f9f7 436 base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2));
<> 144:ef7eb2e8f9f7 437 #endif
<> 144:ef7eb2e8f9f7 438
<> 144:ef7eb2e8f9f7 439 /* When switching mode, disable channel first */
<> 144:ef7eb2e8f9f7 440 base->CONTROLS[chnlNumber].CnSC &=
<> 144:ef7eb2e8f9f7 441 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 442
<> 144:ef7eb2e8f9f7 443 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 444 while ((base->CONTROLS[chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 445 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 446 {
<> 144:ef7eb2e8f9f7 447 }
<> 144:ef7eb2e8f9f7 448
<> 144:ef7eb2e8f9f7 449 /* Set the requested input capture mode */
<> 144:ef7eb2e8f9f7 450 base->CONTROLS[chnlNumber].CnSC |= captureMode;
<> 144:ef7eb2e8f9f7 451
<> 144:ef7eb2e8f9f7 452 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 453 while (!(base->CONTROLS[chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 454 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 455 {
<> 144:ef7eb2e8f9f7 456 }
<> 144:ef7eb2e8f9f7 457 }
<> 144:ef7eb2e8f9f7 458
<> 144:ef7eb2e8f9f7 459 void TPM_SetupOutputCompare(TPM_Type *base,
<> 144:ef7eb2e8f9f7 460 tpm_chnl_t chnlNumber,
<> 144:ef7eb2e8f9f7 461 tpm_output_compare_mode_t compareMode,
<> 144:ef7eb2e8f9f7 462 uint32_t compareValue)
<> 144:ef7eb2e8f9f7 463 {
<> 144:ef7eb2e8f9f7 464 assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
<> 144:ef7eb2e8f9f7 465
<> 144:ef7eb2e8f9f7 466 #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
<> 144:ef7eb2e8f9f7 467 /* Clear quadrature Decoder mode for channel 0 or 1 */
<> 144:ef7eb2e8f9f7 468 if ((chnlNumber == 0) || (chnlNumber == 1))
<> 144:ef7eb2e8f9f7 469 {
<> 144:ef7eb2e8f9f7 470 base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
<> 144:ef7eb2e8f9f7 471 }
<> 144:ef7eb2e8f9f7 472 #endif
<> 144:ef7eb2e8f9f7 473
<> 144:ef7eb2e8f9f7 474 /* When switching mode, disable channel first */
<> 144:ef7eb2e8f9f7 475 base->CONTROLS[chnlNumber].CnSC &=
<> 144:ef7eb2e8f9f7 476 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 477
<> 144:ef7eb2e8f9f7 478 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 479 while ((base->CONTROLS[chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 480 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 481 {
<> 144:ef7eb2e8f9f7 482 }
<> 144:ef7eb2e8f9f7 483
<> 144:ef7eb2e8f9f7 484 /* Setup the channel output behaviour when a match occurs with the compare value */
<> 144:ef7eb2e8f9f7 485 base->CONTROLS[chnlNumber].CnSC |= compareMode;
<> 144:ef7eb2e8f9f7 486
<> 144:ef7eb2e8f9f7 487 /* Setup the compare value */
<> 144:ef7eb2e8f9f7 488 base->CONTROLS[chnlNumber].CnV = compareValue;
<> 144:ef7eb2e8f9f7 489
<> 144:ef7eb2e8f9f7 490 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 491 while (!(base->CONTROLS[chnlNumber].CnSC &
<> 144:ef7eb2e8f9f7 492 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 493 {
<> 144:ef7eb2e8f9f7 494 }
<> 144:ef7eb2e8f9f7 495 }
<> 144:ef7eb2e8f9f7 496
<> 144:ef7eb2e8f9f7 497 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
<> 144:ef7eb2e8f9f7 498 void TPM_SetupDualEdgeCapture(TPM_Type *base,
<> 144:ef7eb2e8f9f7 499 tpm_chnl_t chnlPairNumber,
<> 144:ef7eb2e8f9f7 500 const tpm_dual_edge_capture_param_t *edgeParam,
<> 144:ef7eb2e8f9f7 501 uint32_t filterValue)
<> 144:ef7eb2e8f9f7 502 {
<> 144:ef7eb2e8f9f7 503 assert(edgeParam);
<> 144:ef7eb2e8f9f7 504 assert(chnlPairNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2);
<> 144:ef7eb2e8f9f7 505
<> 144:ef7eb2e8f9f7 506 uint32_t reg;
<> 144:ef7eb2e8f9f7 507 /* Clear quadrature Decoder mode for channel 0 or 1*/
<> 144:ef7eb2e8f9f7 508 #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
<> 144:ef7eb2e8f9f7 509 if (chnlPairNumber == 0)
<> 144:ef7eb2e8f9f7 510 {
<> 144:ef7eb2e8f9f7 511 base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
<> 144:ef7eb2e8f9f7 512 }
<> 144:ef7eb2e8f9f7 513 #endif
<> 144:ef7eb2e8f9f7 514
<> 144:ef7eb2e8f9f7 515 /* Unlock: When switching mode, disable channel first */
<> 144:ef7eb2e8f9f7 516 base->CONTROLS[chnlPairNumber * 2].CnSC &=
<> 144:ef7eb2e8f9f7 517 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 518
<> 144:ef7eb2e8f9f7 519 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 520 while ((base->CONTROLS[chnlPairNumber * 2].CnSC &
<> 144:ef7eb2e8f9f7 521 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 522 {
<> 144:ef7eb2e8f9f7 523 }
<> 144:ef7eb2e8f9f7 524
<> 144:ef7eb2e8f9f7 525 base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &=
<> 144:ef7eb2e8f9f7 526 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 527
<> 144:ef7eb2e8f9f7 528 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 529 while ((base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &
<> 144:ef7eb2e8f9f7 530 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 531 {
<> 144:ef7eb2e8f9f7 532 }
<> 144:ef7eb2e8f9f7 533
<> 144:ef7eb2e8f9f7 534 /* Now, the registers for input mode can be operated. */
<> 144:ef7eb2e8f9f7 535 if (edgeParam->enableSwap)
<> 144:ef7eb2e8f9f7 536 {
<> 144:ef7eb2e8f9f7 537 /* Set the combine and swap bits for the channel pair */
<> 144:ef7eb2e8f9f7 538 base->COMBINE |= (TPM_COMBINE_COMBINE0_MASK | TPM_COMBINE_COMSWAP0_MASK)
<> 144:ef7eb2e8f9f7 539 << (TPM_COMBINE_SHIFT * chnlPairNumber);
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541 /* Input filter setup for channel n+1 input */
<> 144:ef7eb2e8f9f7 542 reg = base->FILTER;
<> 144:ef7eb2e8f9f7 543 reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1)));
<> 144:ef7eb2e8f9f7 544 reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1)));
<> 144:ef7eb2e8f9f7 545 base->FILTER = reg;
<> 144:ef7eb2e8f9f7 546 }
<> 144:ef7eb2e8f9f7 547 else
<> 144:ef7eb2e8f9f7 548 {
<> 144:ef7eb2e8f9f7 549 reg = base->COMBINE;
<> 144:ef7eb2e8f9f7 550 /* Clear the swap bit for the channel pair */
<> 144:ef7eb2e8f9f7 551 reg &= ~(TPM_COMBINE_COMSWAP0_MASK << (TPM_COMBINE_COMSWAP0_SHIFT * chnlPairNumber));
<> 144:ef7eb2e8f9f7 552
<> 144:ef7eb2e8f9f7 553 /* Set the combine bit for the channel pair */
<> 144:ef7eb2e8f9f7 554 reg |= TPM_COMBINE_COMBINE0_MASK << (TPM_COMBINE_SHIFT * chnlPairNumber);
<> 144:ef7eb2e8f9f7 555 base->COMBINE = reg;
<> 144:ef7eb2e8f9f7 556
<> 144:ef7eb2e8f9f7 557 /* Input filter setup for channel n input */
<> 144:ef7eb2e8f9f7 558 reg = base->FILTER;
<> 144:ef7eb2e8f9f7 559 reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
<> 144:ef7eb2e8f9f7 560 reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
<> 144:ef7eb2e8f9f7 561 base->FILTER = reg;
<> 144:ef7eb2e8f9f7 562 }
<> 144:ef7eb2e8f9f7 563
<> 144:ef7eb2e8f9f7 564 /* Setup the edge detection from channel n */
<> 144:ef7eb2e8f9f7 565 base->CONTROLS[chnlPairNumber * 2].CnSC |= edgeParam->currChanEdgeMode;
<> 144:ef7eb2e8f9f7 566
<> 144:ef7eb2e8f9f7 567 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 568 while (!(base->CONTROLS[chnlPairNumber * 2].CnSC &
<> 144:ef7eb2e8f9f7 569 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 570 {
<> 144:ef7eb2e8f9f7 571 }
<> 144:ef7eb2e8f9f7 572
<> 144:ef7eb2e8f9f7 573 /* Setup the edge detection from channel n+1 */
<> 144:ef7eb2e8f9f7 574 base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC |= edgeParam->nextChanEdgeMode;
<> 144:ef7eb2e8f9f7 575
<> 144:ef7eb2e8f9f7 576 /* Wait till mode change is acknowledged */
<> 144:ef7eb2e8f9f7 577 while (!(base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC &
<> 144:ef7eb2e8f9f7 578 (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 579 {
<> 144:ef7eb2e8f9f7 580 }
<> 144:ef7eb2e8f9f7 581 }
<> 144:ef7eb2e8f9f7 582 #endif
<> 144:ef7eb2e8f9f7 583
<> 144:ef7eb2e8f9f7 584 #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
<> 144:ef7eb2e8f9f7 585 void TPM_SetupQuadDecode(TPM_Type *base,
<> 144:ef7eb2e8f9f7 586 const tpm_phase_params_t *phaseAParams,
<> 144:ef7eb2e8f9f7 587 const tpm_phase_params_t *phaseBParams,
<> 144:ef7eb2e8f9f7 588 tpm_quad_decode_mode_t quadMode)
<> 144:ef7eb2e8f9f7 589 {
<> 144:ef7eb2e8f9f7 590 assert(phaseAParams);
<> 144:ef7eb2e8f9f7 591 assert(phaseBParams);
<> 144:ef7eb2e8f9f7 592
<> 144:ef7eb2e8f9f7 593 base->CONTROLS[0].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 594
<> 144:ef7eb2e8f9f7 595 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 596 while ((base->CONTROLS[0].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 597 {
<> 144:ef7eb2e8f9f7 598 }
<> 144:ef7eb2e8f9f7 599 uint32_t reg;
<> 144:ef7eb2e8f9f7 600
<> 144:ef7eb2e8f9f7 601 /* Set Phase A filter value */
<> 144:ef7eb2e8f9f7 602 reg = base->FILTER;
<> 144:ef7eb2e8f9f7 603 reg &= ~(TPM_FILTER_CH0FVAL_MASK);
<> 144:ef7eb2e8f9f7 604 reg |= TPM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal);
<> 144:ef7eb2e8f9f7 605 base->FILTER = reg;
<> 144:ef7eb2e8f9f7 606
<> 144:ef7eb2e8f9f7 607 #if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL
<> 144:ef7eb2e8f9f7 608 /* Set Phase A polarity */
<> 144:ef7eb2e8f9f7 609 if (phaseAParams->phasePolarity)
<> 144:ef7eb2e8f9f7 610 {
<> 144:ef7eb2e8f9f7 611 base->POL |= TPM_POL_POL0_MASK;
<> 144:ef7eb2e8f9f7 612 }
<> 144:ef7eb2e8f9f7 613 else
<> 144:ef7eb2e8f9f7 614 {
<> 144:ef7eb2e8f9f7 615 base->POL &= ~TPM_POL_POL0_MASK;
<> 144:ef7eb2e8f9f7 616 }
<> 144:ef7eb2e8f9f7 617 #endif
<> 144:ef7eb2e8f9f7 618
<> 144:ef7eb2e8f9f7 619 base->CONTROLS[1].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
<> 144:ef7eb2e8f9f7 620
<> 144:ef7eb2e8f9f7 621 /* Wait till mode change to disable channel is acknowledged */
<> 144:ef7eb2e8f9f7 622 while ((base->CONTROLS[1].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
<> 144:ef7eb2e8f9f7 623 {
<> 144:ef7eb2e8f9f7 624 }
<> 144:ef7eb2e8f9f7 625 /* Set Phase B filter value */
<> 144:ef7eb2e8f9f7 626 reg = base->FILTER;
<> 144:ef7eb2e8f9f7 627 reg &= ~(TPM_FILTER_CH1FVAL_MASK);
<> 144:ef7eb2e8f9f7 628 reg |= TPM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal);
<> 144:ef7eb2e8f9f7 629 base->FILTER = reg;
<> 144:ef7eb2e8f9f7 630 #if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL
<> 144:ef7eb2e8f9f7 631 /* Set Phase B polarity */
<> 144:ef7eb2e8f9f7 632 if (phaseBParams->phasePolarity)
<> 144:ef7eb2e8f9f7 633 {
<> 144:ef7eb2e8f9f7 634 base->POL |= TPM_POL_POL1_MASK;
<> 144:ef7eb2e8f9f7 635 }
<> 144:ef7eb2e8f9f7 636 else
<> 144:ef7eb2e8f9f7 637 {
<> 144:ef7eb2e8f9f7 638 base->POL &= ~TPM_POL_POL1_MASK;
<> 144:ef7eb2e8f9f7 639 }
<> 144:ef7eb2e8f9f7 640 #endif
<> 144:ef7eb2e8f9f7 641
<> 144:ef7eb2e8f9f7 642 /* Set Quadrature mode */
<> 144:ef7eb2e8f9f7 643 reg = base->QDCTRL;
<> 144:ef7eb2e8f9f7 644 reg &= ~(TPM_QDCTRL_QUADMODE_MASK);
<> 144:ef7eb2e8f9f7 645 reg |= TPM_QDCTRL_QUADMODE(quadMode);
<> 144:ef7eb2e8f9f7 646 base->QDCTRL = reg;
<> 144:ef7eb2e8f9f7 647
<> 144:ef7eb2e8f9f7 648 /* Enable Quad decode */
<> 144:ef7eb2e8f9f7 649 base->QDCTRL |= TPM_QDCTRL_QUADEN_MASK;
<> 144:ef7eb2e8f9f7 650 }
<> 144:ef7eb2e8f9f7 651
<> 144:ef7eb2e8f9f7 652 #endif
<> 144:ef7eb2e8f9f7 653
<> 144:ef7eb2e8f9f7 654 void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask)
<> 144:ef7eb2e8f9f7 655 {
<> 144:ef7eb2e8f9f7 656 uint32_t chnlInterrupts = (mask & 0xFF);
<> 144:ef7eb2e8f9f7 657 uint8_t chnlNumber = 0;
<> 144:ef7eb2e8f9f7 658
<> 144:ef7eb2e8f9f7 659 /* Enable the timer overflow interrupt */
<> 144:ef7eb2e8f9f7 660 if (mask & kTPM_TimeOverflowInterruptEnable)
<> 144:ef7eb2e8f9f7 661 {
<> 144:ef7eb2e8f9f7 662 base->SC |= TPM_SC_TOIE_MASK;
<> 144:ef7eb2e8f9f7 663 }
<> 144:ef7eb2e8f9f7 664
<> 144:ef7eb2e8f9f7 665 /* Enable the channel interrupts */
<> 144:ef7eb2e8f9f7 666 while (chnlInterrupts)
<> 144:ef7eb2e8f9f7 667 {
<> 144:ef7eb2e8f9f7 668 if (chnlInterrupts & 0x1)
<> 144:ef7eb2e8f9f7 669 {
<> 144:ef7eb2e8f9f7 670 base->CONTROLS[chnlNumber].CnSC |= TPM_CnSC_CHIE_MASK;
<> 144:ef7eb2e8f9f7 671 }
<> 144:ef7eb2e8f9f7 672 chnlNumber++;
<> 144:ef7eb2e8f9f7 673 chnlInterrupts = chnlInterrupts >> 1U;
<> 144:ef7eb2e8f9f7 674 }
<> 144:ef7eb2e8f9f7 675 }
<> 144:ef7eb2e8f9f7 676
<> 144:ef7eb2e8f9f7 677 void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask)
<> 144:ef7eb2e8f9f7 678 {
<> 144:ef7eb2e8f9f7 679 uint32_t chnlInterrupts = (mask & 0xFF);
<> 144:ef7eb2e8f9f7 680 uint8_t chnlNumber = 0;
<> 144:ef7eb2e8f9f7 681
<> 144:ef7eb2e8f9f7 682 /* Disable the timer overflow interrupt */
<> 144:ef7eb2e8f9f7 683 if (mask & kTPM_TimeOverflowInterruptEnable)
<> 144:ef7eb2e8f9f7 684 {
<> 144:ef7eb2e8f9f7 685 base->SC &= ~TPM_SC_TOIE_MASK;
<> 144:ef7eb2e8f9f7 686 }
<> 144:ef7eb2e8f9f7 687
<> 144:ef7eb2e8f9f7 688 /* Disable the channel interrupts */
<> 144:ef7eb2e8f9f7 689 while (chnlInterrupts)
<> 144:ef7eb2e8f9f7 690 {
<> 144:ef7eb2e8f9f7 691 if (chnlInterrupts & 0x1)
<> 144:ef7eb2e8f9f7 692 {
<> 144:ef7eb2e8f9f7 693 base->CONTROLS[chnlNumber].CnSC &= ~TPM_CnSC_CHIE_MASK;
<> 144:ef7eb2e8f9f7 694 }
<> 144:ef7eb2e8f9f7 695 chnlNumber++;
<> 144:ef7eb2e8f9f7 696 chnlInterrupts = chnlInterrupts >> 1U;
<> 144:ef7eb2e8f9f7 697 }
<> 144:ef7eb2e8f9f7 698 }
<> 144:ef7eb2e8f9f7 699
<> 144:ef7eb2e8f9f7 700 uint32_t TPM_GetEnabledInterrupts(TPM_Type *base)
<> 144:ef7eb2e8f9f7 701 {
<> 144:ef7eb2e8f9f7 702 uint32_t enabledInterrupts = 0;
<> 144:ef7eb2e8f9f7 703 int8_t chnlCount = FSL_FEATURE_TPM_CHANNEL_COUNTn(base);
<> 144:ef7eb2e8f9f7 704
<> 144:ef7eb2e8f9f7 705 /* The CHANNEL_COUNT macro returns -1 if it cannot match the TPM instance */
<> 144:ef7eb2e8f9f7 706 assert(chnlCount != -1);
<> 144:ef7eb2e8f9f7 707
<> 144:ef7eb2e8f9f7 708 /* Check if timer overflow interrupt is enabled */
<> 144:ef7eb2e8f9f7 709 if (base->SC & TPM_SC_TOIE_MASK)
<> 144:ef7eb2e8f9f7 710 {
<> 144:ef7eb2e8f9f7 711 enabledInterrupts |= kTPM_TimeOverflowInterruptEnable;
<> 144:ef7eb2e8f9f7 712 }
<> 144:ef7eb2e8f9f7 713
<> 144:ef7eb2e8f9f7 714 /* Check if the channel interrupts are enabled */
<> 144:ef7eb2e8f9f7 715 while (chnlCount > 0)
<> 144:ef7eb2e8f9f7 716 {
<> 144:ef7eb2e8f9f7 717 chnlCount--;
<> 144:ef7eb2e8f9f7 718 if (base->CONTROLS[chnlCount].CnSC & TPM_CnSC_CHIE_MASK)
<> 144:ef7eb2e8f9f7 719 {
<> 144:ef7eb2e8f9f7 720 enabledInterrupts |= (1U << chnlCount);
<> 144:ef7eb2e8f9f7 721 }
<> 144:ef7eb2e8f9f7 722 }
<> 144:ef7eb2e8f9f7 723
<> 144:ef7eb2e8f9f7 724 return enabledInterrupts;
<> 144:ef7eb2e8f9f7 725 }