added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Sun May 22 17:00:12 2016 +0100
Parent:
131:830c525a60d5
Child:
133:0113f86169f0
Commit message:
Synchronized with git revision bd78f98496fab2f02162521d7e279d7bd0f0840e

Full URL: https://github.com/mbedmicro/mbed/commit/bd78f98496fab2f02162521d7e279d7bd0f0840e/

Fix for Issue#1740.

Changed in this revision

targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/drivers/fsl_ftm.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/drivers/fsl_ftm.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_tpm.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_tpm.h Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.c	Tue May 17 14:45:12 2016 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.c	Sun May 22 17:00:12 2016 +0100
@@ -237,11 +237,8 @@
     /* 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);
-    }
+    /* Setup intermediate register reload points */
+    FTM_SetReloadPoints(base, config->reloadPoints);
 
     /* Set the clock prescale factor */
     base->SC = FTM_SC_PS(config->prescale);
@@ -327,6 +324,9 @@
                       uint32_t srcClock_Hz)
 {
     assert(chnlParams);
+    assert(srcClock_Hz);
+    assert(pwmFreq_Hz);
+    assert(numOfChnls);
 
     uint32_t mod, reg;
     uint32_t ftmClock = (srcClock_Hz / (1U << (base->SC & FTM_SC_PS_MASK)));
@@ -373,7 +373,7 @@
             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));
+            reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
 
             /* Edge-aligned mode needs MSB to be 1, don't care for Center-aligned mode */
             reg |= FTM_CnSC_MSB(1U);
@@ -397,6 +397,10 @@
             }
 
             base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
+#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
         }
         else
         {
@@ -445,7 +449,7 @@
             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));
+            reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
 
             /* Update the mode and edge level for channel n */
             base->CONTROLS[chnlParams->chnlNumber * 2].CnSC = reg;
@@ -455,25 +459,25 @@
             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));
+            reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
 
             /* Update the mode and edge level for channel n + 1*/
             base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC = reg;
 
+            /* Set the combine bit for the channel pair */
+            base->COMBINE |=
+                (1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlParams->chnlNumber)));
+
             /* 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, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2), true);
+            FTM_SetPwmOutputEnable(base, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2 + 1), true);
+#endif
         }
-
-#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++;
     }
 
@@ -535,6 +539,13 @@
 {
     uint32_t reg;
 
+    /* Clear the combine bit for the channel pair */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the dual edge capture mode because it's it's higher priority */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the quadrature decoder mode beacause it's higher priority */
+    base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
+
     reg = base->CONTROLS[chnlNumber].CnSC;
     reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
     reg |= captureMode;
@@ -562,8 +573,12 @@
 {
     uint32_t reg;
 
-    /* Set output on match to the requested level */
-    base->CONTROLS[chnlNumber].CnV = compareValue;
+    /* Clear the combine bit for the channel pair */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the dual edge capture mode because it's it's higher priority */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the quadrature decoder mode beacause it's higher priority */
+    base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
 
     reg = base->CONTROLS[chnlNumber].CnSC;
     reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
@@ -571,6 +586,9 @@
     /* Setup the channel output behaviour when a match occurs with the compare value */
     base->CONTROLS[chnlNumber].CnSC = reg;
 
+    /* Set output on match to the requested level */
+    base->CONTROLS[chnlNumber].CnV = compareValue;
+
 #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);
@@ -662,6 +680,8 @@
 
 void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams)
 {
+    assert(faultParams);
+
     uint32_t reg;
 
     reg = base->FLTCTRL;
--- a/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.h	Tue May 17 14:45:12 2016 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K22F/drivers/fsl_ftm.h	Sun May 22 17:00:12 2016 +0100
@@ -33,7 +33,7 @@
 #include "fsl_common.h"
 
 /*!
- * @addtogroup ftm_driver
+ * @addtogroup ftm
  * @{
  */
 
@@ -162,7 +162,7 @@
 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;
+    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 */
--- a/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/drivers/fsl_ftm.c	Tue May 17 14:45:12 2016 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/drivers/fsl_ftm.c	Sun May 22 17:00:12 2016 +0100
@@ -237,11 +237,8 @@
     /* 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);
-    }
+    /* Setup intermediate register reload points */
+    FTM_SetReloadPoints(base, config->reloadPoints);
 
     /* Set the clock prescale factor */
     base->SC = FTM_SC_PS(config->prescale);
@@ -327,6 +324,9 @@
                       uint32_t srcClock_Hz)
 {
     assert(chnlParams);
+    assert(srcClock_Hz);
+    assert(pwmFreq_Hz);
+    assert(numOfChnls);
 
     uint32_t mod, reg;
     uint32_t ftmClock = (srcClock_Hz / (1U << (base->SC & FTM_SC_PS_MASK)));
@@ -373,7 +373,7 @@
             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));
