1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of the copyright holder nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifndef _FSL_FTM_H_
31 #define _FSL_FTM_H_
32 
33 #include "fsl_common.h"
34 
35 /*!
36  * @addtogroup ftm
37  * @{
38  */
39 
40 
41 /*******************************************************************************
42  * Definitions
43  ******************************************************************************/
44 
45 /*! @name Driver version */
46 /*@{*/
47 #define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
48                                                        /*@}*/
49 
50 /*!
51  * @brief List of FTM channels
52  * @note Actual number of available channels is SoC dependent
53  */
54 typedef enum _ftm_chnl
55 {
56     kFTM_Chnl_0 = 0U, /*!< FTM channel number 0*/
57     kFTM_Chnl_1,      /*!< FTM channel number 1 */
58     kFTM_Chnl_2,      /*!< FTM channel number 2 */
59     kFTM_Chnl_3,      /*!< FTM channel number 3 */
60     kFTM_Chnl_4,      /*!< FTM channel number 4 */
61     kFTM_Chnl_5,      /*!< FTM channel number 5 */
62     kFTM_Chnl_6,      /*!< FTM channel number 6 */
63     kFTM_Chnl_7       /*!< FTM channel number 7 */
64 } ftm_chnl_t;
65 
66 /*! @brief List of FTM faults */
67 typedef enum _ftm_fault_input
68 {
69     kFTM_Fault_0 = 0U, /*!< FTM fault 0 input pin */
70     kFTM_Fault_1,      /*!< FTM fault 1 input pin */
71     kFTM_Fault_2,      /*!< FTM fault 2 input pin */
72     kFTM_Fault_3       /*!< FTM fault 3 input pin */
73 } ftm_fault_input_t;
74 
75 /*! @brief FTM PWM operation modes */
76 typedef enum _ftm_pwm_mode
77 {
78     kFTM_EdgeAlignedPwm = 0U, /*!< Edge-aligned PWM */
79     kFTM_CenterAlignedPwm,    /*!< Center-aligned PWM */
80     kFTM_CombinedPwm          /*!< Combined PWM */
81 } ftm_pwm_mode_t;
82 
83 /*! @brief FTM PWM output pulse mode: high-true, low-true or no output */
84 typedef enum _ftm_pwm_level_select
85 {
86     kFTM_NoPwmSignal = 0U, /*!< No PWM output on pin */
87     kFTM_LowTrue,          /*!< Low true pulses */
88     kFTM_HighTrue          /*!< High true pulses */
89 } ftm_pwm_level_select_t;
90 
91 /*! @brief Options to configure a FTM channel's PWM signal */
92 typedef struct _ftm_chnl_pwm_signal_param
93 {
94     ftm_chnl_t chnlNumber;         /*!< The channel/channel pair number.
95                                         In combined mode, this represents the channel pair number. */
96     ftm_pwm_level_select_t level;  /*!< PWM output active level select. */
97     uint8_t dutyCyclePercent;      /*!< PWM pulse width, value should be between 0 to 100
98                                         0 = inactive signal(0% duty cycle)...
99                                         100 = always active signal (100% duty cycle).*/
100     uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to generate an asymmetrical PWM.
101                                         Specifies the delay to the first edge in a PWM period.
102                                         If unsure leave as 0; Should be specified as a
103                                         percentage of the PWM period */
104 } ftm_chnl_pwm_signal_param_t;
105 
106 /*! @brief FlexTimer output compare mode */
107 typedef enum _ftm_output_compare_mode
108 {
109     kFTM_NoOutputSignal = (1U << FTM_CnSC_MSA_SHIFT), /*!< No channel output when counter reaches CnV  */
110     kFTM_ToggleOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (1U << FTM_CnSC_ELSA_SHIFT)), /*!< Toggle output */
111     kFTM_ClearOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (2U << FTM_CnSC_ELSA_SHIFT)),  /*!< Clear output */
112     kFTM_SetOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (3U << FTM_CnSC_ELSA_SHIFT))     /*!< Set output */
113 } ftm_output_compare_mode_t;
114 
115 /*! @brief FlexTimer input capture edge */
116 typedef enum _ftm_input_capture_edge
117 {
118     kFTM_RisingEdge = (1U << FTM_CnSC_ELSA_SHIFT),     /*!< Capture on rising edge only*/
119     kFTM_FallingEdge = (2U << FTM_CnSC_ELSA_SHIFT),    /*!< Capture on falling edge only*/
120     kFTM_RiseAndFallEdge = (3U << FTM_CnSC_ELSA_SHIFT) /*!< Capture on rising or falling edge */
121 } ftm_input_capture_edge_t;
122 
123 /*! @brief FlexTimer dual edge capture modes */
124 typedef enum _ftm_dual_edge_capture_mode
125 {
126     kFTM_OneShot = 0U,                           /*!< One-shot capture mode */
127     kFTM_Continuous = (1U << FTM_CnSC_MSA_SHIFT) /*!< Continuous capture mode */
128 } ftm_dual_edge_capture_mode_t;
129 
130 /*! @brief FlexTimer dual edge capture parameters */
131 typedef struct _ftm_dual_edge_capture_param
132 {
133     ftm_dual_edge_capture_mode_t mode;         /*!< Dual Edge Capture mode */
134     ftm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select for channel n */
135     ftm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select for channel n+1 */
136 } ftm_dual_edge_capture_param_t;
137 
138 /*! @brief FlexTimer quadrature decode modes */
139 typedef enum _ftm_quad_decode_mode
140 {
141     kFTM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */
142     kFTM_QuadCountAndDir       /*!< Count and direction encoding mode */
143 } ftm_quad_decode_mode_t;
144 
145 /*! @brief FlexTimer quadrature phase polarities */
146 typedef enum _ftm_phase_polarity
147 {
148     kFTM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */
149     kFTM_QuadPhaseInvert       /*!< Phase input signal is inverted */
150 } ftm_phase_polarity_t;
151 
152 /*! @brief FlexTimer quadrature decode phase parameters */
153 typedef struct _ftm_phase_param
154 {
155     bool enablePhaseFilter;             /*!< True: enable phase filter; false: disable filter */
156     uint32_t phaseFilterVal;            /*!< Filter value, used only if phase filter is enabled */
157     ftm_phase_polarity_t phasePolarity; /*!< Phase polarity */
158 } ftm_phase_params_t;
159 
160 /*! @brief Structure is used to hold the parameters to configure a FTM fault */
161 typedef struct _ftm_fault_param
162 {
163     bool enableFaultInput; /*!< True: Fault input is enabled; false: Fault input is disabled */
164     bool faultLevel;       /*!< True: Fault polarity is active low; in other words, '0' indicates a fault;
165                                 False: Fault polarity is active high */
166     bool useFaultFilter;   /*!< True: Use the filtered fault signal;
167                                 False: Use the direct path from fault input */
168 } ftm_fault_param_t;
169 
170 /*! @brief FlexTimer pre-scaler factor for the dead time insertion*/
171 typedef enum _ftm_deadtime_prescale
172 {
173     kFTM_Deadtime_Prescale_1 = 1U, /*!< Divide by 1 */
174     kFTM_Deadtime_Prescale_4,      /*!< Divide by 4 */
175     kFTM_Deadtime_Prescale_16      /*!< Divide by 16 */
176 } ftm_deadtime_prescale_t;
177 
178 /*! @brief FlexTimer clock source selection*/
179 typedef enum _ftm_clock_source
180 {
181     kFTM_SystemClock = 1U, /*!< System clock selected */
182     kFTM_FixedClock,       /*!< Fixed frequency clock */
183     kFTM_ExternalClock     /*!< External clock */
184 } ftm_clock_source_t;
185 
186 /*! @brief FlexTimer pre-scaler factor selection for the clock source*/
187 typedef enum _ftm_clock_prescale
188 {
189     kFTM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */
190     kFTM_Prescale_Divide_2,      /*!< Divide by 2 */
191     kFTM_Prescale_Divide_4,      /*!< Divide by 4 */
192     kFTM_Prescale_Divide_8,      /*!< Divide by 8 */
193     kFTM_Prescale_Divide_16,     /*!< Divide by 16 */
194     kFTM_Prescale_Divide_32,     /*!< Divide by 32 */
195     kFTM_Prescale_Divide_64,     /*!< Divide by 64 */
196     kFTM_Prescale_Divide_128     /*!< Divide by 128 */
197 } ftm_clock_prescale_t;
198 
199 /*! @brief Options for the FlexTimer behaviour in BDM Mode */
200 typedef enum _ftm_bdm_mode
201 {
202     kFTM_BdmMode_0 = 0U,
203     /*!< FTM counter stopped, CH(n)F bit can be set, FTM channels in functional mode, writes to MOD,CNTIN and C(n)V
204        registers bypass the register buffers */
205     kFTM_BdmMode_1,
206     /*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are forced to their safe value , writes to
207        MOD,CNTIN and C(n)V registers bypass the register buffers */
208     kFTM_BdmMode_2,
209     /*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are frozen when chip enters in BDM mode,
210        writes to MOD,CNTIN and C(n)V registers bypass the register buffers */
211     kFTM_BdmMode_3
212     /*!< FTM counter in functional mode, CH(n)F bit can be set, FTM channels in functional mode, writes to MOD,CNTIN and
213        C(n)V registers is in fully functional mode */
214 } ftm_bdm_mode_t;
215 
216 /*! @brief Options for the FTM fault control mode */
217 typedef enum _ftm_fault_mode
218 {
219     kFTM_Fault_Disable = 0U, /*!< Fault control is disabled for all channels */
220     kFTM_Fault_EvenChnls,    /*!< Enabled for even channels only(0,2,4,6) with manual fault clearing */
221     kFTM_Fault_AllChnlsMan,  /*!< Enabled for all channels with manual fault clearing */
222     kFTM_Fault_AllChnlsAuto  /*!< Enabled for all channels with automatic fault clearing */
223 } ftm_fault_mode_t;
224 
225 /*!
226  * @brief FTM external trigger options
227  * @note Actual available external trigger sources are SoC-specific
228  */
229 typedef enum _ftm_external_trigger
230 {
231     kFTM_Chnl0Trigger = (1U << 4), /*!< Generate trigger when counter equals chnl 0 CnV reg */
232     kFTM_Chnl1Trigger = (1U << 5), /*!< Generate trigger when counter equals chnl 1 CnV reg */
233     kFTM_Chnl2Trigger = (1U << 0), /*!< Generate trigger when counter equals chnl 2 CnV reg */
234     kFTM_Chnl3Trigger = (1U << 1), /*!< Generate trigger when counter equals chnl 3 CnV reg */
235     kFTM_Chnl4Trigger = (1U << 2), /*!< Generate trigger when counter equals chnl 4 CnV reg */
236     kFTM_Chnl5Trigger = (1U << 3), /*!< Generate trigger when counter equals chnl 5 CnV reg */
237     kFTM_Chnl6Trigger =
238         (1U << 8), /*!< Available on certain SoC's, generate trigger when counter equals chnl 6 CnV reg */
239     kFTM_Chnl7Trigger =
240         (1U << 9), /*!< Available on certain SoC's, generate trigger when counter equals chnl 7 CnV reg */
241     kFTM_InitTrigger = (1U << 6),      /*!< Generate Trigger when counter is updated with CNTIN */
242     kFTM_ReloadInitTrigger = (1U << 7) /*!< Available on certain SoC's, trigger on reload point */
243 } ftm_external_trigger_t;
244 
245 /*! @brief FlexTimer PWM sync options to update registers with buffer */
246 typedef enum _ftm_pwm_sync_method
247 {
248     kFTM_SoftwareTrigger = FTM_SYNC_SWSYNC_MASK,  /*!< Software triggers PWM sync */
249     kFTM_HardwareTrigger_0 = FTM_SYNC_TRIG0_MASK, /*!< Hardware trigger 0 causes PWM sync */
250     kFTM_HardwareTrigger_1 = FTM_SYNC_TRIG1_MASK, /*!< Hardware trigger 1 causes PWM sync */
251     kFTM_HardwareTrigger_2 = FTM_SYNC_TRIG2_MASK  /*!< Hardware trigger 2 causes PWM sync */
252 } ftm_pwm_sync_method_t;
253 
254 /*!
255  * @brief FTM options available as loading point for register reload
256  * @note Actual available reload points are SoC-specific
257  */
258 typedef enum _ftm_reload_point
259 {
260     kFTM_Chnl0Match = (1U << 0),   /*!< Channel 0 match included as a reload point */
261     kFTM_Chnl1Match = (1U << 1),   /*!< Channel 1 match included as a reload point */
262     kFTM_Chnl2Match = (1U << 2),   /*!< Channel 2 match included as a reload point */
263     kFTM_Chnl3Match = (1U << 3),   /*!< Channel 3 match included as a reload point */
264     kFTM_Chnl4Match = (1U << 4),   /*!< Channel 4 match included as a reload point */
265     kFTM_Chnl5Match = (1U << 5),   /*!< Channel 5 match included as a reload point */
266     kFTM_Chnl6Match = (1U << 6),   /*!< Channel 6 match included as a reload point */
267     kFTM_Chnl7Match = (1U << 7),   /*!< Channel 7 match included as a reload point */
268     kFTM_CntMax = (1U << 8),       /*!< Use in up-down count mode only, reload when counter reaches the maximum value */
269     kFTM_CntMin = (1U << 9),       /*!< Use in up-down count mode only, reload when counter reaches the minimum value */
270     kFTM_HalfCycMatch = (1U << 10) /*!< Available on certain SoC's, half cycle match reload point */
271 } ftm_reload_point_t;
272 
273 /*!
274  * @brief List of FTM interrupts
275  * @note Actual available interrupts are SoC-specific
276  */
277 typedef enum _ftm_interrupt_enable
278 {
279     kFTM_Chnl0InterruptEnable = (1U << 0),        /*!< Channel 0 interrupt */
280     kFTM_Chnl1InterruptEnable = (1U << 1),        /*!< Channel 1 interrupt */
281     kFTM_Chnl2InterruptEnable = (1U << 2),        /*!< Channel 2 interrupt */
282     kFTM_Chnl3InterruptEnable = (1U << 3),        /*!< Channel 3 interrupt */
283     kFTM_Chnl4InterruptEnable = (1U << 4),        /*!< Channel 4 interrupt */
284     kFTM_Chnl5InterruptEnable = (1U << 5),        /*!< Channel 5 interrupt */
285     kFTM_Chnl6InterruptEnable = (1U << 6),        /*!< Channel 6 interrupt */
286     kFTM_Chnl7InterruptEnable = (1U << 7),        /*!< Channel 7 interrupt */
287     kFTM_FaultInterruptEnable = (1U << 8),        /*!< Fault interrupt */
288     kFTM_TimeOverflowInterruptEnable = (1U << 9), /*!< Time overflow interrupt */
289     kFTM_ReloadInterruptEnable = (1U << 10)       /*!< Reload interrupt; Available only on certain SoC's */
290 } ftm_interrupt_enable_t;
291 
292 /*!
293  * @brief List of FTM flags
294  * @note Actual available flags are SoC-specific
295  */
296 typedef enum _ftm_status_flags
297 {
298     kFTM_Chnl0Flag = (1U << 0),        /*!< Channel 0 Flag */
299     kFTM_Chnl1Flag = (1U << 1),        /*!< Channel 1 Flag */
300     kFTM_Chnl2Flag = (1U << 2),        /*!< Channel 2 Flag */
301     kFTM_Chnl3Flag = (1U << 3),        /*!< Channel 3 Flag */
302     kFTM_Chnl4Flag = (1U << 4),        /*!< Channel 4 Flag */
303     kFTM_Chnl5Flag = (1U << 5),        /*!< Channel 5 Flag */
304     kFTM_Chnl6Flag = (1U << 6),        /*!< Channel 6 Flag */
305     kFTM_Chnl7Flag = (1U << 7),        /*!< Channel 7 Flag */
306     kFTM_FaultFlag = (1U << 8),        /*!< Fault Flag */
307     kFTM_TimeOverflowFlag = (1U << 9), /*!< Time overflow Flag */
308     kFTM_ChnlTriggerFlag = (1U << 10), /*!< Channel trigger Flag */
309     kFTM_ReloadFlag = (1U << 11)       /*!< Reload Flag; Available only on certain SoC's */
310 } ftm_status_flags_t;
311 
312 /*!
313  * @brief List of FTM Quad Decoder flags.
314  */
315 enum _ftm_quad_decoder_flags
316 {
317     kFTM_QuadDecoderCountingIncreaseFlag = FTM_QDCTRL_QUADIR_MASK, /*!< Counting direction is increasing (FTM counter
318                                                                         increment), or the direction is decreasing. */
319     kFTM_QuadDecoderCountingOverflowOnTopFlag = FTM_QDCTRL_TOFDIR_MASK, /*!< Indicates if the TOF bit was set on the top
320                                                                              or the bottom of counting. */
321 };
322 
323 /*!
324  * @brief FTM configuration structure
325  *
326  * This structure holds the configuration settings for the FTM peripheral. To initialize this
327  * structure to reasonable defaults, call the FTM_GetDefaultConfig() function and pass a
328  * pointer to the configuration structure instance.
329  *
330  * The configuration structure can be made constant so as to reside in flash.
331  */
332 typedef struct _ftm_config
333 {
334     ftm_clock_prescale_t prescale;            /*!< FTM clock prescale value */
335     ftm_bdm_mode_t bdmMode;                   /*!< FTM behavior in BDM mode */
336     uint32_t pwmSyncMode;                     /*!< Synchronization methods to use to update buffered registers; Multiple
337                                                    update modes can be used by providing an OR'ed list of options
338                                                    available in enumeration ::ftm_pwm_sync_method_t. */
339     uint32_t reloadPoints;                    /*!< FTM reload points; When using this, the PWM
340                                                    synchronization is not required. Multiple reload points can be used by providing
341                                                    an OR'ed list of options available in
342                                                    enumeration ::ftm_reload_point_t. */
343     ftm_fault_mode_t faultMode;               /*!< FTM fault control mode */
344     uint8_t faultFilterValue;                 /*!< Fault input filter value */
345     ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar value */
346     uint32_t deadTimeValue;                   /*!< The dead time value
347                                                    deadTimeValue's available range is 0-1023 when register has DTVALEX,
348                                                    otherwise its available range is 0-63. */
349     uint32_t extTriggers;                     /*!< External triggers to enable. Multiple trigger sources can be
350                                                    enabled by providing an OR'ed list of options available in
351                                                    enumeration ::ftm_external_trigger_t. */
352     uint8_t chnlInitState;  /*!< Defines the initialization value of the channels in OUTINT register */
353     uint8_t chnlPolarity;   /*!< Defines the output polarity of the channels in POL register */
354     bool useGlobalTimeBase; /*!< True: Use of an external global time base is enabled;
355                                  False: disabled */
356 } ftm_config_t;
357 
358 /*******************************************************************************
359  * API
360  ******************************************************************************/
361 
362 #if defined(__cplusplus)
363 extern "C" {
364 #endif
365 
366 /*!
367  * @name Initialization and deinitialization
368  * @{
369  */
370 
371 /*!
372  * @brief Ungates the FTM clock and configures the peripheral for basic operation.
373  *
374  * @note This API should be called at the beginning of the application which is using the FTM driver.
375  *
376  * @param base   FTM peripheral base address
377  * @param config Pointer to the user configuration structure.
378  *
379  * @return kStatus_Success indicates success; Else indicates failure.
380  */
381 status_t FTM_Init(FTM_Type *base, const ftm_config_t *config);
382 
383 /*!
384  * @brief Gates the FTM clock.
385  *
386  * @param base FTM peripheral base address
387  */
388 void FTM_Deinit(FTM_Type *base);
389 
390 /*!
391  * @brief  Fills in the FTM configuration structure with the default settings.
392  *
393  * The default values are:
394  * @code
395  *   config->prescale = kFTM_Prescale_Divide_1;
396  *   config->bdmMode = kFTM_BdmMode_0;
397  *   config->pwmSyncMode = kFTM_SoftwareTrigger;
398  *   config->reloadPoints = 0;
399  *   config->faultMode = kFTM_Fault_Disable;
400  *   config->faultFilterValue = 0;
401  *   config->deadTimePrescale = kFTM_Deadtime_Prescale_1;
402  *   config->deadTimeValue =  0;
403  *   config->extTriggers = 0;
404  *   config->chnlInitState = 0;
405  *   config->chnlPolarity = 0;
406  *   config->useGlobalTimeBase = false;
407  * @endcode
408  * @param config Pointer to the user configuration structure.
409  */
410 void FTM_GetDefaultConfig(ftm_config_t *config);
411 
412 /*! @}*/
413 
414 /*!
415  * @name Channel mode operations
416  * @{
417  */
418 
419 /*!
420  * @brief Configures the PWM signal parameters.
421  *
422  * Call this function to configure the PWM signal period, mode, duty cycle, and edge. Use this
423  * function to configure all FTM channels that are used to output a PWM signal.
424  *
425  * @param base        FTM peripheral base address
426  * @param chnlParams  Array of PWM channel parameters to configure the channel(s)
427  * @param numOfChnls  Number of channels to configure; This should be the size of the array passed in
428  * @param mode        PWM operation mode, options available in enumeration ::ftm_pwm_mode_t
429  * @param pwmFreq_Hz  PWM signal frequency in Hz
430  * @param srcClock_Hz FTM counter clock in Hz
431  *
432  * @return kStatus_Success if the PWM setup was successful
433  *         kStatus_Error on failure
434  */
435 status_t FTM_SetupPwm(FTM_Type *base,
436                       const ftm_chnl_pwm_signal_param_t *chnlParams,
437                       uint8_t numOfChnls,
438                       ftm_pwm_mode_t mode,
439                       uint32_t pwmFreq_Hz,
440                       uint32_t srcClock_Hz);
441 
442 /*!
443  * @brief Updates the duty cycle of an active PWM signal.
444  *
445  * @param base              FTM peripheral base address
446  * @param chnlNumber        The channel/channel pair number. In combined mode, this represents
447  *                          the channel pair number
448  * @param currentPwmMode    The current PWM mode set during PWM setup
449  * @param dutyCyclePercent  New PWM pulse width; The value should be between 0 to 100
450  *                          0=inactive signal(0% duty cycle)...
451  *                          100=active signal (100% duty cycle)
452  */
453 void FTM_UpdatePwmDutycycle(FTM_Type *base,
454                             ftm_chnl_t chnlNumber,
455                             ftm_pwm_mode_t currentPwmMode,
456                             uint8_t dutyCyclePercent);
457 
458 /*!
459  * @brief Updates the edge level selection for a channel.
460  *
461  * @param base       FTM peripheral base address
462  * @param chnlNumber The channel number
463  * @param level      The level to be set to the ELSnB:ELSnA field; Valid values are 00, 01, 10, 11.
464  *                   See the Kinetis SoC reference manual for details about this field.
465  */
466 void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, uint8_t level);
467 
468 /*!
469  * @brief Enables capturing an input signal on the channel using the function parameters.
470  *
471  * When the edge specified in the captureMode argument occurs on the channel, the FTM counter is
472  * captured into the CnV register. The user has to read the CnV register separately to get this
473  * value. The filter function is disabled if the filterVal argument passed in is 0. The filter
474  * function is available only for channels 0, 1, 2, 3.
475  *
476  * @param base        FTM peripheral base address
477  * @param chnlNumber  The channel number
478  * @param captureMode Specifies which edge to capture
479  * @param filterValue Filter value, specify 0 to disable filter. Available only for channels 0-3.
480  */
481 void FTM_SetupInputCapture(FTM_Type *base,
482                            ftm_chnl_t chnlNumber,
483                            ftm_input_capture_edge_t captureMode,
484                            uint32_t filterValue);
485 
486 /*!
487  * @brief Configures the FTM to generate timed pulses.
488  *
489  * When the FTM counter matches the value of compareVal argument (this is written into CnV reg),
490  * the channel output is changed based on what is specified in the compareMode argument.
491  *
492  * @param base         FTM peripheral base address
493  * @param chnlNumber   The channel number
494  * @param compareMode  Action to take on the channel output when the compare condition is met
495  * @param compareValue Value to be programmed in the CnV register.
496  */
497 void FTM_SetupOutputCompare(FTM_Type *base,
498                             ftm_chnl_t chnlNumber,
499                             ftm_output_compare_mode_t compareMode,
500                             uint32_t compareValue);
501 
502 /*!
503  * @brief Configures the dual edge capture mode of the FTM.
504  *
505  * This function sets up the dual edge capture mode on a channel pair. The capture edge for the
506  * channel pair and the capture mode (one-shot or continuous) is specified in the parameter
507  * argument. The filter function is disabled if the filterVal argument passed is zero. The filter
508  * function is available only on channels 0 and 2. The user has to read the channel CnV registers
509  * separately to get the capture values.
510  *
511  * @param base           FTM peripheral base address
512  * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
513  * @param edgeParam      Sets up the dual edge capture function
514  * @param filterValue    Filter value, specify 0 to disable filter. Available only for channel pair 0 and 1.
515  */
516 void FTM_SetupDualEdgeCapture(FTM_Type *base,
517                               ftm_chnl_t chnlPairNumber,
518                               const ftm_dual_edge_capture_param_t *edgeParam,
519                               uint32_t filterValue);
520 
521 /*! @}*/
522 
523 /*!
524  * @brief Sets up the working of the FTM fault protection.
525  *
526  * FTM can have up to 4 fault inputs. This function sets up fault parameters, fault level, and a filter.
527  *
528  * @param base        FTM peripheral base address
529  * @param faultNumber FTM fault to configure.
530  * @param faultParams Parameters passed in to set up the fault
531  */
532 void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams);
533 
534 /*!
535  * @name Interrupt Interface
536  * @{
537  */
538 
539 /*!
540  * @brief Enables the selected FTM interrupts.
541  *
542  * @param base FTM peripheral base address
543  * @param mask The interrupts to enable. This is a logical OR of members of the
544  *             enumeration ::ftm_interrupt_enable_t
545  */
546 void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask);
547 
548 /*!
549  * @brief Disables the selected FTM interrupts.
550  *
551  * @param base FTM peripheral base address
552  * @param mask The interrupts to enable. This is a logical OR of members of the
553  *             enumeration ::ftm_interrupt_enable_t
554  */
555 void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask);
556 
557 /*!
558  * @brief Gets the enabled FTM interrupts.
559  *
560  * @param base FTM peripheral base address
561  *
562  * @return The enabled interrupts. This is the logical OR of members of the
563  *         enumeration ::ftm_interrupt_enable_t
564  */
565 uint32_t FTM_GetEnabledInterrupts(FTM_Type *base);
566 
567 /*! @}*/
568 
569 /*!
570  * @name Status Interface
571  * @{
572  */
573 
574 /*!
575  * @brief Gets the FTM status flags.
576  *
577  * @param base FTM peripheral base address
578  *
579  * @return The status flags. This is the logical OR of members of the
580  *         enumeration ::ftm_status_flags_t
581  */
582 uint32_t FTM_GetStatusFlags(FTM_Type *base);
583 
584 /*!
585  * @brief Clears the FTM status flags.
586  *
587  * @param base FTM peripheral base address
588  * @param mask The status flags to clear. This is a logical OR of members of the
589  *             enumeration ::ftm_status_flags_t
590  */
591 void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask);
592 
593 /*! @}*/
594 
595 /*!
596  * @name Read and write the timer period
597  * @{
598  */
599 
600 /*!
601  * @brief Sets the timer period in units of ticks.
602  *
603  * Timers counts from 0 until it equals the count value set here. The count value is written to
604  * the MOD register.
605  *
606  * @note
607  * 1. This API allows the user to use the FTM module as a timer. Do not mix usage
608  *    of this API with FTM's PWM setup API's.
609  * 2. Call the utility macros provided in the fsl_common.h to convert usec or msec to ticks.
610  *
611  * @param base FTM peripheral base address
612  * @param ticks A timer period in units of ticks, which should be equal or greater than 1.
613  */
FTM_SetTimerPeriod(FTM_Type * base,uint32_t ticks)614 static inline void FTM_SetTimerPeriod(FTM_Type *base, uint32_t ticks)
615 {
616     base->MOD = ticks;
617 }
618 
619 /*!
620  * @brief Reads the current timer counting value.
621  *
622  * This function returns the real-time timer counting value in a range from 0 to a
623  * timer period.
624  *
625  * @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec.
626  *
627  * @param base FTM peripheral base address
628  *
629  * @return The current counter value in ticks
630  */
FTM_GetCurrentTimerCount(FTM_Type * base)631 static inline uint32_t FTM_GetCurrentTimerCount(FTM_Type *base)
632 {
633     return (uint32_t)((base->CNT & FTM_CNT_COUNT_MASK) >> FTM_CNT_COUNT_SHIFT);
634 }
635 
636 /*! @}*/
637 /*!
638  * @name Timer Start and Stop
639  * @{
640  */
641 
642 /*!
643  * @brief Starts the FTM counter.
644  *
645  * @param base        FTM peripheral base address
646  * @param clockSource FTM clock source; After the clock source is set, the counter starts running.
647  */
FTM_StartTimer(FTM_Type * base,ftm_clock_source_t clockSource)648 static inline void FTM_StartTimer(FTM_Type *base, ftm_clock_source_t clockSource)
649 {
650     uint32_t reg = base->SC;
651 
652     reg &= ~(FTM_SC_CLKS_MASK);
653     reg |= FTM_SC_CLKS(clockSource);
654     base->SC = reg;
655 }
656 
657 /*!
658  * @brief Stops the FTM counter.
659  *
660  * @param base FTM peripheral base address
661  */
FTM_StopTimer(FTM_Type * base)662 static inline void FTM_StopTimer(FTM_Type *base)
663 {
664     /* Set clock source to none to disable counter */
665     base->SC &= ~(FTM_SC_CLKS_MASK);
666 }
667 
668 /*! @}*/
669 
670 /*!
671  * @name Software output control
672  * @{
673  */
674 
675 /*!
676  * @brief Enables or disables the channel software output control.
677  *
678  * @param base       FTM peripheral base address
679  * @param chnlNumber Channel to be enabled or disabled
680  * @param value      true: channel output is affected by software output control
681                      false: channel output is unaffected by software output control
682  */
FTM_SetSoftwareCtrlEnable(FTM_Type * base,ftm_chnl_t chnlNumber,bool value)683 static inline void FTM_SetSoftwareCtrlEnable(FTM_Type *base, ftm_chnl_t chnlNumber, bool value)
684 {
685     if (value)
686     {
687         base->SWOCTRL |= (1U << chnlNumber);
688     }
689     else
690     {
691         base->SWOCTRL &= ~(1U << chnlNumber);
692     }
693 }
694 
695 /*!
696  * @brief Sets the channel software output control value.
697  *
698  * @param base       FTM peripheral base address.
699  * @param chnlNumber Channel to be configured
700  * @param value      true to set 1, false to set 0
701  */
FTM_SetSoftwareCtrlVal(FTM_Type * base,ftm_chnl_t chnlNumber,bool value)702 static inline void FTM_SetSoftwareCtrlVal(FTM_Type *base, ftm_chnl_t chnlNumber, bool value)
703 {
704     if (value)
705     {
706         base->SWOCTRL |= (1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT));
707     }
708     else
709     {
710         base->SWOCTRL &= ~(1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT));
711     }
712 }
713 
714 /*! @}*/
715 
716 /*!
717  * @brief Enables or disables the FTM global time base signal generation to other FTMs.
718  *
719  * @param base   FTM peripheral base address
720  * @param enable true to enable, false to disable
721  */
FTM_SetGlobalTimeBaseOutputEnable(FTM_Type * base,bool enable)722 static inline void FTM_SetGlobalTimeBaseOutputEnable(FTM_Type *base, bool enable)
723 {
724     if (enable)
725     {
726         base->CONF |= FTM_CONF_GTBEOUT_MASK;
727     }
728     else
729     {
730         base->CONF &= ~FTM_CONF_GTBEOUT_MASK;
731     }
732 }
733 
734 /*!
735  * @brief Sets the FTM peripheral timer channel output mask.
736  *
737  * @param base       FTM peripheral base address
738  * @param chnlNumber Channel to be configured
739  * @param mask       true: masked, channel is forced to its inactive state; false: unmasked
740  */
FTM_SetOutputMask(FTM_Type * base,ftm_chnl_t chnlNumber,bool mask)741 static inline void FTM_SetOutputMask(FTM_Type *base, ftm_chnl_t chnlNumber, bool mask)
742 {
743     if (mask)
744     {
745         base->OUTMASK |= (1U << chnlNumber);
746     }
747     else
748     {
749         base->OUTMASK &= ~(1U << chnlNumber);
750     }
751 }
752 
753 #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
754 /*!
755  * @brief Allows users to enable an output on an FTM channel.
756  *
757  * To enable the PWM channel output call this function with val=true. For input mode,
758  * call this function with val=false.
759  *
760  * @param base       FTM peripheral base address
761  * @param chnlNumber Channel to be configured
762  * @param value      true: enable output; false: output is disabled, used in input mode
763  */
FTM_SetPwmOutputEnable(FTM_Type * base,ftm_chnl_t chnlNumber,bool value)764 static inline void FTM_SetPwmOutputEnable(FTM_Type *base, ftm_chnl_t chnlNumber, bool value)
765 {
766     if (value)
767     {
768         base->SC |= (1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT));
769     }
770     else
771     {
772         base->SC &= ~(1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT));
773     }
774 }
775 #endif
776 
777 /*!
778  * @name Channel pair operations
779  * @{
780  */
781 
782 /*!
783  * @brief This function enables/disables the fault control in a channel pair.
784  *
785  * @param base           FTM peripheral base address
786  * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
787  * @param value          true: Enable fault control for this channel pair; false: No fault control
788  */
FTM_SetFaultControlEnable(FTM_Type * base,ftm_chnl_t chnlPairNumber,bool value)789 static inline void FTM_SetFaultControlEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
790 {
791     if (value)
792     {
793         base->COMBINE |= (1U << (FTM_COMBINE_FAULTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
794     }
795     else
796     {
797         base->COMBINE &= ~(1U << (FTM_COMBINE_FAULTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
798     }
799 }
800 
801 /*!
802  * @brief This function enables/disables the dead time insertion in a channel pair.
803  *
804  * @param base           FTM peripheral base address
805  * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
806  * @param value          true: Insert dead time in this channel pair; false: No dead time inserted
807  */
FTM_SetDeadTimeEnable(FTM_Type * base,ftm_chnl_t chnlPairNumber,bool value)808 static inline void FTM_SetDeadTimeEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
809 {
810     if (value)
811     {
812         base->COMBINE |= (1U << (FTM_COMBINE_DTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
813     }
814     else
815     {
816         base->COMBINE &= ~(1U << (FTM_COMBINE_DTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
817     }
818 }
819 
820 /*!
821  * @brief This function enables/disables complementary mode in a channel pair.
822  *
823  * @param base           FTM peripheral base address
824  * @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
825  * @param value          true: enable complementary mode; false: disable complementary mode
826  */
FTM_SetComplementaryEnable(FTM_Type * base,ftm_chnl_t chnlPairNumber,bool value)827 static inline void FTM_SetComplementaryEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
828 {
829     if (value)
830     {
831         base->COMBINE |= (1U << (FTM_COMBINE_COMP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
832     }
833     else
834     {
835         base->COMBINE &= ~(1U << (FTM_COMBINE_COMP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
836     }
837 }
838 
839 /*!
840  * @brief This function enables/disables inverting control in a channel pair.
841  *
842  * @param base            FTM peripheral base address
843  * @param chnlPairNumber  The FTM channel pair number; options are 0, 1, 2, 3
844  * @param value           true: enable inverting; false: disable inverting
845  */
FTM_SetInvertEnable(FTM_Type * base,ftm_chnl_t chnlPairNumber,bool value)846 static inline void FTM_SetInvertEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
847 {
848     if (value)
849     {
850         base->INVCTRL |= (1U << chnlPairNumber);
851     }
852     else
853     {
854         base->INVCTRL &= ~(1U << chnlPairNumber);
855     }
856 }
857 
858 /*! @}*/
859 
860 /*!
861  * @name Quad Decoder
862  * @{
863  */
864 
865 /*!
866  * @brief Configures the parameters and activates the quadrature decoder mode.
867  *
868  * @param base         FTM peripheral base address
869  * @param phaseAParams Phase A configuration parameters
870  * @param phaseBParams Phase B configuration parameters
871  * @param quadMode     Selects encoding mode used in quadrature decoder mode
872  */
873 void FTM_SetupQuadDecode(FTM_Type *base,
874                          const ftm_phase_params_t *phaseAParams,
875                          const ftm_phase_params_t *phaseBParams,
876                          ftm_quad_decode_mode_t quadMode);
877 
878 /*!
879  * @brief Gets the FTM Quad Decoder flags.
880  *
881  * @param base FTM peripheral base address.
882  * @return Flag mask of FTM Quad Decoder, see #_ftm_quad_decoder_flags.
883  */
FTM_GetQuadDecoderFlags(FTM_Type * base)884 static inline uint32_t FTM_GetQuadDecoderFlags(FTM_Type *base)
885 {
886     return base->QDCTRL & (FTM_QDCTRL_QUADIR_MASK | FTM_QDCTRL_TOFDIR_MASK);
887 }
888 
889 /*!
890  * @brief Sets the modulo values for Quad Decoder.
891  *
892  * The modulo values configure the minimum and maximum values that the Quad decoder counter can reach. After the counter goes
893  * over, the counter value goes to the other side and decrease/increase again.
894  *
895  * @param base FTM peripheral base address.
896  * @param startValue The low limit value for Quad Decoder counter.
897  * @param overValue The high limit value for Quad Decoder counter.
898  */
FTM_SetQuadDecoderModuloValue(FTM_Type * base,uint32_t startValue,uint32_t overValue)899 static inline void FTM_SetQuadDecoderModuloValue(FTM_Type *base, uint32_t startValue, uint32_t overValue)
900 {
901     base->CNTIN = startValue;
902     base->MOD = overValue;
903 }
904 
905 /*!
906  * @brief Gets the current Quad Decoder counter value.
907  *
908  * @param base FTM peripheral base address.
909  * @return Current quad Decoder counter value.
910  */
FTM_GetQuadDecoderCounterValue(FTM_Type * base)911 static inline uint32_t FTM_GetQuadDecoderCounterValue(FTM_Type *base)
912 {
913     return base->CNT;
914 }
915 
916 /*!
917  * @brief Clears the current Quad Decoder counter value.
918  *
919  * The counter is set as the initial value.
920  *
921  * @param base FTM peripheral base address.
922  */
FTM_ClearQuadDecoderCounterValue(FTM_Type * base)923 static inline void FTM_ClearQuadDecoderCounterValue(FTM_Type *base)
924 {
925     base->CNT = base->CNTIN;
926 }
927 
928 /*! @}*/
929 
930 /*!
931  * @brief Enables or disables the FTM software trigger for PWM synchronization.
932  *
933  * @param base   FTM peripheral base address
934  * @param enable true: software trigger is selected, false: software trigger is not selected
935  */
FTM_SetSoftwareTrigger(FTM_Type * base,bool enable)936 static inline void FTM_SetSoftwareTrigger(FTM_Type *base, bool enable)
937 {
938     if (enable)
939     {
940         base->SYNC |= FTM_SYNC_SWSYNC_MASK;
941     }
942     else
943     {
944         base->SYNC &= ~FTM_SYNC_SWSYNC_MASK;
945     }
946 }
947 
948 /*!
949  * @brief Enables or disables the FTM write protection.
950  *
951  * @param base   FTM peripheral base address
952  * @param enable true: Write-protection is enabled, false: Write-protection is disabled
953  */
FTM_SetWriteProtection(FTM_Type * base,bool enable)954 static inline void FTM_SetWriteProtection(FTM_Type *base, bool enable)
955 {
956     /* Configure write protection */
957     if (enable)
958     {
959         base->FMS |= FTM_FMS_WPEN_MASK;
960     }
961     else
962     {
963         base->MODE |= FTM_MODE_WPDIS_MASK;
964     }
965 }
966 
967 #if defined(__cplusplus)
968 }
969 #endif
970 
971 /*! @}*/
972 
973 #endif /* _FSL_FTM_H_*/
974