Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
kadonotakashi 0:8fdf9a60065b 3 * All rights reserved.
kadonotakashi 0:8fdf9a60065b 4 *
kadonotakashi 0:8fdf9a60065b 5 * Redistribution and use in source and binary forms, with or without modification,
kadonotakashi 0:8fdf9a60065b 6 * are permitted provided that the following conditions are met:
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * o Redistributions of source code must retain the above copyright notice, this list
kadonotakashi 0:8fdf9a60065b 9 * of conditions and the following disclaimer.
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * o Redistributions in binary form must reproduce the above copyright notice, this
kadonotakashi 0:8fdf9a60065b 12 * list of conditions and the following disclaimer in the documentation and/or
kadonotakashi 0:8fdf9a60065b 13 * other materials provided with the distribution.
kadonotakashi 0:8fdf9a60065b 14 *
kadonotakashi 0:8fdf9a60065b 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
kadonotakashi 0:8fdf9a60065b 16 * contributors may be used to endorse or promote products derived from this
kadonotakashi 0:8fdf9a60065b 17 * software without specific prior written permission.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
kadonotakashi 0:8fdf9a60065b 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
kadonotakashi 0:8fdf9a60065b 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
kadonotakashi 0:8fdf9a60065b 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
kadonotakashi 0:8fdf9a60065b 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
kadonotakashi 0:8fdf9a60065b 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
kadonotakashi 0:8fdf9a60065b 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
kadonotakashi 0:8fdf9a60065b 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
kadonotakashi 0:8fdf9a60065b 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
kadonotakashi 0:8fdf9a60065b 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kadonotakashi 0:8fdf9a60065b 29 */
kadonotakashi 0:8fdf9a60065b 30
kadonotakashi 0:8fdf9a60065b 31 #include "fsl_ftm.h"
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 34 * Prototypes
kadonotakashi 0:8fdf9a60065b 35 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 36 /*!
kadonotakashi 0:8fdf9a60065b 37 * @brief Gets the instance from the base address
kadonotakashi 0:8fdf9a60065b 38 *
kadonotakashi 0:8fdf9a60065b 39 * @param base FTM peripheral base address
kadonotakashi 0:8fdf9a60065b 40 *
kadonotakashi 0:8fdf9a60065b 41 * @return The FTM instance
kadonotakashi 0:8fdf9a60065b 42 */
kadonotakashi 0:8fdf9a60065b 43 static uint32_t FTM_GetInstance(FTM_Type *base);
kadonotakashi 0:8fdf9a60065b 44
kadonotakashi 0:8fdf9a60065b 45 /*!
kadonotakashi 0:8fdf9a60065b 46 * @brief Sets the FTM register PWM synchronization method
kadonotakashi 0:8fdf9a60065b 47 *
kadonotakashi 0:8fdf9a60065b 48 * This function will set the necessary bits for the PWM synchronization mode that
kadonotakashi 0:8fdf9a60065b 49 * user wishes to use.
kadonotakashi 0:8fdf9a60065b 50 *
kadonotakashi 0:8fdf9a60065b 51 * @param base FTM peripheral base address
kadonotakashi 0:8fdf9a60065b 52 * @param syncMethod Syncronization methods to use to update buffered registers. This is a logical
kadonotakashi 0:8fdf9a60065b 53 * OR of members of the enumeration ::ftm_pwm_sync_method_t
kadonotakashi 0:8fdf9a60065b 54 */
kadonotakashi 0:8fdf9a60065b 55 static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod);
kadonotakashi 0:8fdf9a60065b 56
kadonotakashi 0:8fdf9a60065b 57 /*!
kadonotakashi 0:8fdf9a60065b 58 * @brief Sets the reload points used as loading points for register update
kadonotakashi 0:8fdf9a60065b 59 *
kadonotakashi 0:8fdf9a60065b 60 * This function will set the necessary bits based on what the user wishes to use as loading
kadonotakashi 0:8fdf9a60065b 61 * points for FTM register update. When using this it is not required to use PWM synchnronization.
kadonotakashi 0:8fdf9a60065b 62 *
kadonotakashi 0:8fdf9a60065b 63 * @param base FTM peripheral base address
kadonotakashi 0:8fdf9a60065b 64 * @param reloadPoints FTM reload points. This is a logical OR of members of the
kadonotakashi 0:8fdf9a60065b 65 * enumeration ::ftm_reload_point_t
kadonotakashi 0:8fdf9a60065b 66 */
kadonotakashi 0:8fdf9a60065b 67 static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints);
kadonotakashi 0:8fdf9a60065b 68
kadonotakashi 0:8fdf9a60065b 69 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 70 * Variables
kadonotakashi 0:8fdf9a60065b 71 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 72 /*! @brief Pointers to FTM bases for each instance. */
kadonotakashi 0:8fdf9a60065b 73 static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS;
kadonotakashi 0:8fdf9a60065b 74
kadonotakashi 0:8fdf9a60065b 75 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
kadonotakashi 0:8fdf9a60065b 76 /*! @brief Pointers to FTM clocks for each instance. */
kadonotakashi 0:8fdf9a60065b 77 static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS;
kadonotakashi 0:8fdf9a60065b 78 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
kadonotakashi 0:8fdf9a60065b 79
kadonotakashi 0:8fdf9a60065b 80 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 81 * Code
kadonotakashi 0:8fdf9a60065b 82 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 83 static uint32_t FTM_GetInstance(FTM_Type *base)
kadonotakashi 0:8fdf9a60065b 84 {
kadonotakashi 0:8fdf9a60065b 85 uint32_t instance;
kadonotakashi 0:8fdf9a60065b 86 uint32_t ftmArrayCount = (sizeof(s_ftmBases) / sizeof(s_ftmBases[0]));
kadonotakashi 0:8fdf9a60065b 87
kadonotakashi 0:8fdf9a60065b 88 /* Find the instance index from base address mappings. */
kadonotakashi 0:8fdf9a60065b 89 for (instance = 0; instance < ftmArrayCount; instance++)
kadonotakashi 0:8fdf9a60065b 90 {
kadonotakashi 0:8fdf9a60065b 91 if (s_ftmBases[instance] == base)
kadonotakashi 0:8fdf9a60065b 92 {
kadonotakashi 0:8fdf9a60065b 93 break;
kadonotakashi 0:8fdf9a60065b 94 }
kadonotakashi 0:8fdf9a60065b 95 }
kadonotakashi 0:8fdf9a60065b 96
kadonotakashi 0:8fdf9a60065b 97 assert(instance < ftmArrayCount);
kadonotakashi 0:8fdf9a60065b 98
kadonotakashi 0:8fdf9a60065b 99 return instance;
kadonotakashi 0:8fdf9a60065b 100 }
kadonotakashi 0:8fdf9a60065b 101
kadonotakashi 0:8fdf9a60065b 102 static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod)
kadonotakashi 0:8fdf9a60065b 103 {
kadonotakashi 0:8fdf9a60065b 104 uint8_t chnlNumber = 0;
kadonotakashi 0:8fdf9a60065b 105 uint32_t reg = 0, syncReg = 0;
kadonotakashi 0:8fdf9a60065b 106
kadonotakashi 0:8fdf9a60065b 107 syncReg = base->SYNC;
kadonotakashi 0:8fdf9a60065b 108 /* Enable PWM synchronization of output mask register */
kadonotakashi 0:8fdf9a60065b 109 syncReg |= FTM_SYNC_SYNCHOM_MASK;
kadonotakashi 0:8fdf9a60065b 110
kadonotakashi 0:8fdf9a60065b 111 reg = base->COMBINE;
kadonotakashi 0:8fdf9a60065b 112 for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2); chnlNumber++)
kadonotakashi 0:8fdf9a60065b 113 {
kadonotakashi 0:8fdf9a60065b 114 /* Enable PWM synchronization of registers C(n)V and C(n+1)V */
kadonotakashi 0:8fdf9a60065b 115 reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlNumber)));
kadonotakashi 0:8fdf9a60065b 116 }
kadonotakashi 0:8fdf9a60065b 117 base->COMBINE = reg;
kadonotakashi 0:8fdf9a60065b 118
kadonotakashi 0:8fdf9a60065b 119 reg = base->SYNCONF;
kadonotakashi 0:8fdf9a60065b 120
kadonotakashi 0:8fdf9a60065b 121 /* Use enhanced PWM synchronization method. Use PWM sync to update register values */
kadonotakashi 0:8fdf9a60065b 122 reg |= (FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_CNTINC_MASK | FTM_SYNCONF_INVC_MASK | FTM_SYNCONF_SWOC_MASK);
kadonotakashi 0:8fdf9a60065b 123
kadonotakashi 0:8fdf9a60065b 124 if (syncMethod & FTM_SYNC_SWSYNC_MASK)
kadonotakashi 0:8fdf9a60065b 125 {
kadonotakashi 0:8fdf9a60065b 126 /* Enable needed bits for software trigger to update registers with its buffer value */
kadonotakashi 0:8fdf9a60065b 127 reg |= (FTM_SYNCONF_SWRSTCNT_MASK | FTM_SYNCONF_SWWRBUF_MASK | FTM_SYNCONF_SWINVC_MASK |
kadonotakashi 0:8fdf9a60065b 128 FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWOM_MASK);
kadonotakashi 0:8fdf9a60065b 129 }
kadonotakashi 0:8fdf9a60065b 130
kadonotakashi 0:8fdf9a60065b 131 if (syncMethod & (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK))
kadonotakashi 0:8fdf9a60065b 132 {
kadonotakashi 0:8fdf9a60065b 133 /* Enable needed bits for hardware trigger to update registers with its buffer value */
kadonotakashi 0:8fdf9a60065b 134 reg |= (FTM_SYNCONF_HWRSTCNT_MASK | FTM_SYNCONF_HWWRBUF_MASK | FTM_SYNCONF_HWINVC_MASK |
kadonotakashi 0:8fdf9a60065b 135 FTM_SYNCONF_HWSOC_MASK | FTM_SYNCONF_HWOM_MASK);
kadonotakashi 0:8fdf9a60065b 136
kadonotakashi 0:8fdf9a60065b 137 /* Enable the appropriate hardware trigger that is used for PWM sync */
kadonotakashi 0:8fdf9a60065b 138 if (syncMethod & FTM_SYNC_TRIG0_MASK)
kadonotakashi 0:8fdf9a60065b 139 {
kadonotakashi 0:8fdf9a60065b 140 syncReg |= FTM_SYNC_TRIG0_MASK;
kadonotakashi 0:8fdf9a60065b 141 }
kadonotakashi 0:8fdf9a60065b 142 if (syncMethod & FTM_SYNC_TRIG1_MASK)
kadonotakashi 0:8fdf9a60065b 143 {
kadonotakashi 0:8fdf9a60065b 144 syncReg |= FTM_SYNC_TRIG1_MASK;
kadonotakashi 0:8fdf9a60065b 145 }
kadonotakashi 0:8fdf9a60065b 146 if (syncMethod & FTM_SYNC_TRIG2_MASK)
kadonotakashi 0:8fdf9a60065b 147 {
kadonotakashi 0:8fdf9a60065b 148 syncReg |= FTM_SYNC_TRIG2_MASK;
kadonotakashi 0:8fdf9a60065b 149 }
kadonotakashi 0:8fdf9a60065b 150 }
kadonotakashi 0:8fdf9a60065b 151
kadonotakashi 0:8fdf9a60065b 152 /* Write back values to the SYNC register */
kadonotakashi 0:8fdf9a60065b 153 base->SYNC = syncReg;
kadonotakashi 0:8fdf9a60065b 154
kadonotakashi 0:8fdf9a60065b 155 /* Write the PWM synch values to the SYNCONF register */
kadonotakashi 0:8fdf9a60065b 156 base->SYNCONF = reg;
kadonotakashi 0:8fdf9a60065b 157 }
kadonotakashi 0:8fdf9a60065b 158
kadonotakashi 0:8fdf9a60065b 159 static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints)
kadonotakashi 0:8fdf9a60065b 160 {
kadonotakashi 0:8fdf9a60065b 161 uint32_t chnlNumber = 0;
kadonotakashi 0:8fdf9a60065b 162 uint32_t reg = 0;
kadonotakashi 0:8fdf9a60065b 163
kadonotakashi 0:8fdf9a60065b 164 /* Need CNTINC bit to be 1 for CNTIN register to update with its buffer value on reload */
kadonotakashi 0:8fdf9a60065b 165 base->SYNCONF |= FTM_SYNCONF_CNTINC_MASK;
kadonotakashi 0:8fdf9a60065b 166
kadonotakashi 0:8fdf9a60065b 167 reg = base->COMBINE;
kadonotakashi 0:8fdf9a60065b 168 for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2); chnlNumber++)
kadonotakashi 0:8fdf9a60065b 169 {
kadonotakashi 0:8fdf9a60065b 170 /* Need SYNCEN bit to be 1 for CnV reg to update with its buffer value on reload */
kadonotakashi 0:8fdf9a60065b 171 reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlNumber)));
kadonotakashi 0:8fdf9a60065b 172 }
kadonotakashi 0:8fdf9a60065b 173 base->COMBINE = reg;
kadonotakashi 0:8fdf9a60065b 174
kadonotakashi 0:8fdf9a60065b 175 /* Set the reload points */
kadonotakashi 0:8fdf9a60065b 176 reg = base->PWMLOAD;
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 /* Enable the selected channel match reload points */
kadonotakashi 0:8fdf9a60065b 179 reg &= ~((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1);
kadonotakashi 0:8fdf9a60065b 180 reg |= (reloadPoints & ((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1));
kadonotakashi 0:8fdf9a60065b 181
kadonotakashi 0:8fdf9a60065b 182 #if defined(FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD) && (FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD)
kadonotakashi 0:8fdf9a60065b 183 /* Enable half cycle match as a reload point */
kadonotakashi 0:8fdf9a60065b 184 if (reloadPoints & kFTM_HalfCycMatch)
kadonotakashi 0:8fdf9a60065b 185 {
kadonotakashi 0:8fdf9a60065b 186 reg |= FTM_PWMLOAD_HCSEL_MASK;
kadonotakashi 0:8fdf9a60065b 187 }
kadonotakashi 0:8fdf9a60065b 188 else
kadonotakashi 0:8fdf9a60065b 189 {
kadonotakashi 0:8fdf9a60065b 190 reg &= ~FTM_PWMLOAD_HCSEL_MASK;
kadonotakashi 0:8fdf9a60065b 191 }
kadonotakashi 0:8fdf9a60065b 192 #endif /* FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD */
kadonotakashi 0:8fdf9a60065b 193
kadonotakashi 0:8fdf9a60065b 194 base->PWMLOAD = reg;
kadonotakashi 0:8fdf9a60065b 195
kadonotakashi 0:8fdf9a60065b 196 /* These reload points are used when counter is in up-down counting mode */
kadonotakashi 0:8fdf9a60065b 197 reg = base->SYNC;
kadonotakashi 0:8fdf9a60065b 198 if (reloadPoints & kFTM_CntMax)
kadonotakashi 0:8fdf9a60065b 199 {
kadonotakashi 0:8fdf9a60065b 200 /* Reload when counter turns from up to down */
kadonotakashi 0:8fdf9a60065b 201 reg |= FTM_SYNC_CNTMAX_MASK;
kadonotakashi 0:8fdf9a60065b 202 }
kadonotakashi 0:8fdf9a60065b 203 else
kadonotakashi 0:8fdf9a60065b 204 {
kadonotakashi 0:8fdf9a60065b 205 reg &= ~FTM_SYNC_CNTMAX_MASK;
kadonotakashi 0:8fdf9a60065b 206 }
kadonotakashi 0:8fdf9a60065b 207
kadonotakashi 0:8fdf9a60065b 208 if (reloadPoints & kFTM_CntMin)
kadonotakashi 0:8fdf9a60065b 209 {
kadonotakashi 0:8fdf9a60065b 210 /* Reload when counter turns from down to up */
kadonotakashi 0:8fdf9a60065b 211 reg |= FTM_SYNC_CNTMIN_MASK;
kadonotakashi 0:8fdf9a60065b 212 }
kadonotakashi 0:8fdf9a60065b 213 else
kadonotakashi 0:8fdf9a60065b 214 {
kadonotakashi 0:8fdf9a60065b 215 reg &= ~FTM_SYNC_CNTMIN_MASK;
kadonotakashi 0:8fdf9a60065b 216 }
kadonotakashi 0:8fdf9a60065b 217 base->SYNC = reg;
kadonotakashi 0:8fdf9a60065b 218 }
kadonotakashi 0:8fdf9a60065b 219
kadonotakashi 0:8fdf9a60065b 220 status_t FTM_Init(FTM_Type *base, const ftm_config_t *config)
kadonotakashi 0:8fdf9a60065b 221 {
kadonotakashi 0:8fdf9a60065b 222 assert(config);
kadonotakashi 0:8fdf9a60065b 223
kadonotakashi 0:8fdf9a60065b 224 uint32_t reg;
kadonotakashi 0:8fdf9a60065b 225
kadonotakashi 0:8fdf9a60065b 226 if (!(config->pwmSyncMode &
kadonotakashi 0:8fdf9a60065b 227 (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK | FTM_SYNC_SWSYNC_MASK)))
kadonotakashi 0:8fdf9a60065b 228 {
kadonotakashi 0:8fdf9a60065b 229 /* Invalid PWM sync mode */
kadonotakashi 0:8fdf9a60065b 230 return kStatus_Fail;
kadonotakashi 0:8fdf9a60065b 231 }
kadonotakashi 0:8fdf9a60065b 232
kadonotakashi 0:8fdf9a60065b 233 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
kadonotakashi 0:8fdf9a60065b 234 /* Ungate the FTM clock*/
kadonotakashi 0:8fdf9a60065b 235 CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 236 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
kadonotakashi 0:8fdf9a60065b 237
kadonotakashi 0:8fdf9a60065b 238 /* Configure the fault mode, enable FTM mode and disable write protection */
kadonotakashi 0:8fdf9a60065b 239 base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | FTM_MODE_WPDIS_MASK;
kadonotakashi 0:8fdf9a60065b 240
kadonotakashi 0:8fdf9a60065b 241 /* Configure the update mechanism for buffered registers */
kadonotakashi 0:8fdf9a60065b 242 FTM_SetPwmSync(base, config->pwmSyncMode);
kadonotakashi 0:8fdf9a60065b 243
kadonotakashi 0:8fdf9a60065b 244 /* Setup intermediate register reload points */
kadonotakashi 0:8fdf9a60065b 245 FTM_SetReloadPoints(base, config->reloadPoints);
kadonotakashi 0:8fdf9a60065b 246
kadonotakashi 0:8fdf9a60065b 247 /* Set the clock prescale factor */
kadonotakashi 0:8fdf9a60065b 248 base->SC = FTM_SC_PS(config->prescale);
kadonotakashi 0:8fdf9a60065b 249
kadonotakashi 0:8fdf9a60065b 250 /* Setup the counter operation */
kadonotakashi 0:8fdf9a60065b 251 base->CONF = (FTM_CONF_BDMMODE(config->bdmMode) | FTM_CONF_GTBEEN(config->useGlobalTimeBase));
kadonotakashi 0:8fdf9a60065b 252
kadonotakashi 0:8fdf9a60065b 253 /* Initial state of channel output */
kadonotakashi 0:8fdf9a60065b 254 base->OUTINIT = config->chnlInitState;
kadonotakashi 0:8fdf9a60065b 255
kadonotakashi 0:8fdf9a60065b 256 /* Channel polarity */
kadonotakashi 0:8fdf9a60065b 257 base->POL = config->chnlPolarity;
kadonotakashi 0:8fdf9a60065b 258
kadonotakashi 0:8fdf9a60065b 259 /* Set the external trigger sources */
kadonotakashi 0:8fdf9a60065b 260 base->EXTTRIG = config->extTriggers;
kadonotakashi 0:8fdf9a60065b 261 #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) && (FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER)
kadonotakashi 0:8fdf9a60065b 262 if (config->extTriggers & kFTM_ReloadInitTrigger)
kadonotakashi 0:8fdf9a60065b 263 {
kadonotakashi 0:8fdf9a60065b 264 base->CONF |= FTM_CONF_ITRIGR_MASK;
kadonotakashi 0:8fdf9a60065b 265 }
kadonotakashi 0:8fdf9a60065b 266 else
kadonotakashi 0:8fdf9a60065b 267 {
kadonotakashi 0:8fdf9a60065b 268 base->CONF &= ~FTM_CONF_ITRIGR_MASK;
kadonotakashi 0:8fdf9a60065b 269 }
kadonotakashi 0:8fdf9a60065b 270 #endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */
kadonotakashi 0:8fdf9a60065b 271
kadonotakashi 0:8fdf9a60065b 272 /* FTM deadtime insertion control */
kadonotakashi 0:8fdf9a60065b 273 base->DEADTIME = (0u |
kadonotakashi 0:8fdf9a60065b 274 #if defined(FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE) && (FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE)
kadonotakashi 0:8fdf9a60065b 275 /* Has extended deadtime value register) */
kadonotakashi 0:8fdf9a60065b 276 FTM_DEADTIME_DTVALEX(config->deadTimeValue >> 6) |
kadonotakashi 0:8fdf9a60065b 277 #endif /* FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE */
kadonotakashi 0:8fdf9a60065b 278 FTM_DEADTIME_DTPS(config->deadTimePrescale) |
kadonotakashi 0:8fdf9a60065b 279 FTM_DEADTIME_DTVAL(config->deadTimeValue));
kadonotakashi 0:8fdf9a60065b 280
kadonotakashi 0:8fdf9a60065b 281 /* FTM fault filter value */
kadonotakashi 0:8fdf9a60065b 282 reg = base->FLTCTRL;
kadonotakashi 0:8fdf9a60065b 283 reg &= ~FTM_FLTCTRL_FFVAL_MASK;
kadonotakashi 0:8fdf9a60065b 284 reg |= FTM_FLTCTRL_FFVAL(config->faultFilterValue);
kadonotakashi 0:8fdf9a60065b 285 base->FLTCTRL = reg;
kadonotakashi 0:8fdf9a60065b 286
kadonotakashi 0:8fdf9a60065b 287 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 288 }
kadonotakashi 0:8fdf9a60065b 289
kadonotakashi 0:8fdf9a60065b 290 void FTM_Deinit(FTM_Type *base)
kadonotakashi 0:8fdf9a60065b 291 {
kadonotakashi 0:8fdf9a60065b 292 /* Set clock source to none to disable counter */
kadonotakashi 0:8fdf9a60065b 293 base->SC &= ~(FTM_SC_CLKS_MASK);
kadonotakashi 0:8fdf9a60065b 294
kadonotakashi 0:8fdf9a60065b 295 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
kadonotakashi 0:8fdf9a60065b 296 /* Gate the FTM clock */
kadonotakashi 0:8fdf9a60065b 297 CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 298 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
kadonotakashi 0:8fdf9a60065b 299 }
kadonotakashi 0:8fdf9a60065b 300
kadonotakashi 0:8fdf9a60065b 301 void FTM_GetDefaultConfig(ftm_config_t *config)
kadonotakashi 0:8fdf9a60065b 302 {
kadonotakashi 0:8fdf9a60065b 303 assert(config);
kadonotakashi 0:8fdf9a60065b 304
kadonotakashi 0:8fdf9a60065b 305 /* Divide FTM clock by 1 */
kadonotakashi 0:8fdf9a60065b 306 config->prescale = kFTM_Prescale_Divide_1;
kadonotakashi 0:8fdf9a60065b 307 /* FTM behavior in BDM mode */
kadonotakashi 0:8fdf9a60065b 308 config->bdmMode = kFTM_BdmMode_0;
kadonotakashi 0:8fdf9a60065b 309 /* Software trigger will be used to update registers */
kadonotakashi 0:8fdf9a60065b 310 config->pwmSyncMode = kFTM_SoftwareTrigger;
kadonotakashi 0:8fdf9a60065b 311 /* No intermediate register load */
kadonotakashi 0:8fdf9a60065b 312 config->reloadPoints = 0;
kadonotakashi 0:8fdf9a60065b 313 /* Fault control disabled for all channels */
kadonotakashi 0:8fdf9a60065b 314 config->faultMode = kFTM_Fault_Disable;
kadonotakashi 0:8fdf9a60065b 315 /* Disable the fault filter */
kadonotakashi 0:8fdf9a60065b 316 config->faultFilterValue = 0;
kadonotakashi 0:8fdf9a60065b 317 /* Divide the system clock by 1 */
kadonotakashi 0:8fdf9a60065b 318 config->deadTimePrescale = kFTM_Deadtime_Prescale_1;
kadonotakashi 0:8fdf9a60065b 319 /* No counts are inserted */
kadonotakashi 0:8fdf9a60065b 320 config->deadTimeValue = 0;
kadonotakashi 0:8fdf9a60065b 321 /* No external trigger */
kadonotakashi 0:8fdf9a60065b 322 config->extTriggers = 0;
kadonotakashi 0:8fdf9a60065b 323 /* Initialization value is 0 for all channels */
kadonotakashi 0:8fdf9a60065b 324 config->chnlInitState = 0;
kadonotakashi 0:8fdf9a60065b 325 /* Active high polarity for all channels */
kadonotakashi 0:8fdf9a60065b 326 config->chnlPolarity = 0;
kadonotakashi 0:8fdf9a60065b 327 /* Use internal FTM counter as timebase */
kadonotakashi 0:8fdf9a60065b 328 config->useGlobalTimeBase = false;
kadonotakashi 0:8fdf9a60065b 329 }
kadonotakashi 0:8fdf9a60065b 330
kadonotakashi 0:8fdf9a60065b 331 status_t FTM_SetupPwm(FTM_Type *base,
kadonotakashi 0:8fdf9a60065b 332 const ftm_chnl_pwm_signal_param_t *chnlParams,
kadonotakashi 0:8fdf9a60065b 333 uint8_t numOfChnls,
kadonotakashi 0:8fdf9a60065b 334 ftm_pwm_mode_t mode,
kadonotakashi 0:8fdf9a60065b 335 uint32_t pwmFreq_Hz,
kadonotakashi 0:8fdf9a60065b 336 uint32_t srcClock_Hz)
kadonotakashi 0:8fdf9a60065b 337 {
kadonotakashi 0:8fdf9a60065b 338 assert(chnlParams);
kadonotakashi 0:8fdf9a60065b 339 assert(srcClock_Hz);
kadonotakashi 0:8fdf9a60065b 340 assert(pwmFreq_Hz);
kadonotakashi 0:8fdf9a60065b 341 assert(numOfChnls);
kadonotakashi 0:8fdf9a60065b 342
kadonotakashi 0:8fdf9a60065b 343 uint32_t mod, reg;
kadonotakashi 0:8fdf9a60065b 344 uint32_t ftmClock = (srcClock_Hz / (1U << (base->SC & FTM_SC_PS_MASK)));
kadonotakashi 0:8fdf9a60065b 345 uint16_t cnv, cnvFirstEdge;
kadonotakashi 0:8fdf9a60065b 346 uint8_t i;
kadonotakashi 0:8fdf9a60065b 347
kadonotakashi 0:8fdf9a60065b 348 switch (mode)
kadonotakashi 0:8fdf9a60065b 349 {
kadonotakashi 0:8fdf9a60065b 350 case kFTM_EdgeAlignedPwm:
kadonotakashi 0:8fdf9a60065b 351 case kFTM_CombinedPwm:
kadonotakashi 0:8fdf9a60065b 352 base->SC &= ~FTM_SC_CPWMS_MASK;
kadonotakashi 0:8fdf9a60065b 353 mod = (ftmClock / pwmFreq_Hz) - 1;
kadonotakashi 0:8fdf9a60065b 354 break;
kadonotakashi 0:8fdf9a60065b 355 case kFTM_CenterAlignedPwm:
kadonotakashi 0:8fdf9a60065b 356 base->SC |= FTM_SC_CPWMS_MASK;
kadonotakashi 0:8fdf9a60065b 357 mod = ftmClock / (pwmFreq_Hz * 2);
kadonotakashi 0:8fdf9a60065b 358 break;
kadonotakashi 0:8fdf9a60065b 359 default:
kadonotakashi 0:8fdf9a60065b 360 return kStatus_Fail;
kadonotakashi 0:8fdf9a60065b 361 }
kadonotakashi 0:8fdf9a60065b 362
kadonotakashi 0:8fdf9a60065b 363 /* Return an error in case we overflow the registers, probably would require changing
kadonotakashi 0:8fdf9a60065b 364 * clock source to get the desired frequency */
kadonotakashi 0:8fdf9a60065b 365 if (mod > 65535U)
kadonotakashi 0:8fdf9a60065b 366 {
kadonotakashi 0:8fdf9a60065b 367 return kStatus_Fail;
kadonotakashi 0:8fdf9a60065b 368 }
kadonotakashi 0:8fdf9a60065b 369 /* Set the PWM period */
kadonotakashi 0:8fdf9a60065b 370 base->MOD = mod;
kadonotakashi 0:8fdf9a60065b 371
kadonotakashi 0:8fdf9a60065b 372 /* Setup each FTM channel */
kadonotakashi 0:8fdf9a60065b 373 for (i = 0; i < numOfChnls; i++)
kadonotakashi 0:8fdf9a60065b 374 {
kadonotakashi 0:8fdf9a60065b 375 /* Return error if requested dutycycle is greater than the max allowed */
kadonotakashi 0:8fdf9a60065b 376 if (chnlParams->dutyCyclePercent > 100)
kadonotakashi 0:8fdf9a60065b 377 {
kadonotakashi 0:8fdf9a60065b 378 return kStatus_Fail;
kadonotakashi 0:8fdf9a60065b 379 }
kadonotakashi 0:8fdf9a60065b 380
kadonotakashi 0:8fdf9a60065b 381 if ((mode == kFTM_EdgeAlignedPwm) || (mode == kFTM_CenterAlignedPwm))
kadonotakashi 0:8fdf9a60065b 382 {
kadonotakashi 0:8fdf9a60065b 383 /* Clear the current mode and edge level bits */
kadonotakashi 0:8fdf9a60065b 384 reg = base->CONTROLS[chnlParams->chnlNumber].CnSC;
kadonotakashi 0:8fdf9a60065b 385 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 386
kadonotakashi 0:8fdf9a60065b 387 /* Setup the active level */
kadonotakashi 0:8fdf9a60065b 388 reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
kadonotakashi 0:8fdf9a60065b 389
kadonotakashi 0:8fdf9a60065b 390 /* Edge-aligned mode needs MSB to be 1, don't care for Center-aligned mode */
kadonotakashi 0:8fdf9a60065b 391 reg |= FTM_CnSC_MSB(1U);
kadonotakashi 0:8fdf9a60065b 392
kadonotakashi 0:8fdf9a60065b 393 /* Update the mode and edge level */
kadonotakashi 0:8fdf9a60065b 394 base->CONTROLS[chnlParams->chnlNumber].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 395
kadonotakashi 0:8fdf9a60065b 396 if (chnlParams->dutyCyclePercent == 0)
kadonotakashi 0:8fdf9a60065b 397 {
kadonotakashi 0:8fdf9a60065b 398 /* Signal stays low */
kadonotakashi 0:8fdf9a60065b 399 cnv = 0;
kadonotakashi 0:8fdf9a60065b 400 }
kadonotakashi 0:8fdf9a60065b 401 else
kadonotakashi 0:8fdf9a60065b 402 {
kadonotakashi 0:8fdf9a60065b 403 cnv = (mod * chnlParams->dutyCyclePercent) / 100;
kadonotakashi 0:8fdf9a60065b 404 /* For 100% duty cycle */
kadonotakashi 0:8fdf9a60065b 405 if (cnv >= mod)
kadonotakashi 0:8fdf9a60065b 406 {
kadonotakashi 0:8fdf9a60065b 407 cnv = mod + 1;
kadonotakashi 0:8fdf9a60065b 408 }
kadonotakashi 0:8fdf9a60065b 409 }
kadonotakashi 0:8fdf9a60065b 410
kadonotakashi 0:8fdf9a60065b 411 base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
kadonotakashi 0:8fdf9a60065b 412 #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
kadonotakashi 0:8fdf9a60065b 413 /* Set to output mode */
kadonotakashi 0:8fdf9a60065b 414 FTM_SetPwmOutputEnable(base, chnlParams->chnlNumber, true);
kadonotakashi 0:8fdf9a60065b 415 #endif
kadonotakashi 0:8fdf9a60065b 416 }
kadonotakashi 0:8fdf9a60065b 417 else
kadonotakashi 0:8fdf9a60065b 418 {
kadonotakashi 0:8fdf9a60065b 419 /* This check is added for combined mode as the channel number should be the pair number */
kadonotakashi 0:8fdf9a60065b 420 if (chnlParams->chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2))
kadonotakashi 0:8fdf9a60065b 421 {
kadonotakashi 0:8fdf9a60065b 422 return kStatus_Fail;
kadonotakashi 0:8fdf9a60065b 423 }
kadonotakashi 0:8fdf9a60065b 424
kadonotakashi 0:8fdf9a60065b 425 /* Return error if requested value is greater than the max allowed */
kadonotakashi 0:8fdf9a60065b 426 if (chnlParams->firstEdgeDelayPercent > 100)
kadonotakashi 0:8fdf9a60065b 427 {
kadonotakashi 0:8fdf9a60065b 428 return kStatus_Fail;
kadonotakashi 0:8fdf9a60065b 429 }
kadonotakashi 0:8fdf9a60065b 430
kadonotakashi 0:8fdf9a60065b 431 /* Configure delay of the first edge */
kadonotakashi 0:8fdf9a60065b 432 if (chnlParams->firstEdgeDelayPercent == 0)
kadonotakashi 0:8fdf9a60065b 433 {
kadonotakashi 0:8fdf9a60065b 434 /* No delay for the first edge */
kadonotakashi 0:8fdf9a60065b 435 cnvFirstEdge = 0;
kadonotakashi 0:8fdf9a60065b 436 }
kadonotakashi 0:8fdf9a60065b 437 else
kadonotakashi 0:8fdf9a60065b 438 {
kadonotakashi 0:8fdf9a60065b 439 cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100;
kadonotakashi 0:8fdf9a60065b 440 }
kadonotakashi 0:8fdf9a60065b 441
kadonotakashi 0:8fdf9a60065b 442 /* Configure dutycycle */
kadonotakashi 0:8fdf9a60065b 443 if (chnlParams->dutyCyclePercent == 0)
kadonotakashi 0:8fdf9a60065b 444 {
kadonotakashi 0:8fdf9a60065b 445 /* Signal stays low */
kadonotakashi 0:8fdf9a60065b 446 cnv = 0;
kadonotakashi 0:8fdf9a60065b 447 cnvFirstEdge = 0;
kadonotakashi 0:8fdf9a60065b 448 }
kadonotakashi 0:8fdf9a60065b 449 else
kadonotakashi 0:8fdf9a60065b 450 {
kadonotakashi 0:8fdf9a60065b 451 cnv = (mod * chnlParams->dutyCyclePercent) / 100;
kadonotakashi 0:8fdf9a60065b 452 /* For 100% duty cycle */
kadonotakashi 0:8fdf9a60065b 453 if (cnv >= mod)
kadonotakashi 0:8fdf9a60065b 454 {
kadonotakashi 0:8fdf9a60065b 455 cnv = mod + 1;
kadonotakashi 0:8fdf9a60065b 456 }
kadonotakashi 0:8fdf9a60065b 457 }
kadonotakashi 0:8fdf9a60065b 458
kadonotakashi 0:8fdf9a60065b 459 /* Clear the current mode and edge level bits for channel n */
kadonotakashi 0:8fdf9a60065b 460 reg = base->CONTROLS[chnlParams->chnlNumber * 2].CnSC;
kadonotakashi 0:8fdf9a60065b 461 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 462
kadonotakashi 0:8fdf9a60065b 463 /* Setup the active level for channel n */
kadonotakashi 0:8fdf9a60065b 464 reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
kadonotakashi 0:8fdf9a60065b 465
kadonotakashi 0:8fdf9a60065b 466 /* Update the mode and edge level for channel n */
kadonotakashi 0:8fdf9a60065b 467 base->CONTROLS[chnlParams->chnlNumber * 2].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 468
kadonotakashi 0:8fdf9a60065b 469 /* Clear the current mode and edge level bits for channel n + 1 */
kadonotakashi 0:8fdf9a60065b 470 reg = base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC;
kadonotakashi 0:8fdf9a60065b 471 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 472
kadonotakashi 0:8fdf9a60065b 473 /* Setup the active level for channel n + 1 */
kadonotakashi 0:8fdf9a60065b 474 reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
kadonotakashi 0:8fdf9a60065b 475
kadonotakashi 0:8fdf9a60065b 476 /* Update the mode and edge level for channel n + 1*/
kadonotakashi 0:8fdf9a60065b 477 base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 478
kadonotakashi 0:8fdf9a60065b 479 /* Set the combine bit for the channel pair */
kadonotakashi 0:8fdf9a60065b 480 base->COMBINE |=
kadonotakashi 0:8fdf9a60065b 481 (1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlParams->chnlNumber)));
kadonotakashi 0:8fdf9a60065b 482
kadonotakashi 0:8fdf9a60065b 483 /* Set the channel pair values */
kadonotakashi 0:8fdf9a60065b 484 base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge;
kadonotakashi 0:8fdf9a60065b 485 base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
kadonotakashi 0:8fdf9a60065b 486
kadonotakashi 0:8fdf9a60065b 487 #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
kadonotakashi 0:8fdf9a60065b 488 /* Set to output mode */
kadonotakashi 0:8fdf9a60065b 489 FTM_SetPwmOutputEnable(base, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2), true);
kadonotakashi 0:8fdf9a60065b 490 FTM_SetPwmOutputEnable(base, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2 + 1), true);
kadonotakashi 0:8fdf9a60065b 491 #endif
kadonotakashi 0:8fdf9a60065b 492 }
kadonotakashi 0:8fdf9a60065b 493 chnlParams++;
kadonotakashi 0:8fdf9a60065b 494 }
kadonotakashi 0:8fdf9a60065b 495
kadonotakashi 0:8fdf9a60065b 496 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 497 }
kadonotakashi 0:8fdf9a60065b 498
kadonotakashi 0:8fdf9a60065b 499 void FTM_UpdatePwmDutycycle(FTM_Type *base,
kadonotakashi 0:8fdf9a60065b 500 ftm_chnl_t chnlNumber,
kadonotakashi 0:8fdf9a60065b 501 ftm_pwm_mode_t currentPwmMode,
kadonotakashi 0:8fdf9a60065b 502 uint8_t dutyCyclePercent)
kadonotakashi 0:8fdf9a60065b 503 {
kadonotakashi 0:8fdf9a60065b 504 uint16_t cnv, cnvFirstEdge = 0, mod;
kadonotakashi 0:8fdf9a60065b 505
kadonotakashi 0:8fdf9a60065b 506 mod = base->MOD;
kadonotakashi 0:8fdf9a60065b 507 if ((currentPwmMode == kFTM_EdgeAlignedPwm) || (currentPwmMode == kFTM_CenterAlignedPwm))
kadonotakashi 0:8fdf9a60065b 508 {
kadonotakashi 0:8fdf9a60065b 509 cnv = (mod * dutyCyclePercent) / 100;
kadonotakashi 0:8fdf9a60065b 510 /* For 100% duty cycle */
kadonotakashi 0:8fdf9a60065b 511 if (cnv >= mod)
kadonotakashi 0:8fdf9a60065b 512 {
kadonotakashi 0:8fdf9a60065b 513 cnv = mod + 1;
kadonotakashi 0:8fdf9a60065b 514 }
kadonotakashi 0:8fdf9a60065b 515 base->CONTROLS[chnlNumber].CnV = cnv;
kadonotakashi 0:8fdf9a60065b 516 }
kadonotakashi 0:8fdf9a60065b 517 else
kadonotakashi 0:8fdf9a60065b 518 {
kadonotakashi 0:8fdf9a60065b 519 /* This check is added for combined mode as the channel number should be the pair number */
kadonotakashi 0:8fdf9a60065b 520 if (chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2))
kadonotakashi 0:8fdf9a60065b 521 {
kadonotakashi 0:8fdf9a60065b 522 return;
kadonotakashi 0:8fdf9a60065b 523 }
kadonotakashi 0:8fdf9a60065b 524
kadonotakashi 0:8fdf9a60065b 525 cnv = (mod * dutyCyclePercent) / 100;
kadonotakashi 0:8fdf9a60065b 526 cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV;
kadonotakashi 0:8fdf9a60065b 527 /* For 100% duty cycle */
kadonotakashi 0:8fdf9a60065b 528 if (cnv >= mod)
kadonotakashi 0:8fdf9a60065b 529 {
kadonotakashi 0:8fdf9a60065b 530 cnv = mod + 1;
kadonotakashi 0:8fdf9a60065b 531 }
kadonotakashi 0:8fdf9a60065b 532 base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
kadonotakashi 0:8fdf9a60065b 533 }
kadonotakashi 0:8fdf9a60065b 534 }
kadonotakashi 0:8fdf9a60065b 535
kadonotakashi 0:8fdf9a60065b 536 void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, uint8_t level)
kadonotakashi 0:8fdf9a60065b 537 {
kadonotakashi 0:8fdf9a60065b 538 uint32_t reg = base->CONTROLS[chnlNumber].CnSC;
kadonotakashi 0:8fdf9a60065b 539
kadonotakashi 0:8fdf9a60065b 540 /* Clear the field and write the new level value */
kadonotakashi 0:8fdf9a60065b 541 reg &= ~(FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 542 reg |= ((uint32_t)level << FTM_CnSC_ELSA_SHIFT) & (FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 543
kadonotakashi 0:8fdf9a60065b 544 base->CONTROLS[chnlNumber].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 545 }
kadonotakashi 0:8fdf9a60065b 546
kadonotakashi 0:8fdf9a60065b 547 void FTM_SetupInputCapture(FTM_Type *base,
kadonotakashi 0:8fdf9a60065b 548 ftm_chnl_t chnlNumber,
kadonotakashi 0:8fdf9a60065b 549 ftm_input_capture_edge_t captureMode,
kadonotakashi 0:8fdf9a60065b 550 uint32_t filterValue)
kadonotakashi 0:8fdf9a60065b 551 {
kadonotakashi 0:8fdf9a60065b 552 uint32_t reg;
kadonotakashi 0:8fdf9a60065b 553
kadonotakashi 0:8fdf9a60065b 554 /* Clear the combine bit for the channel pair */
kadonotakashi 0:8fdf9a60065b 555 base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
kadonotakashi 0:8fdf9a60065b 556 /* Clear the dual edge capture mode because it's it's higher priority */
kadonotakashi 0:8fdf9a60065b 557 base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
kadonotakashi 0:8fdf9a60065b 558 /* Clear the quadrature decoder mode beacause it's higher priority */
kadonotakashi 0:8fdf9a60065b 559 base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
kadonotakashi 0:8fdf9a60065b 560
kadonotakashi 0:8fdf9a60065b 561 reg = base->CONTROLS[chnlNumber].CnSC;
kadonotakashi 0:8fdf9a60065b 562 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 563 reg |= captureMode;
kadonotakashi 0:8fdf9a60065b 564
kadonotakashi 0:8fdf9a60065b 565 /* Set the requested input capture mode */
kadonotakashi 0:8fdf9a60065b 566 base->CONTROLS[chnlNumber].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 567 /* Input filter available only for channels 0, 1, 2, 3 */
kadonotakashi 0:8fdf9a60065b 568 if (chnlNumber < kFTM_Chnl_4)
kadonotakashi 0:8fdf9a60065b 569 {
kadonotakashi 0:8fdf9a60065b 570 reg = base->FILTER;
kadonotakashi 0:8fdf9a60065b 571 reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber));
kadonotakashi 0:8fdf9a60065b 572 reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber));
kadonotakashi 0:8fdf9a60065b 573 base->FILTER = reg;
kadonotakashi 0:8fdf9a60065b 574 }
kadonotakashi 0:8fdf9a60065b 575 #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
kadonotakashi 0:8fdf9a60065b 576 /* Set to input mode */
kadonotakashi 0:8fdf9a60065b 577 FTM_SetPwmOutputEnable(base, chnlNumber, false);
kadonotakashi 0:8fdf9a60065b 578 #endif
kadonotakashi 0:8fdf9a60065b 579 }
kadonotakashi 0:8fdf9a60065b 580
kadonotakashi 0:8fdf9a60065b 581 void FTM_SetupOutputCompare(FTM_Type *base,
kadonotakashi 0:8fdf9a60065b 582 ftm_chnl_t chnlNumber,
kadonotakashi 0:8fdf9a60065b 583 ftm_output_compare_mode_t compareMode,
kadonotakashi 0:8fdf9a60065b 584 uint32_t compareValue)
kadonotakashi 0:8fdf9a60065b 585 {
kadonotakashi 0:8fdf9a60065b 586 uint32_t reg;
kadonotakashi 0:8fdf9a60065b 587
kadonotakashi 0:8fdf9a60065b 588 /* Clear the combine bit for the channel pair */
kadonotakashi 0:8fdf9a60065b 589 base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
kadonotakashi 0:8fdf9a60065b 590 /* Clear the dual edge capture mode because it's it's higher priority */
kadonotakashi 0:8fdf9a60065b 591 base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
kadonotakashi 0:8fdf9a60065b 592 /* Clear the quadrature decoder mode beacause it's higher priority */
kadonotakashi 0:8fdf9a60065b 593 base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
kadonotakashi 0:8fdf9a60065b 594
kadonotakashi 0:8fdf9a60065b 595 reg = base->CONTROLS[chnlNumber].CnSC;
kadonotakashi 0:8fdf9a60065b 596 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 597 reg |= compareMode;
kadonotakashi 0:8fdf9a60065b 598 /* Setup the channel output behaviour when a match occurs with the compare value */
kadonotakashi 0:8fdf9a60065b 599 base->CONTROLS[chnlNumber].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 600
kadonotakashi 0:8fdf9a60065b 601 /* Set output on match to the requested level */
kadonotakashi 0:8fdf9a60065b 602 base->CONTROLS[chnlNumber].CnV = compareValue;
kadonotakashi 0:8fdf9a60065b 603
kadonotakashi 0:8fdf9a60065b 604 #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
kadonotakashi 0:8fdf9a60065b 605 /* Set to output mode */
kadonotakashi 0:8fdf9a60065b 606 FTM_SetPwmOutputEnable(base, chnlNumber, true);
kadonotakashi 0:8fdf9a60065b 607 #endif
kadonotakashi 0:8fdf9a60065b 608 }
kadonotakashi 0:8fdf9a60065b 609
kadonotakashi 0:8fdf9a60065b 610 void FTM_SetupDualEdgeCapture(FTM_Type *base,
kadonotakashi 0:8fdf9a60065b 611 ftm_chnl_t chnlPairNumber,
kadonotakashi 0:8fdf9a60065b 612 const ftm_dual_edge_capture_param_t *edgeParam,
kadonotakashi 0:8fdf9a60065b 613 uint32_t filterValue)
kadonotakashi 0:8fdf9a60065b 614 {
kadonotakashi 0:8fdf9a60065b 615 assert(edgeParam);
kadonotakashi 0:8fdf9a60065b 616
kadonotakashi 0:8fdf9a60065b 617 uint32_t reg;
kadonotakashi 0:8fdf9a60065b 618
kadonotakashi 0:8fdf9a60065b 619 reg = base->COMBINE;
kadonotakashi 0:8fdf9a60065b 620 /* Clear the combine bit for the channel pair */
kadonotakashi 0:8fdf9a60065b 621 reg &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
kadonotakashi 0:8fdf9a60065b 622 /* Enable the DECAPEN bit */
kadonotakashi 0:8fdf9a60065b 623 reg |= (1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
kadonotakashi 0:8fdf9a60065b 624 reg |= (1U << (FTM_COMBINE_DECAP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
kadonotakashi 0:8fdf9a60065b 625 base->COMBINE = reg;
kadonotakashi 0:8fdf9a60065b 626
kadonotakashi 0:8fdf9a60065b 627 /* Setup the edge detection from channel n and n + 1 */
kadonotakashi 0:8fdf9a60065b 628 reg = base->CONTROLS[chnlPairNumber * 2].CnSC;
kadonotakashi 0:8fdf9a60065b 629 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 630 reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->currChanEdgeMode);
kadonotakashi 0:8fdf9a60065b 631 base->CONTROLS[chnlPairNumber * 2].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 632
kadonotakashi 0:8fdf9a60065b 633 reg = base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC;
kadonotakashi 0:8fdf9a60065b 634 reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
kadonotakashi 0:8fdf9a60065b 635 reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->nextChanEdgeMode);
kadonotakashi 0:8fdf9a60065b 636 base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC = reg;
kadonotakashi 0:8fdf9a60065b 637
kadonotakashi 0:8fdf9a60065b 638 /* Input filter available only for channels 0, 1, 2, 3 */
kadonotakashi 0:8fdf9a60065b 639 if (chnlPairNumber < kFTM_Chnl_4)
kadonotakashi 0:8fdf9a60065b 640 {
kadonotakashi 0:8fdf9a60065b 641 reg = base->FILTER;
kadonotakashi 0:8fdf9a60065b 642 reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
kadonotakashi 0:8fdf9a60065b 643 reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
kadonotakashi 0:8fdf9a60065b 644 base->FILTER = reg;
kadonotakashi 0:8fdf9a60065b 645 }
kadonotakashi 0:8fdf9a60065b 646
kadonotakashi 0:8fdf9a60065b 647 #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
kadonotakashi 0:8fdf9a60065b 648 /* Set to input mode */
kadonotakashi 0:8fdf9a60065b 649 FTM_SetPwmOutputEnable(base, chnlPairNumber, false);
kadonotakashi 0:8fdf9a60065b 650 #endif
kadonotakashi 0:8fdf9a60065b 651 }
kadonotakashi 0:8fdf9a60065b 652
kadonotakashi 0:8fdf9a60065b 653 void FTM_SetupQuadDecode(FTM_Type *base,
kadonotakashi 0:8fdf9a60065b 654 const ftm_phase_params_t *phaseAParams,
kadonotakashi 0:8fdf9a60065b 655 const ftm_phase_params_t *phaseBParams,
kadonotakashi 0:8fdf9a60065b 656 ftm_quad_decode_mode_t quadMode)
kadonotakashi 0:8fdf9a60065b 657 {
kadonotakashi 0:8fdf9a60065b 658 assert(phaseAParams);
kadonotakashi 0:8fdf9a60065b 659 assert(phaseBParams);
kadonotakashi 0:8fdf9a60065b 660
kadonotakashi 0:8fdf9a60065b 661 uint32_t reg;
kadonotakashi 0:8fdf9a60065b 662
kadonotakashi 0:8fdf9a60065b 663 /* Set Phase A filter value if phase filter is enabled */
kadonotakashi 0:8fdf9a60065b 664 if (phaseAParams->enablePhaseFilter)
kadonotakashi 0:8fdf9a60065b 665 {
kadonotakashi 0:8fdf9a60065b 666 reg = base->FILTER;
kadonotakashi 0:8fdf9a60065b 667 reg &= ~(FTM_FILTER_CH0FVAL_MASK);
kadonotakashi 0:8fdf9a60065b 668 reg |= FTM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal);
kadonotakashi 0:8fdf9a60065b 669 base->FILTER = reg;
kadonotakashi 0:8fdf9a60065b 670 }
kadonotakashi 0:8fdf9a60065b 671
kadonotakashi 0:8fdf9a60065b 672 /* Set Phase B filter value if phase filter is enabled */
kadonotakashi 0:8fdf9a60065b 673 if (phaseBParams->enablePhaseFilter)
kadonotakashi 0:8fdf9a60065b 674 {
kadonotakashi 0:8fdf9a60065b 675 reg = base->FILTER;
kadonotakashi 0:8fdf9a60065b 676 reg &= ~(FTM_FILTER_CH1FVAL_MASK);
kadonotakashi 0:8fdf9a60065b 677 reg |= FTM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal);
kadonotakashi 0:8fdf9a60065b 678 base->FILTER = reg;
kadonotakashi 0:8fdf9a60065b 679 }
kadonotakashi 0:8fdf9a60065b 680
kadonotakashi 0:8fdf9a60065b 681 /* Set Quadrature decode properties */
kadonotakashi 0:8fdf9a60065b 682 reg = base->QDCTRL;
kadonotakashi 0:8fdf9a60065b 683 reg &= ~(FTM_QDCTRL_QUADMODE_MASK | FTM_QDCTRL_PHAFLTREN_MASK | FTM_QDCTRL_PHBFLTREN_MASK | FTM_QDCTRL_PHAPOL_MASK |
kadonotakashi 0:8fdf9a60065b 684 FTM_QDCTRL_PHBPOL_MASK);
kadonotakashi 0:8fdf9a60065b 685 reg |= (FTM_QDCTRL_QUADMODE(quadMode) | FTM_QDCTRL_PHAFLTREN(phaseAParams->enablePhaseFilter) |
kadonotakashi 0:8fdf9a60065b 686 FTM_QDCTRL_PHBFLTREN(phaseBParams->enablePhaseFilter) | FTM_QDCTRL_PHAPOL(phaseAParams->phasePolarity) |
kadonotakashi 0:8fdf9a60065b 687 FTM_QDCTRL_PHBPOL(phaseBParams->phasePolarity));
kadonotakashi 0:8fdf9a60065b 688 base->QDCTRL = reg;
kadonotakashi 0:8fdf9a60065b 689 /* Enable Quad decode */
kadonotakashi 0:8fdf9a60065b 690 base->QDCTRL |= FTM_QDCTRL_QUADEN_MASK;
kadonotakashi 0:8fdf9a60065b 691 }
kadonotakashi 0:8fdf9a60065b 692
kadonotakashi 0:8fdf9a60065b 693 void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams)
kadonotakashi 0:8fdf9a60065b 694 {
kadonotakashi 0:8fdf9a60065b 695 assert(faultParams);
kadonotakashi 0:8fdf9a60065b 696
kadonotakashi 0:8fdf9a60065b 697 uint32_t reg;
kadonotakashi 0:8fdf9a60065b 698
kadonotakashi 0:8fdf9a60065b 699 reg = base->FLTCTRL;
kadonotakashi 0:8fdf9a60065b 700 if (faultParams->enableFaultInput)
kadonotakashi 0:8fdf9a60065b 701 {
kadonotakashi 0:8fdf9a60065b 702 /* Enable the fault input */
kadonotakashi 0:8fdf9a60065b 703 reg |= (FTM_FLTCTRL_FAULT0EN_MASK << faultNumber);
kadonotakashi 0:8fdf9a60065b 704 }
kadonotakashi 0:8fdf9a60065b 705 else
kadonotakashi 0:8fdf9a60065b 706 {
kadonotakashi 0:8fdf9a60065b 707 /* Disable the fault input */
kadonotakashi 0:8fdf9a60065b 708 reg &= ~(FTM_FLTCTRL_FAULT0EN_MASK << faultNumber);
kadonotakashi 0:8fdf9a60065b 709 }
kadonotakashi 0:8fdf9a60065b 710
kadonotakashi 0:8fdf9a60065b 711 if (faultParams->useFaultFilter)
kadonotakashi 0:8fdf9a60065b 712 {
kadonotakashi 0:8fdf9a60065b 713 /* Enable the fault filter */
kadonotakashi 0:8fdf9a60065b 714 reg |= (FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + faultNumber));
kadonotakashi 0:8fdf9a60065b 715 }
kadonotakashi 0:8fdf9a60065b 716 else
kadonotakashi 0:8fdf9a60065b 717 {
kadonotakashi 0:8fdf9a60065b 718 /* Disable the fault filter */
kadonotakashi 0:8fdf9a60065b 719 reg &= ~(FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + faultNumber));
kadonotakashi 0:8fdf9a60065b 720 }
kadonotakashi 0:8fdf9a60065b 721 base->FLTCTRL = reg;
kadonotakashi 0:8fdf9a60065b 722
kadonotakashi 0:8fdf9a60065b 723 if (faultParams->faultLevel)
kadonotakashi 0:8fdf9a60065b 724 {
kadonotakashi 0:8fdf9a60065b 725 /* Active low polarity for the fault input pin */
kadonotakashi 0:8fdf9a60065b 726 base->FLTPOL |= (1U << faultNumber);
kadonotakashi 0:8fdf9a60065b 727 }
kadonotakashi 0:8fdf9a60065b 728 else
kadonotakashi 0:8fdf9a60065b 729 {
kadonotakashi 0:8fdf9a60065b 730 /* Active high polarity for the fault input pin */
kadonotakashi 0:8fdf9a60065b 731 base->FLTPOL &= ~(1U << faultNumber);
kadonotakashi 0:8fdf9a60065b 732 }
kadonotakashi 0:8fdf9a60065b 733 }
kadonotakashi 0:8fdf9a60065b 734
kadonotakashi 0:8fdf9a60065b 735 void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 736 {
kadonotakashi 0:8fdf9a60065b 737 uint32_t chnlInts = (mask & 0xFFU);
kadonotakashi 0:8fdf9a60065b 738 uint8_t chnlNumber = 0;
kadonotakashi 0:8fdf9a60065b 739
kadonotakashi 0:8fdf9a60065b 740 /* Enable the timer overflow interrupt */
kadonotakashi 0:8fdf9a60065b 741 if (mask & kFTM_TimeOverflowInterruptEnable)
kadonotakashi 0:8fdf9a60065b 742 {
kadonotakashi 0:8fdf9a60065b 743 base->SC |= FTM_SC_TOIE_MASK;
kadonotakashi 0:8fdf9a60065b 744 }
kadonotakashi 0:8fdf9a60065b 745
kadonotakashi 0:8fdf9a60065b 746 /* Enable the fault interrupt */
kadonotakashi 0:8fdf9a60065b 747 if (mask & kFTM_FaultInterruptEnable)
kadonotakashi 0:8fdf9a60065b 748 {
kadonotakashi 0:8fdf9a60065b 749 base->MODE |= FTM_MODE_FAULTIE_MASK;
kadonotakashi 0:8fdf9a60065b 750 }
kadonotakashi 0:8fdf9a60065b 751
kadonotakashi 0:8fdf9a60065b 752 #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
kadonotakashi 0:8fdf9a60065b 753 /* Enable the reload interrupt available only on certain SoC's */
kadonotakashi 0:8fdf9a60065b 754 if (mask & kFTM_ReloadInterruptEnable)
kadonotakashi 0:8fdf9a60065b 755 {
kadonotakashi 0:8fdf9a60065b 756 base->SC |= FTM_SC_RIE_MASK;
kadonotakashi 0:8fdf9a60065b 757 }
kadonotakashi 0:8fdf9a60065b 758 #endif
kadonotakashi 0:8fdf9a60065b 759
kadonotakashi 0:8fdf9a60065b 760 /* Enable the channel interrupts */
kadonotakashi 0:8fdf9a60065b 761 while (chnlInts)
kadonotakashi 0:8fdf9a60065b 762 {
kadonotakashi 0:8fdf9a60065b 763 if (chnlInts & 0x1)
kadonotakashi 0:8fdf9a60065b 764 {
kadonotakashi 0:8fdf9a60065b 765 base->CONTROLS[chnlNumber].CnSC |= FTM_CnSC_CHIE_MASK;
kadonotakashi 0:8fdf9a60065b 766 }
kadonotakashi 0:8fdf9a60065b 767 chnlNumber++;
kadonotakashi 0:8fdf9a60065b 768 chnlInts = chnlInts >> 1U;
kadonotakashi 0:8fdf9a60065b 769 }
kadonotakashi 0:8fdf9a60065b 770 }
kadonotakashi 0:8fdf9a60065b 771
kadonotakashi 0:8fdf9a60065b 772 void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 773 {
kadonotakashi 0:8fdf9a60065b 774 uint32_t chnlInts = (mask & 0xFF);
kadonotakashi 0:8fdf9a60065b 775 uint8_t chnlNumber = 0;
kadonotakashi 0:8fdf9a60065b 776
kadonotakashi 0:8fdf9a60065b 777 /* Disable the timer overflow interrupt */
kadonotakashi 0:8fdf9a60065b 778 if (mask & kFTM_TimeOverflowInterruptEnable)
kadonotakashi 0:8fdf9a60065b 779 {
kadonotakashi 0:8fdf9a60065b 780 base->SC &= ~FTM_SC_TOIE_MASK;
kadonotakashi 0:8fdf9a60065b 781 }
kadonotakashi 0:8fdf9a60065b 782 /* Disable the fault interrupt */
kadonotakashi 0:8fdf9a60065b 783 if (mask & kFTM_FaultInterruptEnable)
kadonotakashi 0:8fdf9a60065b 784 {
kadonotakashi 0:8fdf9a60065b 785 base->MODE &= ~FTM_MODE_FAULTIE_MASK;
kadonotakashi 0:8fdf9a60065b 786 }
kadonotakashi 0:8fdf9a60065b 787
kadonotakashi 0:8fdf9a60065b 788 #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
kadonotakashi 0:8fdf9a60065b 789 /* Disable the reload interrupt available only on certain SoC's */
kadonotakashi 0:8fdf9a60065b 790 if (mask & kFTM_ReloadInterruptEnable)
kadonotakashi 0:8fdf9a60065b 791 {
kadonotakashi 0:8fdf9a60065b 792 base->SC &= ~FTM_SC_RIE_MASK;
kadonotakashi 0:8fdf9a60065b 793 }
kadonotakashi 0:8fdf9a60065b 794 #endif
kadonotakashi 0:8fdf9a60065b 795
kadonotakashi 0:8fdf9a60065b 796 /* Disable the channel interrupts */
kadonotakashi 0:8fdf9a60065b 797 while (chnlInts)
kadonotakashi 0:8fdf9a60065b 798 {
kadonotakashi 0:8fdf9a60065b 799 if (chnlInts & 0x1)
kadonotakashi 0:8fdf9a60065b 800 {
kadonotakashi 0:8fdf9a60065b 801 base->CONTROLS[chnlNumber].CnSC &= ~FTM_CnSC_CHIE_MASK;
kadonotakashi 0:8fdf9a60065b 802 }
kadonotakashi 0:8fdf9a60065b 803 chnlNumber++;
kadonotakashi 0:8fdf9a60065b 804 chnlInts = chnlInts >> 1U;
kadonotakashi 0:8fdf9a60065b 805 }
kadonotakashi 0:8fdf9a60065b 806 }
kadonotakashi 0:8fdf9a60065b 807
kadonotakashi 0:8fdf9a60065b 808 uint32_t FTM_GetEnabledInterrupts(FTM_Type *base)
kadonotakashi 0:8fdf9a60065b 809 {
kadonotakashi 0:8fdf9a60065b 810 uint32_t enabledInterrupts = 0;
kadonotakashi 0:8fdf9a60065b 811 int8_t chnlCount = FSL_FEATURE_FTM_CHANNEL_COUNTn(base);
kadonotakashi 0:8fdf9a60065b 812
kadonotakashi 0:8fdf9a60065b 813 /* The CHANNEL_COUNT macro returns -1 if it cannot match the FTM instance */
kadonotakashi 0:8fdf9a60065b 814 assert(chnlCount != -1);
kadonotakashi 0:8fdf9a60065b 815
kadonotakashi 0:8fdf9a60065b 816 /* Check if timer overflow interrupt is enabled */
kadonotakashi 0:8fdf9a60065b 817 if (base->SC & FTM_SC_TOIE_MASK)
kadonotakashi 0:8fdf9a60065b 818 {
kadonotakashi 0:8fdf9a60065b 819 enabledInterrupts |= kFTM_TimeOverflowInterruptEnable;
kadonotakashi 0:8fdf9a60065b 820 }
kadonotakashi 0:8fdf9a60065b 821 /* Check if fault interrupt is enabled */
kadonotakashi 0:8fdf9a60065b 822 if (base->MODE & FTM_MODE_FAULTIE_MASK)
kadonotakashi 0:8fdf9a60065b 823 {
kadonotakashi 0:8fdf9a60065b 824 enabledInterrupts |= kFTM_FaultInterruptEnable;
kadonotakashi 0:8fdf9a60065b 825 }
kadonotakashi 0:8fdf9a60065b 826
kadonotakashi 0:8fdf9a60065b 827 #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
kadonotakashi 0:8fdf9a60065b 828 /* Check if the reload interrupt is enabled */
kadonotakashi 0:8fdf9a60065b 829 if (base->SC & FTM_SC_RIE_MASK)
kadonotakashi 0:8fdf9a60065b 830 {
kadonotakashi 0:8fdf9a60065b 831 enabledInterrupts |= kFTM_ReloadInterruptEnable;
kadonotakashi 0:8fdf9a60065b 832 }
kadonotakashi 0:8fdf9a60065b 833 #endif
kadonotakashi 0:8fdf9a60065b 834
kadonotakashi 0:8fdf9a60065b 835 /* Check if the channel interrupts are enabled */
kadonotakashi 0:8fdf9a60065b 836 while (chnlCount > 0)
kadonotakashi 0:8fdf9a60065b 837 {
kadonotakashi 0:8fdf9a60065b 838 chnlCount--;
kadonotakashi 0:8fdf9a60065b 839 if (base->CONTROLS[chnlCount].CnSC & FTM_CnSC_CHIE_MASK)
kadonotakashi 0:8fdf9a60065b 840 {
kadonotakashi 0:8fdf9a60065b 841 enabledInterrupts |= (1U << chnlCount);
kadonotakashi 0:8fdf9a60065b 842 }
kadonotakashi 0:8fdf9a60065b 843 }
kadonotakashi 0:8fdf9a60065b 844
kadonotakashi 0:8fdf9a60065b 845 return enabledInterrupts;
kadonotakashi 0:8fdf9a60065b 846 }
kadonotakashi 0:8fdf9a60065b 847
kadonotakashi 0:8fdf9a60065b 848 uint32_t FTM_GetStatusFlags(FTM_Type *base)
kadonotakashi 0:8fdf9a60065b 849 {
kadonotakashi 0:8fdf9a60065b 850 uint32_t statusFlags = 0;
kadonotakashi 0:8fdf9a60065b 851
kadonotakashi 0:8fdf9a60065b 852 /* Check the timer flag */
kadonotakashi 0:8fdf9a60065b 853 if (base->SC & FTM_SC_TOF_MASK)
kadonotakashi 0:8fdf9a60065b 854 {
kadonotakashi 0:8fdf9a60065b 855 statusFlags |= kFTM_TimeOverflowFlag;
kadonotakashi 0:8fdf9a60065b 856 }
kadonotakashi 0:8fdf9a60065b 857 /* Check fault flag */
kadonotakashi 0:8fdf9a60065b 858 if (base->FMS & FTM_FMS_FAULTF_MASK)
kadonotakashi 0:8fdf9a60065b 859 {
kadonotakashi 0:8fdf9a60065b 860 statusFlags |= kFTM_FaultFlag;
kadonotakashi 0:8fdf9a60065b 861 }
kadonotakashi 0:8fdf9a60065b 862 /* Check channel trigger flag */
kadonotakashi 0:8fdf9a60065b 863 if (base->EXTTRIG & FTM_EXTTRIG_TRIGF_MASK)
kadonotakashi 0:8fdf9a60065b 864 {
kadonotakashi 0:8fdf9a60065b 865 statusFlags |= kFTM_ChnlTriggerFlag;
kadonotakashi 0:8fdf9a60065b 866 }
kadonotakashi 0:8fdf9a60065b 867 #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
kadonotakashi 0:8fdf9a60065b 868 /* Check reload flag */
kadonotakashi 0:8fdf9a60065b 869 if (base->SC & FTM_SC_RF_MASK)
kadonotakashi 0:8fdf9a60065b 870 {
kadonotakashi 0:8fdf9a60065b 871 statusFlags |= kFTM_ReloadFlag;
kadonotakashi 0:8fdf9a60065b 872 }
kadonotakashi 0:8fdf9a60065b 873 #endif
kadonotakashi 0:8fdf9a60065b 874
kadonotakashi 0:8fdf9a60065b 875 /* Lower 8 bits contain the channel status flags */
kadonotakashi 0:8fdf9a60065b 876 statusFlags |= (base->STATUS & 0xFFU);
kadonotakashi 0:8fdf9a60065b 877
kadonotakashi 0:8fdf9a60065b 878 return statusFlags;
kadonotakashi 0:8fdf9a60065b 879 }
kadonotakashi 0:8fdf9a60065b 880
kadonotakashi 0:8fdf9a60065b 881 void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 882 {
kadonotakashi 0:8fdf9a60065b 883 /* Clear the timer overflow flag by writing a 0 to the bit while it is set */
kadonotakashi 0:8fdf9a60065b 884 if (mask & kFTM_TimeOverflowFlag)
kadonotakashi 0:8fdf9a60065b 885 {
kadonotakashi 0:8fdf9a60065b 886 base->SC &= ~FTM_SC_TOF_MASK;
kadonotakashi 0:8fdf9a60065b 887 }
kadonotakashi 0:8fdf9a60065b 888 /* Clear fault flag by writing a 0 to the bit while it is set */
kadonotakashi 0:8fdf9a60065b 889 if (mask & kFTM_FaultFlag)
kadonotakashi 0:8fdf9a60065b 890 {
kadonotakashi 0:8fdf9a60065b 891 base->FMS &= ~FTM_FMS_FAULTF_MASK;
kadonotakashi 0:8fdf9a60065b 892 }
kadonotakashi 0:8fdf9a60065b 893 /* Clear channel trigger flag */
kadonotakashi 0:8fdf9a60065b 894 if (mask & kFTM_ChnlTriggerFlag)
kadonotakashi 0:8fdf9a60065b 895 {
kadonotakashi 0:8fdf9a60065b 896 base->EXTTRIG &= ~FTM_EXTTRIG_TRIGF_MASK;
kadonotakashi 0:8fdf9a60065b 897 }
kadonotakashi 0:8fdf9a60065b 898
kadonotakashi 0:8fdf9a60065b 899 #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
kadonotakashi 0:8fdf9a60065b 900 /* Check reload flag by writing a 0 to the bit while it is set */
kadonotakashi 0:8fdf9a60065b 901 if (mask & kFTM_ReloadFlag)
kadonotakashi 0:8fdf9a60065b 902 {
kadonotakashi 0:8fdf9a60065b 903 base->SC &= ~FTM_SC_RF_MASK;
kadonotakashi 0:8fdf9a60065b 904 }
kadonotakashi 0:8fdf9a60065b 905 #endif
kadonotakashi 0:8fdf9a60065b 906 /* Clear the channel status flags by writing a 0 to the bit */
kadonotakashi 0:8fdf9a60065b 907 base->STATUS &= ~(mask & 0xFFU);
kadonotakashi 0:8fdf9a60065b 908 }