+            reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
 
             /* Edge-aligned mode needs MSB to be 1, don't care for Center-aligned mode */
             reg |= FTM_CnSC_MSB(1U);
@@ -397,6 +397,10 @@
             }
 
             base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
+#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
         }
         else
         {
@@ -445,7 +449,7 @@
             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));
+            reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
 
             /* Update the mode and edge level for channel n */
             base->CONTROLS[chnlParams->chnlNumber * 2].CnSC = reg;
@@ -455,25 +459,25 @@
             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));
+            reg |= (uint32_t)(chnlParams->level << FTM_CnSC_ELSA_SHIFT);
 
             /* Update the mode and edge level for channel n + 1*/
             base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC = reg;
 
+            /* Set the combine bit for the channel pair */
+            base->COMBINE |=
+                (1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlParams->chnlNumber)));
+
             /* 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, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2), true);
+            FTM_SetPwmOutputEnable(base, (ftm_chnl_t)((uint8_t)chnlParams->chnlNumber * 2 + 1), true);
+#endif
         }
-
-#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++;
     }
 
@@ -535,6 +539,13 @@
 {
     uint32_t reg;
 
+    /* Clear the combine bit for the channel pair */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the dual edge capture mode because it's it's higher priority */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the quadrature decoder mode beacause it's higher priority */
+    base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
+
     reg = base->CONTROLS[chnlNumber].CnSC;
     reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
     reg |= captureMode;
@@ -562,8 +573,12 @@
 {
     uint32_t reg;
 
-    /* Set output on match to the requested level */
-    base->CONTROLS[chnlNumber].CnV = compareValue;
+    /* Clear the combine bit for the channel pair */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the dual edge capture mode because it's it's higher priority */
+    base->COMBINE &= ~(1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * (chnlNumber >> 1))));
+    /* Clear the quadrature decoder mode beacause it's higher priority */
+    base->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
 
     reg = base->CONTROLS[chnlNumber].CnSC;
     reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
@@ -571,6 +586,9 @@
     /* Setup the channel output behaviour when a match occurs with the compare value */
     base->CONTROLS[chnlNumber].CnSC = reg;
 
+    /* Set output on match to the requested level */
+    base->CONTROLS[chnlNumber].CnV = compareValue;
+
 #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);
@@ -662,6 +680,8 @@
 
 void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams)
 {
+    assert(faultParams);
+
     uint32_t reg;
 
     reg = base->FLTCTRL;
--- a/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/drivers/fsl_ftm.h	Tue May 17 14:45:12 2016 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/drivers/fsl_ftm.h	Sun May 22 17:00:12 2016 +0100
@@ -33,7 +33,7 @@
 #include "fsl_common.h"
 
 /*!
- * @addtogroup ftm_driver
+ * @addtogroup ftm
  * @{
  */
 
@@ -162,7 +162,7 @@
 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;
+    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 */
--- a/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_tpm.c	Tue May 17 14:45:12 2016 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_tpm.c	Sun May 22 17:00:12 2016 +0100
@@ -94,9 +94,9 @@
     base->SC = TPM_SC_PS(config->prescale);
 
     /* Setup the counter operation */
-    base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_DBGMODE(config->enableDebugMode) |
-                 TPM_CONF_GTBEEN(config->useGlobalTimeBase) | TPM_CONF_CROT(config->enableReloadOnTrigger) |
-                 TPM_CONF_CSOT(config->enableStartOnTrigger) | TPM_CONF_CSOO(config->enableStopOnOverflow) |
+    base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_GTBEEN(config->useGlobalTimeBase) |
+                 TPM_CONF_CROT(config->enableReloadOnTrigger) | TPM_CONF_CSOT(config->enableStartOnTrigger) |
+                 TPM_CONF_CSOO(config->enableStopOnOverflow) |
 #if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
                  TPM_CONF_CPOT(config->enablePauseOnTrigger) |
 #endif
@@ -104,6 +104,14 @@
                  TPM_CONF_TRGSRC(config->triggerSource) |
 #endif
                  TPM_CONF_TRGSEL(config->triggerSelect);
+    if (config->enableDebugMode)
+    {
+        base->CONF |= TPM_CONF_DBGMODE_MASK;
+    }
+    else
+    {
+        base->CONF &= ~TPM_CONF_DBGMODE_MASK;
+    }
 }
 
 void TPM_Deinit(TPM_Type *base)
@@ -151,12 +159,20 @@
                       uint32_t srcClock_Hz)
 {
     assert(chnlParams);
+    assert(pwmFreq_Hz);
+    assert(numOfChnls);
+    assert(srcClock_Hz);
 
     uint32_t mod;
     uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK)));
     uint16_t cnv;
     uint8_t i;
 
