http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f8f2ebbf/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.c
----------------------------------------------------------------------
diff --git 
a/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.c
 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.c
new file mode 100644
index 0000000..a905609
--- /dev/null
+++ 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.c
@@ -0,0 +1,876 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, 
this list
+ *   of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, 
this
+ *   list of conditions and the following disclaimer in the documentation 
and/or
+ *   other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fsl_ftm.h"
+
+/*******************************************************************************
+ * Prototypes
+ 
******************************************************************************/
+/*!
+ * @brief Gets the instance from the base address
+ *
+ * @param base FTM peripheral base address
+ *
+ * @return The FTM instance
+ */
+static uint32_t FTM_GetInstance(FTM_Type *base);
+
+/*!
+ * @brief Sets the FTM register PWM synchronization method
+ *
+ * This function will set the necessary bits for the PWM synchronization mode 
that
+ * user wishes to use.
+ *
+ * @param base       FTM peripheral base address
+ * @param syncMethod Syncronization methods to use to update buffered 
registers. This is a logical
+ *                   OR of members of the enumeration ::ftm_pwm_sync_method_t
+ */
+static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod);
+
+/*!
+ * @brief Sets the reload points used as loading points for register update
+ *
+ * This function will set the necessary bits based on what the user wishes to 
use as loading
+ * points for FTM register update. When using this it is not required to use 
PWM synchnronization.
+ *
+ * @param base         FTM peripheral base address
+ * @param reloadPoints FTM reload points. This is a logical OR of members of 
the
+ *                     enumeration ::ftm_reload_point_t
+ */
+static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints);
+
+/*******************************************************************************
+ * Variables
+ 
******************************************************************************/
+/*! @brief Pointers to FTM bases for each instance. */
+static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS;
+
+/*! @brief Pointers to FTM clocks for each instance. */
+static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS;
+
+/*******************************************************************************
+ * Code
+ 
******************************************************************************/
+static uint32_t FTM_GetInstance(FTM_Type *base)
+{
+    uint32_t instance;
+    uint32_t ftmArrayCount = (sizeof(s_ftmBases) / sizeof(s_ftmBases[0]));
+
+    /* Find the instance index from base address mappings. */
+    for (instance = 0; instance < ftmArrayCount; instance++)
+    {
+        if (s_ftmBases[instance] == base)
+        {
+            break;
+        }
+    }
+
+    assert(instance < ftmArrayCount);
+
+    return instance;
+}
+
+static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod)
+{
+    uint8_t chnlNumber = 0;
+    uint32_t reg = 0, syncReg = 0;
+
+    syncReg = base->SYNC;
+    /* Enable PWM synchronization of output mask register */
+    syncReg |= FTM_SYNC_SYNCHOM_MASK;
+
+    reg = base->COMBINE;
+    for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 
2); chnlNumber++)
+    {
+        /* Enable PWM synchronization of registers C(n)V and C(n+1)V */
+        reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT 
* chnlNumber)));
+    }
+    base->COMBINE = reg;
+
+    reg = base->SYNCONF;
+
+    /* Use enhanced PWM synchronization method. Use PWM sync to update 
register values */
+    reg |= (FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_CNTINC_MASK | 
FTM_SYNCONF_INVC_MASK | FTM_SYNCONF_SWOC_MASK);
+
+    if (syncMethod & FTM_SYNC_SWSYNC_MASK)
+    {
+        /* Enable needed bits for software trigger to update registers with 
its buffer value */
+        reg |= (FTM_SYNCONF_SWRSTCNT_MASK | FTM_SYNCONF_SWWRBUF_MASK | 
FTM_SYNCONF_SWINVC_MASK |
+                FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWOM_MASK);
+    }
+
+    if (syncMethod & (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | 
FTM_SYNC_TRIG2_MASK))
+    {
+        /* Enable needed bits for hardware trigger to update registers with 
its buffer value */
+        reg |= (FTM_SYNCONF_HWRSTCNT_MASK | FTM_SYNCONF_HWWRBUF_MASK | 
FTM_SYNCONF_HWINVC_MASK |
+                FTM_SYNCONF_HWSOC_MASK | FTM_SYNCONF_HWOM_MASK);
+
+        /* Enable the appropriate hardware trigger that is used for PWM sync */
+        if (syncMethod & FTM_SYNC_TRIG0_MASK)
+        {
+            syncReg |= FTM_SYNC_TRIG0_MASK;
+        }
+        if (syncMethod & FTM_SYNC_TRIG1_MASK)
+        {
+            syncReg |= FTM_SYNC_TRIG1_MASK;
+        }
+        if (syncMethod & FTM_SYNC_TRIG2_MASK)
+        {
+            syncReg |= FTM_SYNC_TRIG2_MASK;
+        }
+    }
+
+    /* Write back values to the SYNC register */
+    base->SYNC = syncReg;
+
+    /* Write the PWM synch values to the SYNCONF register */
+    base->SYNCONF = reg;
+}
+
+static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints)
+{
+    uint32_t chnlNumber = 0;
+    uint32_t reg = 0;
+
+    /* Need CNTINC bit to be 1 for CNTIN register to update with its buffer 
value on reload  */
+    base->SYNCONF |= FTM_SYNCONF_CNTINC_MASK;
+
+    reg = base->COMBINE;
+    for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 
2); chnlNumber++)
+    {
+        /* Need SYNCEN bit to be 1 for CnV reg to update with its buffer value 
on reload  */
+        reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT 
* chnlNumber)));
+    }
+    base->COMBINE = reg;
+
+    /* Set the reload points */
+    reg = base->PWMLOAD;
+
+    /* Enable the selected channel match reload points */
+    reg &= ~((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1);
+    reg |= (reloadPoints & ((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1));
+
+#if defined(FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD) && 
(FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD)
+    /* Enable half cycle match as a reload point */
+    if (reloadPoints & kFTM_HalfCycMatch)
+    {
+        reg |= FTM_PWMLOAD_HCSEL_MASK;
+    }
+    else
+    {
+        reg &= ~FTM_PWMLOAD_HCSEL_MASK;
+    }
+#endif /* FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD */
+
+    base->PWMLOAD = reg;
+
+    /* These reload points are used when counter is in up-down counting mode */
+    reg = base->SYNC;
+    if (reloadPoints & kFTM_CntMax)
+    {
+        /* Reload when counter turns from up to down */
+        reg |= FTM_SYNC_CNTMAX_MASK;
+    }
+    else
+    {
+        reg &= ~FTM_SYNC_CNTMAX_MASK;
+    }
+
+    if (reloadPoints & kFTM_CntMin)
+    {
+        /* Reload when counter turns from down to up */
+        reg |= FTM_SYNC_CNTMIN_MASK;
+    }
+    else
+    {
+        reg &= ~FTM_SYNC_CNTMIN_MASK;
+    }
+    base->SYNC = reg;
+}
+
+status_t FTM_Init(FTM_Type *base, const ftm_config_t *config)
+{
+    assert(config);
+
+    uint32_t reg;
+
+    if (!(config->pwmSyncMode &
+          (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK | 
FTM_SYNC_SWSYNC_MASK)))
+    {
+        /* Invalid PWM sync mode */
+        return kStatus_Fail;
+    }
+
+    /* Ungate the FTM clock*/
+    CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]);
+
+    /* Configure the fault mode, enable FTM mode and disable write protection 
*/
+    base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | 
FTM_MODE_WPDIS_MASK;
+
+    /* Configure the update mechanism for buffered registers */
+    FTM_SetPwmSync(base, config->pwmSyncMode);
+
+    if (config->reloadPoints)
+    {
+        /* Setup intermediate register reload points */
+        FTM_SetReloadPoints(base, config->reloadPoints);
+    }
+
+    /* Set the clock prescale factor */
+    base->SC = FTM_SC_PS(config->prescale);
+
+    /* Setup the counter operation */
+    base->CONF = (FTM_CONF_BDMMODE(config->bdmMode) | 
FTM_CONF_GTBEEN(config->useGlobalTimeBase));
+
+    /* Initial state of channel output */
+    base->OUTINIT = config->chnlInitState;
+
+    /* Channel polarity */
+    base->POL = config->chnlPolarity;
+
+    /* Set the external trigger sources */
+    base->EXTTRIG = config->extTriggers;
+#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) && 
(FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER)
+    if (config->extTriggers & kFTM_ReloadInitTrigger)
+    {
+        base->CONF |= FTM_CONF_ITRIGR_MASK;
+    }
+    else
+    {
+        base->CONF &= ~FTM_CONF_ITRIGR_MASK;
+    }
+#endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */
+
+    /* FTM deadtime insertion control */
+    base->DEADTIME = (FTM_DEADTIME_DTPS(config->deadTimePrescale) | 
FTM_DEADTIME_DTVAL(config->deadTimeValue));
+
+    /* FTM fault filter value */
+    reg = base->FLTCTRL;
+    reg &= ~FTM_FLTCTRL_FFVAL_MASK;
+    reg |= FTM_FLTCTRL_FFVAL(config->faultFilterValue);
+    base->FLTCTRL = reg;
+
+    return kStatus_Success;
+}
+
+void FTM_Deinit(FTM_Type *base)
+{
+    /* Set clock source to none to disable counter */
+    base->SC &= ~(FTM_SC_CLKS_MASK);
+
+    /* Gate the FTM clock */
+    CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]);
+}
+
+void FTM_GetDefaultConfig(ftm_config_t *config)
+{
+    assert(config);
+
+    /* Divide FTM clock by 1 */
+    config->prescale = kFTM_Prescale_Divide_1;
+    /* FTM behavior in BDM mode */
+    config->bdmMode = kFTM_BdmMode_0;
+    /* Software trigger will be used to update registers */
+    config->pwmSyncMode = kFTM_SoftwareTrigger;
+    /* No intermediate register load */
+    config->reloadPoints = 0;
+    /* Fault control disabled for all channels */
+    config->faultMode = kFTM_Fault_Disable;
+    /* Disable the fault filter */
+    config->faultFilterValue = 0;
+    /* Divide the system clock by 1 */
+    config->deadTimePrescale = kFTM_Deadtime_Prescale_1;
+    /* No counts are inserted */
+    config->deadTimeValue = 0;
+    /* No external trigger */
+    config->extTriggers = 0;
+    /* Initialization value is 0 for all channels */
+    config->chnlInitState = 0;
+    /* Active high polarity for all channels */
+    config->chnlPolarity = 0;
+    /* Use internal FTM counter as timebase */
+    config->useGlobalTimeBase = false;
+}
+
+status_t FTM_SetupPwm(FTM_Type *base,
+                      const ftm_chnl_pwm_signal_param_t *chnlParams,
+                      uint8_t numOfChnls,
+                      ftm_pwm_mode_t mode,
+                      uint32_t pwmFreq_Hz,
+                      uint32_t srcClock_Hz)
+{
+    assert(chnlParams);
+
+    uint32_t mod, reg;
+    uint32_t ftmClock = (srcClock_Hz / (1U << (base->SC & FTM_SC_PS_MASK)));
+    uint16_t cnv, cnvFirstEdge;
+    uint8_t i;
+
+    switch (mode)
+    {
+        case kFTM_EdgeAlignedPwm:
+        case kFTM_CombinedPwm:
+            base->SC &= ~FTM_SC_CPWMS_MASK;
+            mod = (ftmClock / pwmFreq_Hz) - 1;
+            break;
+        case kFTM_CenterAlignedPwm:
+            base->SC |= FTM_SC_CPWMS_MASK;
+            mod = ftmClock / (pwmFreq_Hz * 2);
+            break;
+        default:
+            return kStatus_Fail;
+    }
+
+    /* Return an error in case we overflow the registers, probably would 
require changing
+     * clock source to get the desired frequency */
+    if (mod > 65535U)
+    {
+        return kStatus_Fail;
+    }
+    /* Set the PWM period */
+    base->MOD = mod;
+
+    /* Setup each FTM channel */
+    for (i = 0; i < numOfChnls; i++)
+    {
+        /* Return error if requested dutycycle is greater than the max allowed 
*/
+        if (chnlParams->dutyCyclePercent > 100)
+        {
+            return kStatus_Fail;
+        }
+
+        if ((mode == kFTM_EdgeAlignedPwm) || (mode == kFTM_CenterAlignedPwm))
+        {
+            /* Clear the current mode and edge level bits */
+            reg = base->CONTROLS[chnlParams->chnlNumber].CnSC;
+            reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | 
FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
+
+            /* Setup the active level */
+            reg |= (FTM_CnSC_ELSA(chnlParams->level) | 
FTM_CnSC_ELSB(chnlParams->level));
+
+            /* Edge-aligned mode needs MSB to be 1, don't care for 
Center-aligned mode */
+            reg |= FTM_CnSC_MSB(1U);
+
+            /* Update the mode and edge level */
+            base->CONTROLS[chnlParams->chnlNumber].CnSC = reg;
+
+            if (chnlParams->dutyCyclePercent == 0)
+            {
+                /* Signal stays low */
+                cnv = 0;
+            }
+            else
+            {
+                cnv = (mod * chnlParams->dutyCyclePercent) / 100;
+                /* For 100% duty cycle */
+                if (cnv >= mod)
+                {
+                    cnv = mod + 1;
+                }
+            }
+
+            base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
+        }
+        else
+        {
+            /* This check is added for combined mode as the channel number 
should be the pair number */
+            if (chnlParams->chnlNumber >= 
(FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2))
+            {
+                return kStatus_Fail;
+            }
+
+            /* Return error if requested value is greater than the max allowed 
*/
+            if (chnlParams->firstEdgeDelayPercent > 100)
+            {
+                return kStatus_Fail;
+            }
+
+            /* Configure delay of the first edge */
+            if (chnlParams->firstEdgeDelayPercent == 0)
+            {
+                /* No delay for the first edge */
+                cnvFirstEdge = 0;
+            }
+            else
+            {
+                cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100;
+            }
+
+            /* Configure dutycycle */
+            if (chnlParams->dutyCyclePercent == 0)
+            {
+                /* Signal stays low */
+                cnv = 0;
+                cnvFirstEdge = 0;
+            }
+            else
+            {
+                cnv = (mod * chnlParams->dutyCyclePercent) / 100;
+                /* For 100% duty cycle */
+                if (cnv >= mod)
+                {
+                    cnv = mod + 1;
+                }
+            }
+
+            /* Clear the current mode and edge level bits for channel n */
+            reg = base->CONTROLS[chnlParams->chnlNumber * 2].CnSC;
+            reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | 
FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
+
+            /* Setup the active level for channel n */
+            reg |= (FTM_CnSC_ELSA(chnlParams->level) | 
FTM_CnSC_ELSB(chnlParams->level));
+
+            /* Update the mode and edge level for channel n */
+            base->CONTROLS[chnlParams->chnlNumber * 2].CnSC = reg;
+
+            /* Clear the current mode and edge level bits for channel n + 1 */
+            reg = base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC;
+            reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | 
FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
+
+            /* Setup the active level for channel n + 1 */
+            reg |= (FTM_CnSC_ELSA(chnlParams->level) | 
FTM_CnSC_ELSB(chnlParams->level));
+
+            /* Update the mode and edge level for channel n + 1*/
+            base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC = reg;
+
+            /* Set the channel pair values */
+            base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge;
+            base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = 
cnvFirstEdge + cnv;
+
+            /* Set the combine bit for the channel pair */
+            base->COMBINE |=
+                (1U << (FTM_COMBINE_COMBINE0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlParams->chnlNumber)));
+        }
+
+#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && 
(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
+        /* Set to output mode */
+        FTM_SetPwmOutputEnable(base, chnlParams->chnlNumber, true);
+#endif
+
+        chnlParams++;
+    }
+
+    return kStatus_Success;
+}
+
+void FTM_UpdatePwmDutycycle(FTM_Type *base,
+                            ftm_chnl_t chnlNumber,
+                            ftm_pwm_mode_t currentPwmMode,
+                            uint8_t dutyCyclePercent)
+{
+    uint16_t cnv, cnvFirstEdge = 0, mod;
+
+    mod = base->MOD;
+    if ((currentPwmMode == kFTM_EdgeAlignedPwm) || (currentPwmMode == 
kFTM_CenterAlignedPwm))
+    {
+        cnv = (mod * dutyCyclePercent) / 100;
+        /* For 100% duty cycle */
+        if (cnv >= mod)
+        {
+            cnv = mod + 1;
+        }
+        base->CONTROLS[chnlNumber].CnV = cnv;
+    }
+    else
+    {
+        /* This check is added for combined mode as the channel number should 
be the pair number */
+        if (chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2))
+        {
+            return;
+        }
+
+        cnv = (mod * dutyCyclePercent) / 100;
+        cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV;
+        /* For 100% duty cycle */
+        if (cnv >= mod)
+        {
+            cnv = mod + 1;
+        }
+        base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
+    }
+}
+
+void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, 
uint8_t level)
+{
+    uint32_t reg = base->CONTROLS[chnlNumber].CnSC;
+
+    /* Clear the field and write the new level value */
+    reg &= ~(FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
+    reg |= ((uint32_t)level << FTM_CnSC_ELSA_SHIFT) & (FTM_CnSC_ELSA_MASK | 
FTM_CnSC_ELSB_MASK);
+
+    base->CONTROLS[chnlNumber].CnSC = reg;
+}
+
+void FTM_SetupInputCapture(FTM_Type *base,
+                           ftm_chnl_t chnlNumber,
+                           ftm_input_capture_edge_t captureMode,
+                           uint32_t filterValue)
+{
+    uint32_t reg;
+
+    reg = base->CONTROLS[chnlNumber].CnSC;
+    reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | 
FTM_CnSC_ELSB_MASK);
+    reg |= captureMode;
+
+    /* Set the requested input capture mode */
+    base->CONTROLS[chnlNumber].CnSC = reg;
+    /* Input filter available only for channels 0, 1, 2, 3 */
+    if (chnlNumber < kFTM_Chnl_4)
+    {
+        reg = base->FILTER;
+        reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * 
chnlNumber));
+        reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber));
+        base->FILTER = reg;
+    }
+#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && 
(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
+    /* Set to input mode */
+    FTM_SetPwmOutputEnable(base, chnlNumber, false);
+#endif
+}
+
+void FTM_SetupOutputCompare(FTM_Type *base,
+                            ftm_chnl_t chnlNumber,
+                            ftm_output_compare_mode_t compareMode,
+                            uint32_t compareValue)
+{
+    uint32_t reg;
+
+    /* Set output on match to the requested level */
+    base->CONTROLS[chnlNumber].CnV = compareValue;
+
+    reg = base->CONTROLS[chnlNumber].CnSC;
+    reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | 
FTM_CnSC_ELSB_MASK);
+    reg |= compareMode;
+    /* Setup the channel output behaviour when a match occurs with the compare 
value */
+    base->CONTROLS[chnlNumber].CnSC = reg;
+
+#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && 
(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
+    /* Set to output mode */
+    FTM_SetPwmOutputEnable(base, chnlNumber, true);
+#endif
+}
+
+void FTM_SetupDualEdgeCapture(FTM_Type *base,
+                              ftm_chnl_t chnlPairNumber,
+                              const ftm_dual_edge_capture_param_t *edgeParam,
+                              uint32_t filterValue)
+{
+    assert(edgeParam);
+
+    uint32_t reg;
+
+    reg = base->COMBINE;
+    /* Clear the combine bit for the channel pair */
+    reg &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * 
chnlPairNumber)));
+    /* Enable the DECAPEN bit */
+    reg |= (1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * 
chnlPairNumber)));
+    reg |= (1U << (FTM_COMBINE_DECAP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * 
chnlPairNumber)));
+    base->COMBINE = reg;
+
+    /* Setup the edge detection from channel n and n + 1 */
+    reg = base->CONTROLS[chnlPairNumber * 2].CnSC;
+    reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | 
FTM_CnSC_ELSB_MASK);
+    reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->currChanEdgeMode);
+    base->CONTROLS[chnlPairNumber * 2].CnSC = reg;
+
+    reg = base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC;
+    reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | 
FTM_CnSC_ELSB_MASK);
+    reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->nextChanEdgeMode);
+    base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC = reg;
+
+    /* Input filter available only for channels 0, 1, 2, 3 */
+    if (chnlPairNumber < kFTM_Chnl_4)
+    {
+        reg = base->FILTER;
+        reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * 
chnlPairNumber));
+        reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
+        base->FILTER = reg;
+    }
+
+#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && 
(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
+    /* Set to input mode */
+    FTM_SetPwmOutputEnable(base, chnlPairNumber, false);
+#endif
+}
+
+void FTM_SetupQuadDecode(FTM_Type *base,
+                         const ftm_phase_params_t *phaseAParams,
+                         const ftm_phase_params_t *phaseBParams,
+                         ftm_quad_decode_mode_t quadMode)
+{
+    assert(phaseAParams);
+    assert(phaseBParams);
+
+    uint32_t reg;
+
+    /* Set Phase A filter value if phase filter is enabled */
+    if (phaseAParams->enablePhaseFilter)
+    {
+        reg = base->FILTER;
+        reg &= ~(FTM_FILTER_CH0FVAL_MASK);
+        reg |= FTM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal);
+        base->FILTER = reg;
+    }
+
+    /* Set Phase B filter value if phase filter is enabled */
+    if (phaseBParams->enablePhaseFilter)
+    {
+        reg = base->FILTER;
+        reg &= ~(FTM_FILTER_CH1FVAL_MASK);
+        reg |= FTM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal);
+        base->FILTER = reg;
+    }
+
+    /* Set Quadrature decode properties */
+    reg = base->QDCTRL;
+    reg &= ~(FTM_QDCTRL_QUADMODE_MASK | FTM_QDCTRL_PHAFLTREN_MASK | 
FTM_QDCTRL_PHBFLTREN_MASK | FTM_QDCTRL_PHAPOL_MASK |
+             FTM_QDCTRL_PHBPOL_MASK);
+    reg |= (FTM_QDCTRL_QUADMODE(quadMode) | 
FTM_QDCTRL_PHAFLTREN(phaseAParams->enablePhaseFilter) |
+            FTM_QDCTRL_PHBFLTREN(phaseBParams->enablePhaseFilter) | 
FTM_QDCTRL_PHAPOL(phaseAParams->phasePolarity) |
+            FTM_QDCTRL_PHBPOL(phaseBParams->phasePolarity));
+    base->QDCTRL = reg;
+    /* Enable Quad decode */
+    base->QDCTRL |= FTM_QDCTRL_QUADEN_MASK;
+}
+
+void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const 
ftm_fault_param_t *faultParams)
+{
+    uint32_t reg;
+
+    reg = base->FLTCTRL;
+    if (faultParams->enableFaultInput)
+    {
+        /* Enable the fault input */
+        reg |= (FTM_FLTCTRL_FAULT0EN_MASK << faultNumber);
+    }
+    else
+    {
+        /* Disable the fault input */
+        reg &= ~(FTM_FLTCTRL_FAULT0EN_MASK << faultNumber);
+    }
+
+    if (faultParams->useFaultFilter)
+    {
+        /* Enable the fault filter */
+        reg |= (FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + 
faultNumber));
+    }
+    else
+    {
+        /* Disable the fault filter */
+        reg &= ~(FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + 
faultNumber));
+    }
+    base->FLTCTRL = reg;
+
+    if (faultParams->faultLevel)
+    {
+        /* Active low polarity for the fault input pin */
+        base->FLTPOL |= (1U << faultNumber);
+    }
+    else
+    {
+        /* Active high polarity for the fault input pin */
+        base->FLTPOL &= ~(1U << faultNumber);
+    }
+}
+
+void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask)
+{
+    uint32_t chnlInts = (mask & 0xFFU);
+    uint8_t chnlNumber = 0;
+
+    /* Enable the timer overflow interrupt */
+    if (mask & kFTM_TimeOverflowInterruptEnable)
+    {
+        base->SC |= FTM_SC_TOIE_MASK;
+    }
+
+    /* Enable the fault interrupt */
+    if (mask & kFTM_FaultInterruptEnable)
+    {
+        base->MODE |= FTM_MODE_FAULTIE_MASK;
+    }
+
+#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && 
(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
+    /* Enable the reload interrupt available only on certain SoC's */
+    if (mask & kFTM_ReloadInterruptEnable)
+    {
+        base->SC |= FTM_SC_RIE_MASK;
+    }
+#endif
+
+    /* Enable the channel interrupts */
+    while (chnlInts)
+    {
+        if (chnlInts & 0x1)
+        {
+            base->CONTROLS[chnlNumber].CnSC |= FTM_CnSC_CHIE_MASK;
+        }
+        chnlNumber++;
+        chnlInts = chnlInts >> 1U;
+    }
+}
+
+void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask)
+{
+    uint32_t chnlInts = (mask & 0xFF);
+    uint8_t chnlNumber = 0;
+
+    /* Disable the timer overflow interrupt */
+    if (mask & kFTM_TimeOverflowInterruptEnable)
+    {
+        base->SC &= ~FTM_SC_TOIE_MASK;
+    }
+    /* Disable the fault interrupt */
+    if (mask & kFTM_FaultInterruptEnable)
+    {
+        base->MODE &= ~FTM_MODE_FAULTIE_MASK;
+    }
+
+#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && 
(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
+    /* Disable the reload interrupt available only on certain SoC's */
+    if (mask & kFTM_ReloadInterruptEnable)
+    {
+        base->SC &= ~FTM_SC_RIE_MASK;
+    }
+#endif
+
+    /* Disable the channel interrupts */
+    while (chnlInts)
+    {
+        if (chnlInts & 0x1)
+        {
+            base->CONTROLS[chnlNumber].CnSC &= ~FTM_CnSC_CHIE_MASK;
+        }
+        chnlNumber++;
+        chnlInts = chnlInts >> 1U;
+    }
+}
+
+uint32_t FTM_GetEnabledInterrupts(FTM_Type *base)
+{
+    uint32_t enabledInterrupts = 0;
+    int8_t chnlCount = FSL_FEATURE_FTM_CHANNEL_COUNTn(base);
+
+    /* The CHANNEL_COUNT macro returns -1 if it cannot match the FTM instance 
*/
+    assert(chnlCount != -1);
+
+    /* Check if timer overflow interrupt is enabled */
+    if (base->SC & FTM_SC_TOIE_MASK)
+    {
+        enabledInterrupts |= kFTM_TimeOverflowInterruptEnable;
+    }
+    /* Check if fault interrupt is enabled */
+    if (base->MODE & FTM_MODE_FAULTIE_MASK)
+    {
+        enabledInterrupts |= kFTM_FaultInterruptEnable;
+    }
+
+#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && 
(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
+    /* Check if the reload interrupt is enabled */
+    if (base->SC & FTM_SC_RIE_MASK)
+    {
+        enabledInterrupts |= kFTM_ReloadInterruptEnable;
+    }
+#endif
+
+    /* Check if the channel interrupts are enabled */
+    while (chnlCount > 0)
+    {
+        chnlCount--;
+        if (base->CONTROLS[chnlCount].CnSC & FTM_CnSC_CHIE_MASK)
+        {
+            enabledInterrupts |= (1U << chnlCount);
+        }
+    }
+
+    return enabledInterrupts;
+}
+
+uint32_t FTM_GetStatusFlags(FTM_Type *base)
+{
+    uint32_t statusFlags = 0;
+
+    /* Check the timer flag */
+    if (base->SC & FTM_SC_TOF_MASK)
+    {
+        statusFlags |= kFTM_TimeOverflowFlag;
+    }
+    /* Check fault flag */
+    if (base->FMS & FTM_FMS_FAULTF_MASK)
+    {
+        statusFlags |= kFTM_FaultFlag;
+    }
+    /* Check channel trigger flag */
+    if (base->EXTTRIG & FTM_EXTTRIG_TRIGF_MASK)
+    {
+        statusFlags |= kFTM_ChnlTriggerFlag;
+    }
+#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && 
(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
+    /* Check reload flag */
+    if (base->SC & FTM_SC_RF_MASK)
+    {
+        statusFlags |= kFTM_ReloadFlag;
+    }
+#endif
+
+    /* Lower 8 bits contain the channel status flags */
+    statusFlags |= (base->STATUS & 0xFFU);
+
+    return statusFlags;
+}
+
+void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask)
+{
+    /* Clear the timer overflow flag by writing a 0 to the bit while it is set 
*/
+    if (mask & kFTM_TimeOverflowFlag)
+    {
+        base->SC &= ~FTM_SC_TOF_MASK;
+    }
+    /* Clear fault flag by writing a 0 to the bit while it is set */
+    if (mask & kFTM_FaultFlag)
+    {
+        base->FMS &= ~FTM_FMS_FAULTF_MASK;
+    }
+    /* Clear channel trigger flag */
+    if (mask & kFTM_ChnlTriggerFlag)
+    {
+        base->EXTTRIG &= ~FTM_EXTTRIG_TRIGF_MASK;
+    }
+
+#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && 
(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
+    /* Check reload flag by writing a 0 to the bit while it is set */
+    if (mask & kFTM_ReloadFlag)
+    {
+        base->SC &= ~FTM_SC_RF_MASK;
+    }
+#endif
+    /* Clear the channel status flags by writing a 0 to the bit */
+    base->STATUS &= ~(mask & 0xFFU);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f8f2ebbf/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.h
----------------------------------------------------------------------
diff --git 
a/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.h
 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.h
new file mode 100644
index 0000000..eb1ebf7
--- /dev/null
+++ 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_ftm.h
@@ -0,0 +1,862 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, 
this list
+ *   of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, 
this
+ *   list of conditions and the following disclaimer in the documentation 
and/or
+ *   other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _FSL_FTM_H_
+#define _FSL_FTM_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup ftm_driver
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ 
******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+#define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
+/*@}*/
+
+/*!
+ * @brief List of FTM channels
+ * @note Actual number of available channels is SoC dependent
+ */
+typedef enum _ftm_chnl
+{
+    kFTM_Chnl_0 = 0U, /*!< FTM channel number 0*/
+    kFTM_Chnl_1,      /*!< FTM channel number 1 */
+    kFTM_Chnl_2,      /*!< FTM channel number 2 */
+    kFTM_Chnl_3,      /*!< FTM channel number 3 */
+    kFTM_Chnl_4,      /*!< FTM channel number 4 */
+    kFTM_Chnl_5,      /*!< FTM channel number 5 */
+    kFTM_Chnl_6,      /*!< FTM channel number 6 */
+    kFTM_Chnl_7       /*!< FTM channel number 7 */
+} ftm_chnl_t;
+
+/*! @brief List of FTM faults */
+typedef enum _ftm_fault_input
+{
+    kFTM_Fault_0 = 0U, /*!< FTM fault 0 input pin */
+    kFTM_Fault_1,      /*!< FTM fault 1 input pin */
+    kFTM_Fault_2,      /*!< FTM fault 2 input pin */
+    kFTM_Fault_3       /*!< FTM fault 3 input pin */
+} ftm_fault_input_t;
+
+/*! @brief FTM PWM operation modes */
+typedef enum _ftm_pwm_mode
+{
+    kFTM_EdgeAlignedPwm = 0U, /*!< Edge-aligned PWM */
+    kFTM_CenterAlignedPwm,    /*!< Center-aligned PWM */
+    kFTM_CombinedPwm          /*!< Combined PWM */
+} ftm_pwm_mode_t;
+
+/*! @brief FTM PWM output pulse mode: high-true, low-true or no output */
+typedef enum _ftm_pwm_level_select
+{
+    kFTM_NoPwmSignal = 0U, /*!< No PWM output on pin */
+    kFTM_LowTrue,          /*!< Low true pulses */
+    kFTM_HighTrue          /*!< High true pulses */
+} ftm_pwm_level_select_t;
+
+/*! @brief Options to configure a FTM channel's PWM signal */
+typedef struct _ftm_chnl_pwm_signal_param
+{
+    ftm_chnl_t chnlNumber;         /*!< The channel/channel pair number.
+                                        In combined mode, this represents the 
channel pair number. */
+    ftm_pwm_level_select_t level;  /*!< PWM output active level select. */
+    uint8_t dutyCyclePercent;      /*!< PWM pulse width, value should be 
between 0 to 100
+                                        0 = inactive signal(0% duty cycle)...
+                                        100 = always active signal (100% duty 
cycle).*/
+    uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to 
generate an asymmetrical PWM.
+                                        Specifies the delay to the first edge 
in a PWM period.
+                                        If unsure leave as 0; Should be 
specified as a
+                                        percentage of the PWM period */
+} ftm_chnl_pwm_signal_param_t;
+
+/*! @brief FlexTimer output compare mode */
+typedef enum _ftm_output_compare_mode
+{
+    kFTM_NoOutputSignal = (1U << FTM_CnSC_MSA_SHIFT), /*!< No channel output 
when counter reaches CnV  */
+    kFTM_ToggleOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (1U << 
FTM_CnSC_ELSA_SHIFT)), /*!< Toggle output */
+    kFTM_ClearOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (2U << 
FTM_CnSC_ELSA_SHIFT)),  /*!< Clear output */
+    kFTM_SetOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (3U << 
FTM_CnSC_ELSA_SHIFT))     /*!< Set output */
+} ftm_output_compare_mode_t;
+
+/*! @brief FlexTimer input capture edge */
+typedef enum _ftm_input_capture_edge
+{
+    kFTM_RisingEdge = (1U << FTM_CnSC_ELSA_SHIFT),     /*!< Capture on rising 
edge only*/
+    kFTM_FallingEdge = (2U << FTM_CnSC_ELSA_SHIFT),    /*!< Capture on falling 
edge only*/
+    kFTM_RiseAndFallEdge = (3U << FTM_CnSC_ELSA_SHIFT) /*!< Capture on rising 
or falling edge */
+} ftm_input_capture_edge_t;
+
+/*! @brief FlexTimer dual edge capture modes */
+typedef enum _ftm_dual_edge_capture_mode
+{
+    kFTM_OneShot = 0U,                           /*!< One-shot capture mode */
+    kFTM_Continuous = (1U << FTM_CnSC_MSA_SHIFT) /*!< Continuous capture mode 
*/
+} ftm_dual_edge_capture_mode_t;
+
+/*! @brief FlexTimer dual edge capture parameters */
+typedef struct _ftm_dual_edge_capture_param
+{
+    ftm_dual_edge_capture_mode_t mode;         /*!< Dual Edge Capture mode */
+    ftm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select 
for channel n */
+    ftm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select 
for channel n+1 */
+} ftm_dual_edge_capture_param_t;
+
+/*! @brief FlexTimer quadrature decode modes */
+typedef enum _ftm_quad_decode_mode
+{
+    kFTM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */
+    kFTM_QuadCountAndDir       /*!< Count and direction encoding mode */
+} ftm_quad_decode_mode_t;
+
+/*! @brief FlexTimer quadrature phase polarities */
+typedef enum _ftm_phase_polarity
+{
+    kFTM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */
+    kFTM_QuadPhaseInvert       /*!< Phase input signal is inverted */
+} ftm_phase_polarity_t;
+
+/*! @brief FlexTimer quadrature decode phase parameters */
+typedef struct _ftm_phase_param
+{
+    bool enablePhaseFilter;             /*!< True: enable phase filter; false: 
disable filter */
+    uint32_t phaseFilterVal;            /*!< Filter value, used only if phase 
filter is enabled */
+    ftm_phase_polarity_t phasePolarity; /*!< Phase polarity */
+} ftm_phase_params_t;
+
+/*! @brief Structure is used to hold the parameters to configure a FTM fault */
+typedef struct _ftm_fault_param
+{
+    bool enableFaultInput; /*!< True: Fault input is enabled; false: Fault 
input is disabled */
+    bool faultLevel;       /*!< True: Fault polarity is active low i.e '0' 
indicates a fault;
+                                False: Fault polarity is active high */
+    bool useFaultFilter;   /*!< True: Use the filtered fault signal;
+                                False: Use the direct path from fault input */
+} ftm_fault_param_t;
+
+/*! @brief FlexTimer pre-scaler factor for the dead time insertion*/
+typedef enum _ftm_deadtime_prescale
+{
+    kFTM_Deadtime_Prescale_1 = 1U, /*!< Divide by 1 */
+    kFTM_Deadtime_Prescale_4,      /*!< Divide by 4 */
+    kFTM_Deadtime_Prescale_16      /*!< Divide by 16 */
+} ftm_deadtime_prescale_t;
+
+/*! @brief FlexTimer clock source selection*/
+typedef enum _ftm_clock_source
+{
+    kFTM_SystemClock = 1U, /*!< System clock selected */
+    kFTM_FixedClock,       /*!< Fixed frequency clock */
+    kFTM_ExternalClock     /*!< External clock */
+} ftm_clock_source_t;
+
+/*! @brief FlexTimer pre-scaler factor selection for the clock source*/
+typedef enum _ftm_clock_prescale
+{
+    kFTM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */
+    kFTM_Prescale_Divide_2,      /*!< Divide by 2 */
+    kFTM_Prescale_Divide_4,      /*!< Divide by 4 */
+    kFTM_Prescale_Divide_8,      /*!< Divide by 8 */
+    kFTM_Prescale_Divide_16,     /*!< Divide by 16 */
+    kFTM_Prescale_Divide_32,     /*!< Divide by 32 */
+    kFTM_Prescale_Divide_64,     /*!< Divide by 64 */
+    kFTM_Prescale_Divide_128     /*!< Divide by 128 */
+} ftm_clock_prescale_t;
+
+/*! @brief Options for the FlexTimer behaviour in BDM Mode */
+typedef enum _ftm_bdm_mode
+{
+    kFTM_BdmMode_0 = 0U,
+    /*!< FTM counter stopped, CH(n)F bit can be set, FTM channels in 
functional mode, writes to MOD,CNTIN and C(n)V
+       registers bypass the register buffers */
+    kFTM_BdmMode_1,
+    /*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are 
forced to their safe value , writes to
+       MOD,CNTIN and C(n)V registers bypass the register buffers */
+    kFTM_BdmMode_2,
+    /*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are 
frozen when chip enters in BDM mode,
+       writes to MOD,CNTIN and C(n)V registers bypass the register buffers */
+    kFTM_BdmMode_3
+    /*!< FTM counter in functional mode, CH(n)F bit can be set, FTM channels 
in functional mode, writes to MOD,CNTIN and
+       C(n)V registers is in fully functional mode */
+} ftm_bdm_mode_t;
+
+/*! @brief Options for the FTM fault control mode */
+typedef enum _ftm_fault_mode
+{
+    kFTM_Fault_Disable = 0U, /*!< Fault control is disabled for all channels */
+    kFTM_Fault_EvenChnls,    /*!< Enabled for even channels only(0,2,4,6) with 
manual fault clearing */
+    kFTM_Fault_AllChnlsMan,  /*!< Enabled for all channels with manual fault 
clearing */
+    kFTM_Fault_AllChnlsAuto  /*!< Enabled for all channels with automatic 
fault clearing */
+} ftm_fault_mode_t;
+
+/*!
+ * @brief FTM external trigger options
+ * @note Actual available external trigger sources are SoC-specific
+ */
+typedef enum _ftm_external_trigger
+{
+    kFTM_Chnl0Trigger = (1U << 4), /*!< Generate trigger when counter equals 
chnl 0 CnV reg */
+    kFTM_Chnl1Trigger = (1U << 5), /*!< Generate trigger when counter equals 
chnl 1 CnV reg */
+    kFTM_Chnl2Trigger = (1U << 0), /*!< Generate trigger when counter equals 
chnl 2 CnV reg */
+    kFTM_Chnl3Trigger = (1U << 1), /*!< Generate trigger when counter equals 
chnl 3 CnV reg */
+    kFTM_Chnl4Trigger = (1U << 2), /*!< Generate trigger when counter equals 
chnl 4 CnV reg */
+    kFTM_Chnl5Trigger = (1U << 3), /*!< Generate trigger when counter equals 
chnl 5 CnV reg */
+    kFTM_Chnl6Trigger =
+        (1U << 8), /*!< Available on certain SoC's, generate trigger when 
counter equals chnl 6 CnV reg */
+    kFTM_Chnl7Trigger =
+        (1U << 9), /*!< Available on certain SoC's, generate trigger when 
counter equals chnl 7 CnV reg */
+    kFTM_InitTrigger = (1U << 6),      /*!< Generate Trigger when counter is 
updated with CNTIN */
+    kFTM_ReloadInitTrigger = (1U << 7) /*!< Available on certain SoC's, 
trigger on reload point */
+} ftm_external_trigger_t;
+
+/*! @brief FlexTimer PWM sync options to update registers with buffer */
+typedef enum _ftm_pwm_sync_method
+{
+    kFTM_SoftwareTrigger = FTM_SYNC_SWSYNC_MASK,  /*!< Software triggers PWM 
sync */
+    kFTM_HardwareTrigger_0 = FTM_SYNC_TRIG0_MASK, /*!< Hardware trigger 0 
causes PWM sync */
+    kFTM_HardwareTrigger_1 = FTM_SYNC_TRIG1_MASK, /*!< Hardware trigger 1 
causes PWM sync */
+    kFTM_HardwareTrigger_2 = FTM_SYNC_TRIG2_MASK  /*!< Hardware trigger 2 
causes PWM sync */
+} ftm_pwm_sync_method_t;
+
+/*!
+ * @brief FTM options available as loading point for register reload
+ * @note Actual available reload points are SoC-specific
+ */
+typedef enum _ftm_reload_point
+{
+    kFTM_Chnl0Match = (1U << 0),   /*!< Channel 0 match included as a reload 
point */
+    kFTM_Chnl1Match = (1U << 1),   /*!< Channel 1 match included as a reload 
point */
+    kFTM_Chnl2Match = (1U << 2),   /*!< Channel 2 match included as a reload 
point */
+    kFTM_Chnl3Match = (1U << 3),   /*!< Channel 3 match included as a reload 
point */
+    kFTM_Chnl4Match = (1U << 4),   /*!< Channel 4 match included as a reload 
point */
+    kFTM_Chnl5Match = (1U << 5),   /*!< Channel 5 match included as a reload 
point */
+    kFTM_Chnl6Match = (1U << 6),   /*!< Channel 6 match included as a reload 
point */
+    kFTM_Chnl7Match = (1U << 7),   /*!< Channel 7 match included as a reload 
point */
+    kFTM_CntMax = (1U << 8),       /*!< Use in up-down count mode only, reload 
when counter reaches the maximum value */
+    kFTM_CntMin = (1U << 9),       /*!< Use in up-down count mode only, reload 
when counter reaches the minimum value */
+    kFTM_HalfCycMatch = (1U << 10) /*!< Available on certain SoC's, half cycle 
match reload point */
+} ftm_reload_point_t;
+
+/*!
+ * @brief List of FTM interrupts
+ * @note Actual available interrupts are SoC-specific
+ */
+typedef enum _ftm_interrupt_enable
+{
+    kFTM_Chnl0InterruptEnable = (1U << 0),        /*!< Channel 0 interrupt */
+    kFTM_Chnl1InterruptEnable = (1U << 1),        /*!< Channel 1 interrupt */
+    kFTM_Chnl2InterruptEnable = (1U << 2),        /*!< Channel 2 interrupt */
+    kFTM_Chnl3InterruptEnable = (1U << 3),        /*!< Channel 3 interrupt */
+    kFTM_Chnl4InterruptEnable = (1U << 4),        /*!< Channel 4 interrupt */
+    kFTM_Chnl5InterruptEnable = (1U << 5),        /*!< Channel 5 interrupt */
+    kFTM_Chnl6InterruptEnable = (1U << 6),        /*!< Channel 6 interrupt */
+    kFTM_Chnl7InterruptEnable = (1U << 7),        /*!< Channel 7 interrupt */
+    kFTM_FaultInterruptEnable = (1U << 8),        /*!< Fault interrupt */
+    kFTM_TimeOverflowInterruptEnable = (1U << 9), /*!< Time overflow interrupt 
*/
+    kFTM_ReloadInterruptEnable = (1U << 10)       /*!< Reload interrupt; 
Available only on certain SoC's */
+} ftm_interrupt_enable_t;
+
+/*!
+ * @brief List of FTM flags
+ * @note Actual available flags are SoC-specific
+ */
+typedef enum _ftm_status_flags
+{
+    kFTM_Chnl0Flag = (1U << 0),        /*!< Channel 0 Flag */
+    kFTM_Chnl1Flag = (1U << 1),        /*!< Channel 1 Flag */
+    kFTM_Chnl2Flag = (1U << 2),        /*!< Channel 2 Flag */
+    kFTM_Chnl3Flag = (1U << 3),        /*!< Channel 3 Flag */
+    kFTM_Chnl4Flag = (1U << 4),        /*!< Channel 4 Flag */
+    kFTM_Chnl5Flag = (1U << 5),        /*!< Channel 5 Flag */
+    kFTM_Chnl6Flag = (1U << 6),        /*!< Channel 6 Flag */
+    kFTM_Chnl7Flag = (1U << 7),        /*!< Channel 7 Flag */
+    kFTM_FaultFlag = (1U << 8),        /*!< Fault Flag */
+    kFTM_TimeOverflowFlag = (1U << 9), /*!< Time overflow Flag */
+    kFTM_ChnlTriggerFlag = (1U << 10), /*!< Channel trigger Flag */
+    kFTM_ReloadFlag = (1U << 11)       /*!< Reload Flag; Available only on 
certain SoC's */
+} ftm_status_flags_t;
+
+/*!
+ * @brief FTM configuration structure
+ *
+ * This structure holds the configuration settings for the FTM peripheral. To 
initialize this
+ * structure to reasonable defaults, call the FTM_GetDefaultConfig() function 
and pass a
+ * pointer to the configuration structure instance.
+ *
+ * The configuration structure can be made constant so as to reside in flash.
+ */
+typedef struct _ftm_config
+{
+    ftm_clock_prescale_t prescale;            /*!< FTM clock prescale value */
+    ftm_bdm_mode_t bdmMode;                   /*!< FTM behavior in BDM mode */
+    uint32_t pwmSyncMode;                     /*!< Synchronization methods to 
use to update buffered registers; Multiple
+                                                   update modes can be used by 
providing an OR'ed list of options
+                                                   available in enumeration 
::ftm_pwm_sync_method_t. */
+    uint32_t reloadPoints;                    /*!< FTM reload points; When 
using this, the PWM
+                                                   synchronization is not 
required. Multiple reload points can be used by providing
+                                                   an OR'ed list of options 
available in
+                                                   enumeration 
::ftm_reload_point_t. */
+    ftm_fault_mode_t faultMode;               /*!< FTM fault control mode */
+    uint8_t faultFilterValue;                 /*!< Fault input filter value */
+    ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar 
value */
+    uint8_t deadTimeValue;                    /*!< The dead time value */
+    uint32_t extTriggers;                     /*!< External triggers to 
enable. Multiple trigger sources can be
+                                                   enabled by providing an 
OR'ed list of options available in
+                                                   enumeration 
::ftm_external_trigger_t. */
+    uint8_t chnlInitState;  /*!< Defines the initialization value of the 
channels in OUTINT register */
+    uint8_t chnlPolarity;   /*!< Defines the output polarity of the channels 
in POL register */
+    bool useGlobalTimeBase; /*!< True: Use of an external global time base is 
enabled;
+                                 False: disabled */
+} ftm_config_t;
+
+/*******************************************************************************
+ * API
+ 
******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Ungates the FTM clock and configures the peripheral for basic 
operation.
+ *
+ * @note This API should be called at the beginning of the application using 
the FTM driver.
+ *
+ * @param base   FTM peripheral base address
+ * @param config Pointer to the user configuration structure.
+ *
+ * @return kStatus_Success indicates success; Else indicates failure.
+ */
+status_t FTM_Init(FTM_Type *base, const ftm_config_t *config);
+
+/*!
+ * @brief Gates the FTM clock.
+ *
+ * @param base FTM peripheral base address
+ */
+void FTM_Deinit(FTM_Type *base);
+
+/*!
+ * @brief  Fills in the FTM configuration structure with the default settings.
+ *
+ * The default values are:
+ * @code
+ *   config->prescale = kFTM_Prescale_Divide_1;
+ *   config->bdmMode = kFTM_BdmMode_0;
+ *   config->pwmSyncMode = kFTM_SoftwareTrigger;
+ *   config->reloadPoints = 0;
+ *   config->faultMode = kFTM_Fault_Disable;
+ *   config->faultFilterValue = 0;
+ *   config->deadTimePrescale = kFTM_Deadtime_Prescale_1;
+ *   config->deadTimeValue =  0;
+ *   config->extTriggers = 0;
+ *   config->chnlInitState = 0;
+ *   config->chnlPolarity = 0;
+ *   config->useGlobalTimeBase = false;
+ * @endcode
+ * @param config Pointer to the user configuration structure.
+ */
+void FTM_GetDefaultConfig(ftm_config_t *config);
+
+/*! @}*/
+
+/*!
+ * @name Channel mode operations
+ * @{
+ */
+
+/*!
+ * @brief Configures the PWM signal parameters.
+ *
+ * Call this function to configure the PWM signal period, mode, duty cycle, 
and edge. Use this
+ * function to configure all FTM channels that are used to output a PWM signal.
+ *
+ * @param base        FTM peripheral base address
+ * @param chnlParams  Array of PWM channel parameters to configure the 
channel(s)
+ * @param numOfChnls  Number of channels to configure; This should be the size 
of the array passed in
+ * @param mode        PWM operation mode, options available in enumeration 
::ftm_pwm_mode_t
+ * @param pwmFreq_Hz  PWM signal frequency in Hz
+ * @param srcClock_Hz FTM counter clock in Hz
+ *
+ * @return kStatus_Success if the PWM setup was successful
+ *         kStatus_Error on failure
+ */
+status_t FTM_SetupPwm(FTM_Type *base,
+                      const ftm_chnl_pwm_signal_param_t *chnlParams,
+                      uint8_t numOfChnls,
+                      ftm_pwm_mode_t mode,
+                      uint32_t pwmFreq_Hz,
+                      uint32_t srcClock_Hz);
+
+/*!
+ * @brief Updates the duty cycle of an active PWM signal.
+ *
+ * @param base              FTM peripheral base address
+ * @param chnlNumber        The channel/channel pair number. In combined mode, 
this represents
+ *                          the channel pair number
+ * @param currentPwmMode    The current PWM mode set during PWM setup
+ * @param dutyCyclePercent  New PWM pulse width; The value should be between 0 
to 100
+ *                          0=inactive signal(0% duty cycle)...
+ *                          100=active signal (100% duty cycle)
+ */
+void FTM_UpdatePwmDutycycle(FTM_Type *base,
+                            ftm_chnl_t chnlNumber,
+                            ftm_pwm_mode_t currentPwmMode,
+                            uint8_t dutyCyclePercent);
+
+/*!
+ * @brief Updates the edge level selection for a channel.
+ *
+ * @param base       FTM peripheral base address
+ * @param chnlNumber The channel number
+ * @param level      The level to be set to the ELSnB:ELSnA field; Valid 
values are 00, 01, 10, 11.
+ *                   See the Kinetis SoC reference manual for details about 
this field.
+ */
+void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, 
uint8_t level);
+
+/*!
+ * @brief Enables capturing an input signal on the channel using the function 
parameters.
+ *
+ * When the edge specified in the captureMode argument occurs on the channel, 
the FTM counter is
+ * captured into the CnV register. The user has to read the CnV register 
separately to get this
+ * value. The filter function is disabled if the filterVal argument passed in 
is 0. The filter
+ * function is available only for channels 0, 1, 2, 3.
+ *
+ * @param base        FTM peripheral base address
+ * @param chnlNumber  The channel number
+ * @param captureMode Specifies which edge to capture
+ * @param filterValue Filter value, specify 0 to disable filter. Available 
only for channels 0-3.
+ */
+void FTM_SetupInputCapture(FTM_Type *base,
+                           ftm_chnl_t chnlNumber,
+                           ftm_input_capture_edge_t captureMode,
+                           uint32_t filterValue);
+
+/*!
+ * @brief Configures the FTM to generate timed pulses.
+ *
+ * When the FTM counter matches the value of compareVal argument (this is 
written into CnV reg),
+ * the channel output is changed based on what is specified in the compareMode 
argument.
+ *
+ * @param base         FTM peripheral base address
+ * @param chnlNumber   The channel number
+ * @param compareMode  Action to take on the channel output when the compare 
condition is met
+ * @param compareValue Value to be programmed in the CnV register.
+ */
+void FTM_SetupOutputCompare(FTM_Type *base,
+                            ftm_chnl_t chnlNumber,
+                            ftm_output_compare_mode_t compareMode,
+                            uint32_t compareValue);
+
+/*!
+ * @brief Configures the dual edge capture mode of the FTM.
+ *
+ * This function sets up the dual edge capture mode on a channel pair. The 
capture edge for the
+ * channel pair and the capture mode (one-shot or continuous) is specified in 
the parameter
+ * argument. The filter function is disabled if the filterVal argument passed 
is zero. The filter
+ * function is available only on channels 0 and 2. The user has to read the 
channel CnV registers
+ * separately to get the capture values.
+ *
+ * @param base           FTM peripheral base address
+ * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
+ * @param edgeParam      Sets up the dual edge capture function
+ * @param filterValue    Filter value, specify 0 to disable filter. Available 
only for channel pair 0 and 1.
+ */
+void FTM_SetupDualEdgeCapture(FTM_Type *base,
+                              ftm_chnl_t chnlPairNumber,
+                              const ftm_dual_edge_capture_param_t *edgeParam,
+                              uint32_t filterValue);
+
+/*! @}*/
+
+/*!
+ * @brief Configures the parameters and activates the quadrature decoder mode.
+ *
+ * @param base         FTM peripheral base address
+ * @param phaseAParams Phase A configuration parameters
+ * @param phaseBParams Phase B configuration parameters
+ * @param quadMode     Selects encoding mode used in quadrature decoder mode
+ */
+void FTM_SetupQuadDecode(FTM_Type *base,
+                         const ftm_phase_params_t *phaseAParams,
+                         const ftm_phase_params_t *phaseBParams,
+                         ftm_quad_decode_mode_t quadMode);
+
+/*!
+ * @brief Sets up the working of the FTM fault protection.
+ *
+ * FTM can have up to 4 fault inputs. This function sets up fault parameters, 
fault level, and a filter.
+ *
+ * @param base        FTM peripheral base address
+ * @param faultNumber FTM fault to configure.
+ * @param faultParams Parameters passed in to set up the fault
+ */
+void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const 
ftm_fault_param_t *faultParams);
+
+/*!
+ * @name Interrupt Interface
+ * @{
+ */
+
+/*!
+ * @brief Enables the selected FTM interrupts.
+ *
+ * @param base FTM peripheral base address
+ * @param mask The interrupts to enable. This is a logical OR of members of the
+ *             enumeration ::ftm_interrupt_enable_t
+ */
+void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask);
+
+/*!
+ * @brief Disables the selected FTM interrupts.
+ *
+ * @param base FTM peripheral base address
+ * @param mask The interrupts to enable. This is a logical OR of members of the
+ *             enumeration ::ftm_interrupt_enable_t
+ */
+void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask);
+
+/*!
+ * @brief Gets the enabled FTM interrupts.
+ *
+ * @param base FTM peripheral base address
+ *
+ * @return The enabled interrupts. This is the logical OR of members of the
+ *         enumeration ::ftm_interrupt_enable_t
+ */
+uint32_t FTM_GetEnabledInterrupts(FTM_Type *base);
+
+/*! @}*/
+
+/*!
+ * @name Status Interface
+ * @{
+ */
+
+/*!
+ * @brief Gets the FTM status flags.
+ *
+ * @param base FTM peripheral base address
+ *
+ * @return The status flags. This is the logical OR of members of the
+ *         enumeration ::ftm_status_flags_t
+ */
+uint32_t FTM_GetStatusFlags(FTM_Type *base);
+
+/*!
+ * @brief Clears the FTM status flags.
+ *
+ * @param base FTM peripheral base address
+ * @param mask The status flags to clear. This is a logical OR of members of 
the
+ *             enumeration ::ftm_status_flags_t
+ */
+void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask);
+
+/*! @}*/
+
+/*!
+ * @name Timer Start and Stop
+ * @{
+ */
+
+/*!
+ * @brief Starts the FTM counter.
+ *
+ * @param base        FTM peripheral base address
+ * @param clockSource FTM clock source; After the clock source is set, the 
counter starts running.
+ */
+static inline void FTM_StartTimer(FTM_Type *base, ftm_clock_source_t 
clockSource)
+{
+    uint32_t reg = base->SC;
+
+    reg &= ~(FTM_SC_CLKS_MASK);
+    reg |= FTM_SC_CLKS(clockSource);
+    base->SC = reg;
+}
+
+/*!
+ * @brief Stops the FTM counter.
+ *
+ * @param base FTM peripheral base address
+ */
+static inline void FTM_StopTimer(FTM_Type *base)
+{
+    /* Set clock source to none to disable counter */
+    base->SC &= ~(FTM_SC_CLKS_MASK);
+}
+
+/*! @}*/
+
+/*!
+ * @name Software output control
+ * @{
+ */
+
+/*!
+ * @brief Enables or disables the channel software output control.
+ *
+ * @param base       FTM peripheral base address
+ * @param chnlNumber Channel to be enabled or disabled
+ * @param value      true: channel output is affected by software output 
control
+                     false: channel output is unaffected by software output 
control
+ */
+static inline void FTM_SetSoftwareCtrlEnable(FTM_Type *base, ftm_chnl_t 
chnlNumber, bool value)
+{
+    if (value)
+    {
+        base->SWOCTRL |= (1U << chnlNumber);
+    }
+    else
+    {
+        base->SWOCTRL &= ~(1U << chnlNumber);
+    }
+}
+
+/*!
+ * @brief Sets the channel software output control value.
+ *
+ * @param base       FTM peripheral base address.
+ * @param chnlNumber Channel to be configured
+ * @param value      true to set 1, false to set 0
+ */
+static inline void FTM_SetSoftwareCtrlVal(FTM_Type *base, ftm_chnl_t 
chnlNumber, bool value)
+{
+    if (value)
+    {
+        base->SWOCTRL |= (1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT));
+    }
+    else
+    {
+        base->SWOCTRL &= ~(1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT));
+    }
+}
+
+/*! @}*/
+
+/*!
+ * @brief Enables or disables the FTM global time base signal generation to 
other FTMs.
+ *
+ * @param base   FTM peripheral base address
+ * @param enable true to enable, false to disable
+ */
+static inline void FTM_SetGlobalTimeBaseOutputEnable(FTM_Type *base, bool 
enable)
+{
+    if (enable)
+    {
+        base->CONF |= FTM_CONF_GTBEOUT_MASK;
+    }
+    else
+    {
+        base->CONF &= ~FTM_CONF_GTBEOUT_MASK;
+    }
+}
+
+/*!
+ * @brief Sets the FTM peripheral timer channel output mask.
+ *
+ * @param base       FTM peripheral base address
+ * @param chnlNumber Channel to be configured
+ * @param mask       true: masked, channel is forced to its inactive state; 
false: unmasked
+ */
+static inline void FTM_SetOutputMask(FTM_Type *base, ftm_chnl_t chnlNumber, 
bool mask)
+{
+    if (mask)
+    {
+        base->OUTMASK |= (1U << chnlNumber);
+    }
+    else
+    {
+        base->OUTMASK &= ~(1U << chnlNumber);
+    }
+}
+
+#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && 
(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
+/*!
+ * @brief Allows user to enable an output on an FTM channel.
+ *
+ * To enable the PWM channel output call this function with val=true. For 
input mode,
+ * call this function with val=false.
+ *
+ * @param base       FTM peripheral base address
+ * @param chnlNumber Channel to be configured
+ * @param value      true: enable output; false: output is disabled, used in 
input mode
+ */
+static inline void FTM_SetPwmOutputEnable(FTM_Type *base, ftm_chnl_t 
chnlNumber, bool value)
+{
+    if (value)
+    {
+        base->SC |= (1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT));
+    }
+    else
+    {
+        base->SC &= ~(1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT));
+    }
+}
+#endif
+
+/*!
+ * @name Channel pair operations
+ * @{
+ */
+
+/*!
+ * @brief This function enables/disables the fault control in a channel pair.
+ *
+ * @param base           FTM peripheral base address
+ * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
+ * @param value          true: Enable fault control for this channel pair; 
false: No fault control
+ */
+static inline void FTM_SetFaultControlEnable(FTM_Type *base, ftm_chnl_t 
chnlPairNumber, bool value)
+{
+    if (value)
+    {
+        base->COMBINE |= (1U << (FTM_COMBINE_FAULTEN0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
+    }
+    else
+    {
+        base->COMBINE &= ~(1U << (FTM_COMBINE_FAULTEN0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
+    }
+}
+
+/*!
+ * @brief This function enables/disables the dead time insertion in a channel 
pair.
+ *
+ * @param base           FTM peripheral base address
+ * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
+ * @param value          true: Insert dead time in this channel pair; false: 
No dead time inserted
+ */
+static inline void FTM_SetDeadTimeEnable(FTM_Type *base, ftm_chnl_t 
chnlPairNumber, bool value)
+{
+    if (value)
+    {
+        base->COMBINE |= (1U << (FTM_COMBINE_DTEN0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
+    }
+    else
+    {
+        base->COMBINE &= ~(1U << (FTM_COMBINE_DTEN0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
+    }
+}
+
+/*!
+ * @brief This function enables/disables complementary mode in a channel pair.
+ *
+ * @param base           FTM peripheral base address
+ * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
+ * @param value          true: enable complementary mode; false: disable 
complementary mode
+ */
+static inline void FTM_SetComplementaryEnable(FTM_Type *base, ftm_chnl_t 
chnlPairNumber, bool value)
+{
+    if (value)
+    {
+        base->COMBINE |= (1U << (FTM_COMBINE_COMP0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
+    }
+    else
+    {
+        base->COMBINE &= ~(1U << (FTM_COMBINE_COMP0_SHIFT + 
(FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
+    }
+}
+
+/*!
+ * @brief This function enables/disables inverting control in a channel pair.
+ *
+ * @param base            FTM peripheral base address
+ * @param chnlPairNumber  The FTM channel pair number; options are 0, 1, 2, 3
+ * @param value           true: enable inverting; false: disable inverting
+ */
+static inline void FTM_SetInvertEnable(FTM_Type *base, ftm_chnl_t 
chnlPairNumber, bool value)
+{
+    if (value)
+    {
+        base->INVCTRL |= (1U << chnlPairNumber);
+    }
+    else
+    {
+        base->INVCTRL &= ~(1U << chnlPairNumber);
+    }
+}
+
+/*! @}*/
+
+/*!
+ * @brief Enables or disables the FTM software trigger for PWM synchronization.
+ *
+ * @param base   FTM peripheral base address
+ * @param enable true: software trigger is selected, false: software trigger 
is not selected
+ */
+static inline void FTM_SetSoftwareTrigger(FTM_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->SYNC |= FTM_SYNC_SWSYNC_MASK;
+    }
+    else
+    {
+        base->SYNC &= ~FTM_SYNC_SWSYNC_MASK;
+    }
+}
+
+/*!
+ * @brief Enables or disables the FTM write protection.
+ *
+ * @param base   FTM peripheral base address
+ * @param enable true: Write-protection is enabled, false: Write-protection is 
disabled
+ */
+static inline void FTM_SetWriteProtection(FTM_Type *base, bool enable)
+{
+    /* Configure write protection */
+    if (enable)
+    {
+        base->FMS |= FTM_FMS_WPEN_MASK;
+    }
+    else
+    {
+        base->MODE |= FTM_MODE_WPDIS_MASK;
+    }
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_FTM_H_*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f8f2ebbf/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.c
----------------------------------------------------------------------
diff --git 
a/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.c
 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.c
new file mode 100644
index 0000000..8fc068f
--- /dev/null
+++ 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, 
this list
+ *   of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, 
this
+ *   list of conditions and the following disclaimer in the documentation 
and/or
+ *   other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fsl_gpio.h"
+
+/*******************************************************************************
+ * Variables
+ 
******************************************************************************/
+static PORT_Type *const s_portBases[] = PORT_BASE_PTRS;
+static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
+
+/*******************************************************************************
+* Prototypes
+******************************************************************************/
+
+/*!
+* @brief Gets the GPIO instance according to the GPIO base
+*
+* @param base    GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
+* @retval GPIO instance
+*/
+static uint32_t GPIO_GetInstance(GPIO_Type *base);
+
+/*******************************************************************************
+ * Code
+ 
******************************************************************************/
+
+static uint32_t GPIO_GetInstance(GPIO_Type *base)
+{
+    uint32_t instance;
+
+    /* Find the instance index from base address mappings. */
+    for (instance = 0; instance < FSL_FEATURE_SOC_GPIO_COUNT; instance++)
+    {
+        if (s_gpioBases[instance] == base)
+        {
+            break;
+        }
+    }
+
+    assert(instance < FSL_FEATURE_SOC_GPIO_COUNT);
+
+    return instance;
+}
+
+void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t 
*config)
+{
+    assert(config);
+
+    if (config->pinDirection == kGPIO_DigitalInput)
+    {
+        base->PDDR &= ~(1U << pin);
+    }
+    else
+    {
+        GPIO_WritePinOutput(base, pin, config->outputLogic);
+        base->PDDR |= (1U << pin);
+    }
+}
+
+uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base)
+{
+    uint8_t instance;
+    PORT_Type *portBase;
+    instance = GPIO_GetInstance(base);
+    portBase = s_portBases[instance];
+    return portBase->ISFR;
+}
+
+void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask)
+{
+    uint8_t instance;
+    PORT_Type *portBase;
+    instance = GPIO_GetInstance(base);
+    portBase = s_portBases[instance];
+    portBase->ISFR = mask;
+}
+
+#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
+
+/*******************************************************************************
+ * Variables
+ 
******************************************************************************/
+static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS;
+
+/*******************************************************************************
+* Prototypes
+******************************************************************************/
+/*!
+* @brief Gets the FGPIO instance according to the GPIO base
+*
+* @param base    FGPIO peripheral base pointer(PTA, PTB, PTC, etc.)
+* @retval FGPIO instance
+*/
+static uint32_t FGPIO_GetInstance(FGPIO_Type *base);
+
+/*******************************************************************************
+ * Code
+ 
******************************************************************************/
+
+static uint32_t FGPIO_GetInstance(FGPIO_Type *base)
+{
+    uint32_t instance;
+
+    /* Find the instance index from base address mappings. */
+    for (instance = 0; instance < FSL_FEATURE_SOC_FGPIO_COUNT; instance++)
+    {
+        if (s_fgpioBases[instance] == base)
+        {
+            break;
+        }
+    }
+
+    assert(instance < FSL_FEATURE_SOC_FGPIO_COUNT);
+
+    return instance;
+}
+
+void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t 
*config)
+{
+    assert(config);
+
+    if (config->pinDirection == kGPIO_DigitalInput)
+    {
+        base->PDDR &= ~(1U << pin);
+    }
+    else
+    {
+        FGPIO_WritePinOutput(base, pin, config->outputLogic);
+        base->PDDR |= (1U << pin);
+    }
+}
+
+uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base)
+{
+    uint8_t instance;
+    instance = FGPIO_GetInstance(base);
+    PORT_Type *portBase;
+    portBase = s_portBases[instance];
+    return portBase->ISFR;
+}
+
+void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask)
+{
+    uint8_t instance;
+    instance = FGPIO_GetInstance(base);
+    PORT_Type *portBase;
+    portBase = s_portBases[instance];
+    portBase->ISFR = mask;
+}
+
+#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f8f2ebbf/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.h
----------------------------------------------------------------------
diff --git 
a/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.h
 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.h
new file mode 100644
index 0000000..6eaaaa0
--- /dev/null
+++ 
b/hw/mcu/nxp/src/ext/sdk-2.0-frdm-k64f_b160321/devices/MK64F12/drivers/fsl_gpio.h
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, 
this list
+ *   of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, 
this
+ *   list of conditions and the following disclaimer in the documentation 
and/or
+ *   other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FSL_GPIO_H_
+#define _FSL_GPIO_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup gpio
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ 
******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief GPIO driver version 2.1.0. */
+#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
+/*@}*/
+
+/*! @brief GPIO direction definition*/
+typedef enum _gpio_pin_direction
+{
+    kGPIO_DigitalInput = 0U,  /*!< Set current pin as digital input*/
+    kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
+} gpio_pin_direction_t;
+
+/*!
+ * @brief The GPIO pin configuration structure.
+ *
+ * Every pin can only be configured as either output pin or input pin at a 
time.
+ * If configured as a input pin, then leave the outputConfig unused
+ * Note : In some cases, the corresponding port property should be configured 
in advance
+ *        with the PORT_SetPinConfig()
+ */
+typedef struct _gpio_pin_config
+{
+    gpio_pin_direction_t pinDirection; /*!< gpio direction, input or output */
+    /* Output configurations, please ignore if configured as a input one */
+    uint8_t outputLogic; /*!< Set default output logic, no use in input */
+} gpio_pin_config_t;
+
+/*! @} */
+
+/*******************************************************************************
+ * API
+ 
******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @addtogroup gpio_driver
+ * @{
+ */
+
+/*! @name GPIO Configuration */
+/*@{*/
+
+/*!
+ * @brief Initializes a GPIO pin used by the board.
+ *
+ * To initialize the GPIO, define a pin configuration, either input or output, 
in the user file.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * @code
+ * // Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalInput,
+ *   0,
+ * }
+ * //Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalOutput,
+ *   0,
+ * }
+ * @endcode
+ *
+ * @param base   GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param pin    GPIO port pin number
+ * @param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t 
*config);
+
+/*@}*/
+
+/*! @name GPIO Output Operations */
+/*@{*/
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0.
+ *
+ * @param base    GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param pin     GPIO pin's number
+ * @param output  GPIO pin output logic level.
+ *        - 0: corresponding pin output low logic level.
+ *        - 1: corresponding pin output high logic level.
+ */
+static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t 
output)
+{
+    if (output == 0U)
+    {
+        base->PCOR = 1 << pin;
+    }
+    else
+    {
+        base->PSOR = 1 << pin;
+    }
+}
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 1.
+ *
+ * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask GPIO pins' numbers macro
+ */
+static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
+{
+    base->PSOR = mask;
+}
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 0.
+ *
+ * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask GPIO pins' numbers macro
+ */
+static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
+{
+    base->PCOR = mask;
+}
+
+/*!
+ * @brief Reverses current output logic of the multiple GPIO pins.
+ *
+ * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask GPIO pins' numbers macro
+ */
+static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask)
+{
+    base->PTOR = mask;
+}
+/*@}*/
+
+/*! @name GPIO Input Operations */
+/*@{*/
+
+/*!
+ * @brief Reads the current input value of the whole GPIO port.
+ *
+ * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param pin     GPIO pin's number
+ * @retval GPIO port input value
+ *        - 0: corresponding pin input low logic level.
+ *        - 1: corresponding pin input high logic level.
+ */
+static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
+{
+    return (((base->PDIR) >> pin) & 0x01U);
+}
+/*@}*/
+
+/*! @name GPIO Interrupt */
+/*@{*/
+
+/*!
+ * @brief Reads whole GPIO port interrupt status flag.
+ *
+ * If a pin is configured to generate the DMA request, the corresponding flag
+ * is cleared automatically at the completion of the requested DMA transfer.
+ * Otherwise, the flag remains set until a logic one is written to that flag.
+ * If configured for a level sensitive interrupt that remains asserted, the 
flag
+ * is set again immediately.
+ *
+ * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @retval Current GPIO port interrupt status flag, for example, 0x00010001 
means the
+ *         pin 0 and 17 have the interrupt.
+ */
+uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base);
+
+/*!
+ * @brief Clears multiple GPIO pins' interrupt status flag.
+ *
+ * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask GPIO pins' numbers macro
+ */
+void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
+
+/*@}*/
+/*! @} */
+
+/*!
+ * @addtogroup fgpio_driver
+ * @{
+ */
+
+/*
+ * Introduce the FGPIO feature.
+ *
+ * The FGPIO features are only support on some of Kinetis chips. The FGPIO 
registers are aliased to the IOPORT
+ * interface. Accesses via the IOPORT interface occur in parallel with any 
instruction fetches and will therefore
+ * complete in a single cycle. This aliased Fast GPIO memory map is called 
FGPIO.
+ */
+
+#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
+
+/*! @name FGPIO Configuration */
+/*@{*/
+
+/*!
+ * @brief Initializes a FGPIO pin used by the board.
+ *
+ * To initialize the FGPIO driver, define a pin configuration, either input or 
output, in the user file.
+ * Then, call the FGPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * @code
+ * // Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalInput,
+ *   0,
+ * }
+ * //Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ *   kGPIO_DigitalOutput,
+ *   0,
+ * }
+ * @endcode
+ *
+ * @param base   FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param pin    FGPIO port pin number
+ * @param config FGPIO pin configuration pointer
+ */
+void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t 
*config);
+
+/*@}*/
+
+/*! @name FGPIO Output Operations */
+/*@{*/
+
+/*!
+ * @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0.
+ *
+ * @param base    FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so 
on.)
+ * @param pin     FGPIO pin's number
+ * @param output  FGPIOpin output logic level.
+ *        - 0: corresponding pin output low logic level.
+ *        - 1: corresponding pin output high logic level.
+ */
+static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, 
uint8_t output)
+{
+    if (output == 0U)
+    {
+        base->PCOR = 1 << pin;
+    }
+    else
+    {
+        base->PSOR = 1 << pin;
+    }
+}
+
+/*!
+ * @brief Sets the output level of the multiple FGPIO pins to the logic 1.
+ *
+ * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask FGPIO pins' numbers macro
+ */
+static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask)
+{
+    base->PSOR = mask;
+}
+
+/*!
+ * @brief Sets the output level of the multiple FGPIO pins to the logic 0.
+ *
+ * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask FGPIO pins' numbers macro
+ */
+static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask)
+{
+    base->PCOR = mask;
+}
+
+/*!
+ * @brief Reverses current output logic of the multiple FGPIO pins.
+ *
+ * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask FGPIO pins' numbers macro
+ */
+static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask)
+{
+    base->PTOR = mask;
+}
+/*@}*/
+
+/*! @name FGPIO Input Operations */
+/*@{*/
+
+/*!
+ * @brief Reads the current input value of the whole FGPIO port.
+ *
+ * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param pin  FGPIO pin's number
+ * @retval FGPIO port input value
+ *        - 0: corresponding pin input low logic level.
+ *        - 1: corresponding pin input high logic level.
+ */
+static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin)
+{
+    return (((base->PDIR) >> pin) & 0x01U);
+}
+/*@}*/
+
+/*! @name FGPIO Interrupt */
+/*@{*/
+
+/*!
+ * @brief Reads the whole FGPIO port interrupt status flag.
+ *
+ * If a pin is configured to generate the DMA request,  the corresponding flag
+ * is cleared automatically at the completion of the requested DMA transfer.
+ * Otherwise, the flag remains set until a logic one is written to that flag.
+ * If configured for a level sensitive interrupt that remains asserted, the 
flag
+ * is set again immediately.
+ *
+ * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @retval Current FGPIO port interrupt status flags, for example, 0x00010001 
means the
+ *         pin 0 and 17 have the interrupt.
+ */
+uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base);
+
+/*!
+ * @brief Clears the multiple FGPIO pins' interrupt status flag.
+ *
+ * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
+ * @param mask FGPIO pins' numbers macro
+ */
+void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask);
+
+/*@}*/
+
+#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*!
+ * @}
+ */
+
+#endif /* _FSL_GPIO_H_*/

Reply via email to