+#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
+    /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/
+    base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
+#endif
+
     switch (mode)
     {
         case kTPM_EdgeAlignedPwm:
@@ -233,9 +249,6 @@
                     cnv = mod + 1;
                 }
             }
-            /* 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 << (TPM_COMBINE_COMBINE0_SHIFT + (TPM_COMBINE_SHIFT * chnlParams->chnlNumber)));
@@ -244,6 +257,12 @@
             base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &=
                 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
 
+            /* Wait till mode change to disable channel is acknowledged */
+            while ((base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &
+                    (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+            {
+            }
+
             /* Set the requested PWM mode for channel n, PWM output requires mode select to be set to 2 */
             base->CONTROLS[chnlParams->chnlNumber * 2].CnSC |=
                 ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
@@ -253,11 +272,19 @@
                      (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
             {
             }
+            /* Set the channel pair values */
+            base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge;
 
             /* When switching mode, disable channel n + 1 first */
             base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &=
                 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
 
+            /* Wait till mode change to disable channel is acknowledged */
+            while ((base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &
+                    (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+            {
+            }
+
             /* Set the requested PWM mode for channel n + 1, PWM output requires mode select to be set to 2 */
             base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC |=
                 ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
@@ -267,6 +294,8 @@
                      (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
             {
             }
+            /* Set the channel pair values */
+            base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
         }
         else
         {
@@ -286,12 +315,16 @@
                 }
             }
 
-            base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
-
             /* When switching mode, disable channel first */
             base->CONTROLS[chnlParams->chnlNumber].CnSC &=
                 ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
 
+            /* Wait till mode change to disable channel is acknowledged */
+            while ((base->CONTROLS[chnlParams->chnlNumber].CnSC &
+                    (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+            {
+            }
+
             /* Set the requested PWM mode, PWM output requires mode select to be set to 2 */
             base->CONTROLS[chnlParams->chnlNumber].CnSC |=
                 ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
@@ -301,6 +334,7 @@
                      (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
             {
             }
+            base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
 #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
         }
 #endif
@@ -364,9 +398,10 @@
     /* When switching mode, disable channel first  */
     base->CONTROLS[chnlNumber].CnSC &=
         ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
-    /* Wait till mode change is acknowledged */
-    while (0U != (base->CONTROLS[chnlNumber].CnSC &
-                  (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[chnlNumber].CnSC &
+            (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
     {
     }
 
@@ -388,10 +423,29 @@
 {
     assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
 
+#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
+    /* Clear quadrature Decoder mode for channel 0 or 1*/
+    if ((chnlNumber == 0) || (chnlNumber == 1))
+    {
+        base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
+    }
+#endif
+
+#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
+    /* Clear the combine bit for chnlNumber */
+    base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2));
+#endif
+
     /* When switching mode, disable channel first  */
     base->CONTROLS[chnlNumber].CnSC &=
         ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
 
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[chnlNumber].CnSC &
+            (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+    {
+    }
+
     /* Set the requested input capture mode */
     base->CONTROLS[chnlNumber].CnSC |= captureMode;
 
@@ -409,16 +463,30 @@
 {
     assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
 
-    /* Setup the compare value */
-    base->CONTROLS[chnlNumber].CnV = compareValue;
+#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
+    /* Clear quadrature Decoder mode for channel 0 or 1 */
+    if ((chnlNumber == 0) || (chnlNumber == 1))
+    {
+        base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
+    }
+#endif
 
     /* When switching mode, disable channel first  */
     base->CONTROLS[chnlNumber].CnSC &=
         ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
 
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[chnlNumber].CnSC &
+            (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+    {
+    }
+
     /* Setup the channel output behaviour when a match occurs with the compare value */
     base->CONTROLS[chnlNumber].CnSC |= compareMode;
 
+    /* Setup the compare value */
+    base->CONTROLS[chnlNumber].CnV = compareValue;
+
     /* Wait till mode change is acknowledged */
     while (!(base->CONTROLS[chnlNumber].CnSC &
              (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
@@ -433,26 +501,37 @@
                               uint32_t filterValue)
 {
     assert(edgeParam);
+    assert(chnlPairNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2);
 
     uint32_t reg;
+/* Clear quadrature Decoder mode for channel 0 or 1*/
+#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
+    if (chnlPairNumber == 0)
+    {
+        base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
+    }
+#endif
 
     /* Unlock: When switching mode, disable channel first */
     base->CONTROLS[chnlPairNumber * 2].CnSC &=
         ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
-    /* Wait till mode change is acknowledged */
-    while (0U != (base->CONTROLS[chnlPairNumber * 2].CnSC &
-                  (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[chnlPairNumber * 2].CnSC &
+            (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
     {
     }
+
     base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &=
         ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
-    /* Wait till mode change is acknowledged */
-    while (0U != (base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &
-                  (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &
+            (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
     {
     }
+
     /* Now, the registers for input mode can be operated. */
-
     if (edgeParam->enableSwap)
     {
         /* Set the combine and swap bits for the channel pair */
@@ -484,6 +563,7 @@
 
     /* Setup the edge detection from channel n */
     base->CONTROLS[chnlPairNumber * 2].CnSC |= edgeParam->currChanEdgeMode;
+
     /* Wait till mode change is acknowledged */
     while (!(base->CONTROLS[chnlPairNumber * 2].CnSC &
              (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
@@ -492,6 +572,7 @@
 
     /* Setup the edge detection from channel n+1 */
     base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC |= edgeParam->nextChanEdgeMode;
+
     /* Wait till mode change is acknowledged */
     while (!(base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC &
              (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
@@ -509,6 +590,12 @@
     assert(phaseAParams);
     assert(phaseBParams);
 
+    base->CONTROLS[0].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
+
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[0].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+    {
+    }
     uint32_t reg;
 
     /* Set Phase A filter value */
@@ -517,6 +604,7 @@
     reg |= TPM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal);
     base->FILTER = reg;
 
+#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL
     /* Set Phase A polarity */
     if (phaseAParams->phasePolarity)
     {
@@ -526,13 +614,20 @@
     {
         base->POL &= ~TPM_POL_POL0_MASK;
     }
+#endif
 
+    base->CONTROLS[1].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
+
+    /* Wait till mode change to disable channel is acknowledged */
+    while ((base->CONTROLS[1].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
+    {
+    }
     /* Set Phase B filter value */
     reg = base->FILTER;
     reg &= ~(TPM_FILTER_CH1FVAL_MASK);
     reg |= TPM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal);
     base->FILTER = reg;
-
+#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL
     /* Set Phase B polarity */
     if (phaseBParams->phasePolarity)
     {
@@ -542,6 +637,7 @@
     {
         base->POL &= ~TPM_POL_POL1_MASK;
     }
+#endif
 
     /* Set Quadrature mode */
     reg = base->QDCTRL;
@@ -627,30 +723,3 @@
 
     return enabledInterrupts;
 }
-
-uint32_t TPM_GetStatusFlags(TPM_Type *base)
-{
-    uint32_t statusFlags = 0;
-
-    /* Check timer flag */
-    if (base->SC & TPM_SC_TOF_MASK)
-    {
-        statusFlags |= kTPM_TimeOverflowFlag;
-    }
-
-    statusFlags |= base->STATUS;
-
-    return statusFlags;
-}
-
-void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask)
-{
-    /* Clear the timer overflow flag */
-    if (mask & kTPM_TimeOverflowFlag)
-    {
-        base->SC |= TPM_SC_TOF_MASK;
-    }
-
-    /* Clear the channel status flags */
-    base->STATUS = (mask & 0xFF);
-}
--- a/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_tpm.h	Tue May 17 14:45:12 2016 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_tpm.h	Sun May 22 17:00:12 2016 +0100
@@ -33,7 +33,7 @@
 #include "fsl_common.h"
 
 /*!
- * @addtogroup tpm_driver
+ * @addtogroup tpm
  * @{
  */
 
@@ -45,7 +45,7 @@
 
 /*! @name Driver version */
 /*@{*/
-#define FSL_TPM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1 */
+#define FSL_TPM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
 /*@}*/
 
 /*!
@@ -505,7 +505,10 @@
  * @return The status flags. This is the logical OR of members of the
  *         enumeration ::tpm_status_flags_t
  */
-uint32_t TPM_GetStatusFlags(TPM_Type *base);
+static inline uint32_t TPM_GetStatusFlags(TPM_Type *base)
+{
+    return base->STATUS;
+}
 
 /*!
  * @brief Clears the TPM status flags
@@ -514,7 +517,11 @@
  * @param mask The status flags to clear. This is a logical OR of members of the
  *             enumeration ::tpm_status_flags_t
  */
-void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask);
+static inline void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask)
+{
+    /* Clear the status flags */
+    base->STATUS = mask;
+}
 
 /*! @}*/
 
@@ -548,6 +555,11 @@
 {
     /* Set clock source to none to disable counter */
     base->SC &= ~(TPM_SC_CMOD_MASK);
+
+    /* Wait till this reads as zero acknowledging the counter is disabled */
+    while (base->SC & TPM_SC_CMOD_MASK)
+    {
+    }
 }
 
 /*! @}*/