1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_PWM_H_
9 #define FSL_PWM_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup pwm_driver
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 /*! @name Driver version */
22 /*! @{ */
23 #define FSL_PWM_DRIVER_VERSION (MAKE_VERSION(2, 8, 4)) /*!< Version 2.8.4 */
24 /*! @} */
25 
26 /*! Number of bits per submodule for software output control */
27 #define PWM_SUBMODULE_SWCONTROL_WIDTH 2
28 /*! Because setting the pwm duty cycle doesn't support PWMX, getting the pwm duty cycle also doesn't support PWMX. */
29 #define PWM_SUBMODULE_CHANNEL 2
30 
31 /*! @brief List of PWM submodules */
32 typedef enum _pwm_submodule
33 {
34     kPWM_Module_0 = 0U, /*!< Submodule 0 */
35     kPWM_Module_1,      /*!< Submodule 1 */
36     kPWM_Module_2,      /*!< Submodule 2 */
37 #if defined(FSL_FEATURE_PWM_SUBMODULE_COUNT) && (FSL_FEATURE_PWM_SUBMODULE_COUNT > 3U)
38     kPWM_Module_3       /*!< Submodule 3 */
39 #endif /* FSL_FEATURE_PWM_SUBMODULE_COUNT */
40 } pwm_submodule_t;
41 
42 /*! @brief List of PWM channels in each module */
43 typedef enum _pwm_channels
44 {
45     kPWM_PwmB = 0U,
46     kPWM_PwmA,
47     kPWM_PwmX
48 } pwm_channels_t;
49 
50 /*! @brief List of PWM value registers */
51 typedef enum _pwm_value_register
52 {
53     kPWM_ValueRegister_0 = 0U, /*!< PWM Value0 register */
54     kPWM_ValueRegister_1,      /*!< PWM Value1 register */
55     kPWM_ValueRegister_2,      /*!< PWM Value2 register */
56     kPWM_ValueRegister_3,      /*!< PWM Value3 register */
57     kPWM_ValueRegister_4,      /*!< PWM Value4 register */
58     kPWM_ValueRegister_5       /*!< PWM Value5 register */
59 } pwm_value_register_t;
60 
61 /*! @brief List of PWM value registers mask */
62 enum _pwm_value_register_mask
63 {
64     kPWM_ValueRegisterMask_0 = (1U << 0), /*!< PWM Value0 register mask */
65     kPWM_ValueRegisterMask_1 = (1U << 1), /*!< PWM Value1 register mask */
66     kPWM_ValueRegisterMask_2 = (1U << 2), /*!< PWM Value2 register mask */
67     kPWM_ValueRegisterMask_3 = (1U << 3), /*!< PWM Value3 register mask */
68     kPWM_ValueRegisterMask_4 = (1U << 4), /*!< PWM Value4 register mask */
69     kPWM_ValueRegisterMask_5 = (1U << 5)  /*!< PWM Value5 register mask */
70 };
71 
72 /*! @brief PWM clock source selection.*/
73 typedef enum _pwm_clock_source
74 {
75     kPWM_BusClock = 0U,  /*!< The IPBus clock is used as the clock */
76     kPWM_ExternalClock,  /*!< EXT_CLK is used as the clock */
77     kPWM_Submodule0Clock /*!< Clock of the submodule 0 (AUX_CLK) is used as the source clock */
78 } pwm_clock_source_t;
79 
80 /*! @brief PWM prescaler factor selection for clock source*/
81 typedef enum _pwm_clock_prescale
82 {
83     kPWM_Prescale_Divide_1 = 0U, /*!< PWM clock frequency = fclk/1 */
84     kPWM_Prescale_Divide_2,      /*!< PWM clock frequency = fclk/2 */
85     kPWM_Prescale_Divide_4,      /*!< PWM clock frequency = fclk/4 */
86     kPWM_Prescale_Divide_8,      /*!< PWM clock frequency = fclk/8 */
87     kPWM_Prescale_Divide_16,     /*!< PWM clock frequency = fclk/16 */
88     kPWM_Prescale_Divide_32,     /*!< PWM clock frequency = fclk/32 */
89     kPWM_Prescale_Divide_64,     /*!< PWM clock frequency = fclk/64 */
90     kPWM_Prescale_Divide_128     /*!< PWM clock frequency = fclk/128 */
91 } pwm_clock_prescale_t;
92 
93 /*! @brief Options that can trigger a PWM FORCE_OUT */
94 typedef enum _pwm_force_output_trigger
95 {
96     kPWM_Force_Local = 0U,   /*!< The local force signal, CTRL2[FORCE], from the submodule is used to force updates */
97     kPWM_Force_Master,       /*!< The master force signal from submodule 0 is used to force updates */
98     kPWM_Force_LocalReload,  /*!< The local reload signal from this submodule is used to force updates without regard to
99                                 the state of LDOK */
100     kPWM_Force_MasterReload, /*!< The master reload signal from submodule 0 is used to force updates if LDOK is set */
101     kPWM_Force_LocalSync,    /*!< The local sync signal from this submodule is used to force updates */
102     kPWM_Force_MasterSync,   /*!< The master sync signal from submodule0 is used to force updates */
103     kPWM_Force_External,     /*!< The external force signal, EXT_FORCE, from outside the PWM module causes updates */
104     kPWM_Force_ExternalSync  /*!< The external sync signal, EXT_SYNC, from outside the PWM module causes updates */
105 } pwm_force_output_trigger_t;
106 
107 /*! @brief PWM channel output status */
108 typedef enum _pwm_output_state
109 {
110     kPWM_HighState = 0, /*!< The output state of PWM channel is high */
111     kPWM_LowState,      /*!< The output state of PWM channel is low */
112     kPWM_NormalState,   /*!< The output state of PWM channel is normal */
113     kPWM_InvertState,   /*!< The output state of PWM channel is invert */
114     kPWM_MaskState      /*!< The output state of PWM channel is mask */
115 } pwm_output_state_t;
116 
117 /*! @brief PWM counter initialization options */
118 typedef enum _pwm_init_source
119 {
120     kPWM_Initialize_LocalSync = 0U, /*!< Local sync causes initialization */
121     kPWM_Initialize_MasterReload,   /*!< Master reload from submodule 0 causes initialization */
122     kPWM_Initialize_MasterSync,     /*!< Master sync from submodule 0 causes initialization */
123     kPWM_Initialize_ExtSync         /*!< EXT_SYNC causes initialization */
124 } pwm_init_source_t;
125 
126 /*! @brief PWM load frequency selection */
127 typedef enum _pwm_load_frequency
128 {
129     kPWM_LoadEveryOportunity = 0U, /*!< Every PWM opportunity */
130     kPWM_LoadEvery2Oportunity,     /*!< Every 2 PWM opportunities */
131     kPWM_LoadEvery3Oportunity,     /*!< Every 3 PWM opportunities */
132     kPWM_LoadEvery4Oportunity,     /*!< Every 4 PWM opportunities */
133     kPWM_LoadEvery5Oportunity,     /*!< Every 5 PWM opportunities */
134     kPWM_LoadEvery6Oportunity,     /*!< Every 6 PWM opportunities */
135     kPWM_LoadEvery7Oportunity,     /*!< Every 7 PWM opportunities */
136     kPWM_LoadEvery8Oportunity,     /*!< Every 8 PWM opportunities */
137     kPWM_LoadEvery9Oportunity,     /*!< Every 9 PWM opportunities */
138     kPWM_LoadEvery10Oportunity,    /*!< Every 10 PWM opportunities */
139     kPWM_LoadEvery11Oportunity,    /*!< Every 11 PWM opportunities */
140     kPWM_LoadEvery12Oportunity,    /*!< Every 12 PWM opportunities */
141     kPWM_LoadEvery13Oportunity,    /*!< Every 13 PWM opportunities */
142     kPWM_LoadEvery14Oportunity,    /*!< Every 14 PWM opportunities */
143     kPWM_LoadEvery15Oportunity,    /*!< Every 15 PWM opportunities */
144     kPWM_LoadEvery16Oportunity     /*!< Every 16 PWM opportunities */
145 } pwm_load_frequency_t;
146 
147 /*! @brief List of PWM fault selections */
148 typedef enum _pwm_fault_input
149 {
150     kPWM_Fault_0 = 0U, /*!< Fault 0 input pin */
151     kPWM_Fault_1,      /*!< Fault 1 input pin */
152     kPWM_Fault_2,      /*!< Fault 2 input pin */
153     kPWM_Fault_3       /*!< Fault 3 input pin */
154 } pwm_fault_input_t;
155 
156 /*! @brief List of PWM fault disable mapping selections */
157 typedef enum _pwm_fault_disable
158 {
159     kPWM_FaultDisable_0 = (1U << 0), /*!< Fault 0 disable mapping */
160     kPWM_FaultDisable_1 = (1U << 1), /*!< Fault 1 disable mapping */
161     kPWM_FaultDisable_2 = (1U << 2), /*!< Fault 2 disable mapping */
162     kPWM_FaultDisable_3 = (1U << 3)  /*!< Fault 3 disable mapping */
163 } pwm_fault_disable_t;
164 
165 /*! @brief List of PWM fault channels */
166 typedef enum _pwm_fault_channels
167 {
168     kPWM_faultchannel_0 = 0U,
169     kPWM_faultchannel_1
170 } pwm_fault_channels_t;
171 
172 /*! @brief PWM capture edge select */
173 typedef enum _pwm_input_capture_edge
174 {
175     kPWM_Disable = 0U,   /*!< Disabled */
176     kPWM_FallingEdge,    /*!< Capture on falling edge only */
177     kPWM_RisingEdge,     /*!< Capture on rising edge only */
178     kPWM_RiseAndFallEdge /*!< Capture on rising or falling edge */
179 } pwm_input_capture_edge_t;
180 
181 /*! @brief PWM output options when a FORCE_OUT signal is asserted */
182 typedef enum _pwm_force_signal
183 {
184     kPWM_UsePwm = 0U,     /*!< Generated PWM signal is used by the deadtime logic.*/
185     kPWM_InvertedPwm,     /*!< Inverted PWM signal is used by the deadtime logic.*/
186     kPWM_SoftwareControl, /*!< Software controlled value is used by the deadtime logic. */
187     kPWM_UseExternal      /*!< PWM_EXTA signal is used by the deadtime logic. */
188 } pwm_force_signal_t;
189 
190 /*! @brief Options available for the PWM A & B pair operation */
191 typedef enum _pwm_chnl_pair_operation
192 {
193     kPWM_Independent = 0U,  /*!< PWM A & PWM B operate as 2 independent channels */
194     kPWM_ComplementaryPwmA, /*!< PWM A & PWM B are complementary channels, PWM A generates the signal */
195     kPWM_ComplementaryPwmB  /*!< PWM A & PWM B are complementary channels, PWM B generates the signal */
196 } pwm_chnl_pair_operation_t;
197 
198 /*! @brief Options available on how to load the buffered-registers with new values */
199 typedef enum _pwm_register_reload
200 {
201     kPWM_ReloadImmediate = 0U,     /*!< Buffered-registers get loaded with new values as soon as LDOK bit is set */
202     kPWM_ReloadPwmHalfCycle,       /*!< Registers loaded on a PWM half cycle */
203     kPWM_ReloadPwmFullCycle,       /*!< Registers loaded on a PWM full cycle */
204     kPWM_ReloadPwmHalfAndFullCycle /*!< Registers loaded on a PWM half & full cycle */
205 } pwm_register_reload_t;
206 
207 /*! @brief Options available on how to re-enable the PWM output when recovering from a fault */
208 typedef enum _pwm_fault_recovery_mode
209 {
210     kPWM_NoRecovery = 0U,        /*!< PWM output will stay inactive */
211     kPWM_RecoverHalfCycle,       /*!< PWM output re-enabled at the first half cycle */
212     kPWM_RecoverFullCycle,       /*!< PWM output re-enabled at the first full cycle */
213     kPWM_RecoverHalfAndFullCycle /*!< PWM output re-enabled at the first half or full cycle */
214 } pwm_fault_recovery_mode_t;
215 
216 /*! @brief List of PWM interrupt options */
217 typedef enum _pwm_interrupt_enable
218 {
219     kPWM_CompareVal0InterruptEnable = (1U << 0),  /*!< PWM VAL0 compare interrupt */
220     kPWM_CompareVal1InterruptEnable = (1U << 1),  /*!< PWM VAL1 compare interrupt */
221     kPWM_CompareVal2InterruptEnable = (1U << 2),  /*!< PWM VAL2 compare interrupt */
222     kPWM_CompareVal3InterruptEnable = (1U << 3),  /*!< PWM VAL3 compare interrupt */
223     kPWM_CompareVal4InterruptEnable = (1U << 4),  /*!< PWM VAL4 compare interrupt */
224     kPWM_CompareVal5InterruptEnable = (1U << 5),  /*!< PWM VAL5 compare interrupt */
225 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX
226     kPWM_CaptureX0InterruptEnable   = (1U << 6),  /*!< PWM capture X0 interrupt */
227     kPWM_CaptureX1InterruptEnable   = (1U << 7),  /*!< PWM capture X1 interrupt */
228 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX */
229 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB
230     kPWM_CaptureB0InterruptEnable   = (1U << 8),  /*!< PWM capture B0 interrupt */
231     kPWM_CaptureB1InterruptEnable   = (1U << 9),  /*!< PWM capture B1 interrupt */
232 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB */
233 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA
234     kPWM_CaptureA0InterruptEnable   = (1U << 10), /*!< PWM capture A0 interrupt */
235     kPWM_CaptureA1InterruptEnable   = (1U << 11), /*!< PWM capture A1 interrupt */
236 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA */
237     kPWM_ReloadInterruptEnable      = (1U << 12), /*!< PWM reload interrupt */
238     kPWM_ReloadErrorInterruptEnable = (1U << 13), /*!< PWM reload error interrupt */
239     kPWM_Fault0InterruptEnable      = (1U << 16), /*!< PWM fault 0 interrupt */
240     kPWM_Fault1InterruptEnable      = (1U << 17), /*!< PWM fault 1 interrupt */
241     kPWM_Fault2InterruptEnable      = (1U << 18), /*!< PWM fault 2 interrupt */
242     kPWM_Fault3InterruptEnable      = (1U << 19)  /*!< PWM fault 3 interrupt */
243 } pwm_interrupt_enable_t;
244 
245 /*! @brief List of PWM status flags */
246 typedef enum _pwm_status_flags
247 {
248     kPWM_CompareVal0Flag = (1U << 0),  /*!< PWM VAL0 compare flag */
249     kPWM_CompareVal1Flag = (1U << 1),  /*!< PWM VAL1 compare flag */
250     kPWM_CompareVal2Flag = (1U << 2),  /*!< PWM VAL2 compare flag */
251     kPWM_CompareVal3Flag = (1U << 3),  /*!< PWM VAL3 compare flag */
252     kPWM_CompareVal4Flag = (1U << 4),  /*!< PWM VAL4 compare flag */
253     kPWM_CompareVal5Flag = (1U << 5),  /*!< PWM VAL5 compare flag */
254 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX
255     kPWM_CaptureX0Flag   = (1U << 6),  /*!< PWM capture X0 flag */
256     kPWM_CaptureX1Flag   = (1U << 7),  /*!< PWM capture X1 flag */
257 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX */
258 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB
259     kPWM_CaptureB0Flag   = (1U << 8),  /*!< PWM capture B0 flag */
260     kPWM_CaptureB1Flag   = (1U << 9),  /*!< PWM capture B1 flag */
261 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB */
262 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA
263     kPWM_CaptureA0Flag   = (1U << 10), /*!< PWM capture A0 flag */
264     kPWM_CaptureA1Flag   = (1U << 11), /*!< PWM capture A1 flag */
265 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA */
266     kPWM_ReloadFlag      = (1U << 12), /*!< PWM reload flag */
267     kPWM_ReloadErrorFlag = (1U << 13), /*!< PWM reload error flag */
268     kPWM_RegUpdatedFlag  = (1U << 14), /*!< PWM registers updated flag */
269     kPWM_Fault0Flag      = (1U << 16), /*!< PWM fault 0 flag */
270     kPWM_Fault1Flag      = (1U << 17), /*!< PWM fault 1 flag */
271     kPWM_Fault2Flag      = (1U << 18), /*!< PWM fault 2 flag */
272     kPWM_Fault3Flag      = (1U << 19)  /*!< PWM fault 3 flag */
273 } pwm_status_flags_t;
274 
275 /*! @brief List of PWM DMA options */
276 typedef enum _pwm_dma_enable
277 {
278 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX
279     kPWM_CaptureX0DMAEnable = (1U << 0), /*!< PWM capture X0 DMA */
280     kPWM_CaptureX1DMAEnable = (1U << 1), /*!< PWM capture X1 DMA */
281 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX */
282 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB
283     kPWM_CaptureB0DMAEnable = (1U << 2), /*!< PWM capture B0 DMA */
284     kPWM_CaptureB1DMAEnable = (1U << 3), /*!< PWM capture B1 DMA */
285 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB */
286 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA
287     kPWM_CaptureA0DMAEnable = (1U << 4), /*!< PWM capture A0 DMA */
288     kPWM_CaptureA1DMAEnable = (1U << 5)  /*!< PWM capture A1 DMA */
289 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA */
290 } pwm_dma_enable_t;
291 
292 /*! @brief List of PWM capture DMA enable source select */
293 typedef enum _pwm_dma_source_select
294 {
295     kPWM_DMARequestDisable = 0U, /*!< Read DMA requests disabled */
296     kPWM_DMAWatermarksEnable,    /*!< Exceeding a FIFO watermark sets the DMA read request */
297     kPWM_DMALocalSync,           /*!< A local sync (VAL1 matches counter) sets the read DMA request */
298     kPWM_DMALocalReload          /*!< A local reload (STS[RF] being set) sets the read DMA request */
299 } pwm_dma_source_select_t;
300 
301 /*! @brief PWM FIFO Watermark AND Control */
302 typedef enum _pwm_watermark_control
303 {
304     kPWM_FIFOWatermarksOR = 0U, /*!< Selected FIFO watermarks are OR'ed together */
305     kPWM_FIFOWatermarksAND      /*!< Selected FIFO watermarks are AND'ed together */
306 } pwm_watermark_control_t;
307 
308 /*! @brief PWM operation mode */
309 typedef enum _pwm_mode
310 {
311     kPWM_SignedCenterAligned = 0U, /*!< Signed center-aligned */
312     kPWM_CenterAligned,            /*!< Unsigned cente-aligned */
313     kPWM_SignedEdgeAligned,        /*!< Signed edge-aligned */
314     kPWM_EdgeAligned               /*!< Unsigned edge-aligned */
315 } pwm_mode_t;
316 
317 /*! @brief PWM output pulse mode, high-true or low-true */
318 typedef enum _pwm_level_select
319 {
320     kPWM_HighTrue = 0U, /*!< High level represents "on" or "active" state */
321     kPWM_LowTrue        /*!< Low level represents "on" or "active" state */
322 } pwm_level_select_t;
323 
324 /*! @brief PWM output fault status */
325 typedef enum _pwm_fault_state
326 {
327     kPWM_PwmFaultState0 =
328         0U,              /*!< Output is forced to logic 0 state prior to consideration of output polarity control. */
329     kPWM_PwmFaultState1, /*!< Output is forced to logic 1 state prior to consideration of output polarity control. */
330     kPWM_PwmFaultState2, /*!< Output is tristated. */
331     kPWM_PwmFaultState3  /*!< Output is tristated. */
332 } pwm_fault_state_t;
333 
334 /*! @brief PWM reload source select */
335 typedef enum _pwm_reload_source_select
336 {
337     kPWM_LocalReload = 0U, /*!< The local reload signal is used to reload registers */
338     kPWM_MasterReload      /*!< The master reload signal (from submodule 0) is used to reload */
339 } pwm_reload_source_select_t;
340 
341 /*! @brief PWM fault clearing options */
342 typedef enum _pwm_fault_clear
343 {
344     kPWM_Automatic = 0U, /*!< Automatic fault clearing  */
345     kPWM_ManualNormal,   /*!< Manual fault clearing with no fault safety mode */
346     kPWM_ManualSafety    /*!< Manual fault clearing with fault safety mode */
347 } pwm_fault_clear_t;
348 
349 /*! @brief Options for submodule master control operation */
350 typedef enum _pwm_module_control
351 {
352     kPWM_Control_Module_0 = (1U << 0), /*!< Control submodule 0's start/stop,buffer reload operation */
353     kPWM_Control_Module_1 = (1U << 1), /*!< Control submodule 1's start/stop,buffer reload operation */
354     kPWM_Control_Module_2 = (1U << 2), /*!< Control submodule 2's start/stop,buffer reload operation */
355     kPWM_Control_Module_3 = (1U << 3)  /*!< Control submodule 3's start/stop,buffer reload operation */
356 } pwm_module_control_t;
357 
358 /*! @brief Structure for the user to define the PWM signal characteristics */
359 typedef struct _pwm_signal_param
360 {
361     pwm_channels_t pwmChannel; /*!< PWM channel being configured; PWM A or PWM B */
362     uint8_t dutyCyclePercent;  /*!< PWM pulse width, value should be between 0 to 100
363                                     0=inactive signal(0% duty cycle)...
364                                     100=always active signal (100% duty cycle)*/
365     pwm_level_select_t level;  /*!< PWM output active level select */
366     uint16_t deadtimeValue;    /*!< The deadtime value; only used if channel pair is operating in complementary mode */
367     pwm_fault_state_t faultState; /*!< PWM output fault status */
368     bool pwmchannelenable;        /*!< Enable PWM output */
369 } pwm_signal_param_t;
370 
371 /*!
372  * @brief PWM config structure
373  *
374  * This structure holds the configuration settings for the PWM peripheral. To initialize this
375  * structure to reasonable defaults, call the PWM_GetDefaultConfig() function and pass a
376  * pointer to your config structure instance.
377  *
378  * The config struct can be made const so it resides in flash
379  */
380 typedef struct _pwm_config
381 {
382     bool enableDebugMode; /*!< true: PWM continues to run in debug mode;
383                                false: PWM is paused in debug mode */
384 #if !defined(FSL_FEATURE_PWM_HAS_NO_WAITEN) || (!FSL_FEATURE_PWM_HAS_NO_WAITEN)
385     bool enableWait;                         /*!< true: PWM continues to run in WAIT mode;
386                                                   false: PWM is paused in WAIT mode */
387 #endif                                       /* FSL_FEATURE_PWM_HAS_NO_WAITEN */
388     pwm_init_source_t initializationControl; /*!< Option to initialize the counter */
389     pwm_clock_source_t clockSource;          /*!< Clock source for the counter */
390     pwm_clock_prescale_t prescale;           /*!< Pre-scaler to divide down the clock */
391     pwm_chnl_pair_operation_t pairOperation; /*!< Channel pair in indepedent or complementary mode */
392     pwm_register_reload_t reloadLogic;       /*!< PWM Reload logic setup */
393     pwm_reload_source_select_t reloadSelect; /*!< Reload source select */
394     pwm_load_frequency_t reloadFrequency;    /*!< Specifies when to reload, used when user's choice
395                                                   is not immediate reload */
396     pwm_force_output_trigger_t forceTrigger; /*!< Specify which signal will trigger a FORCE_OUT */
397 } pwm_config_t;
398 
399 /*! @brief Structure for the user to configure the fault input filter. */
400 typedef struct _pwm_fault_input_filter_param
401 {
402     uint8_t faultFilterCount;  /*!< Fault filter count */
403     uint8_t faultFilterPeriod; /*!< Fault filter period;value of 0 will bypass the filter */
404     bool faultGlitchStretch;   /*!< Fault Glitch Stretch Enable: A logic 1 means that input
405                                     fault signals will be stretched to at least 2 IPBus clock cycles */
406 } pwm_fault_input_filter_param_t;
407 
408 /*! @brief Structure is used to hold the parameters to configure a PWM fault */
409 typedef struct _pwm_fault_param
410 {
411     pwm_fault_clear_t faultClearingMode;   /*!< Fault clearing mode to use */
412     bool faultLevel;                       /*!< true: Logic 1 indicates fault;
413                                                 false: Logic 0 indicates fault */
414     bool enableCombinationalPath;          /*!< true: Combinational Path from fault input is enabled;
415                                                 false: No combination path is available */
416     pwm_fault_recovery_mode_t recoverMode; /*!< Specify when to re-enable the PWM output */
417 } pwm_fault_param_t;
418 
419 /*!
420  * @brief Structure is used to hold parameters to configure the capture capability of a signal pin
421  */
422 typedef struct _pwm_input_capture_param
423 {
424     bool captureInputSel;           /*!< true: Use the edge counter signal as source
425                                          false: Use the raw input signal from the pin as source */
426     uint8_t edgeCompareValue;       /*!< Compare value, used only if edge counter is used as source */
427     pwm_input_capture_edge_t edge0; /*!< Specify which edge causes a capture for input circuitry 0 */
428     pwm_input_capture_edge_t edge1; /*!< Specify which edge causes a capture for input circuitry 1 */
429     bool enableOneShotCapture;      /*!< true: Use one-shot capture mode;
430                                          false: Use free-running capture mode */
431     uint8_t fifoWatermark;          /*!< Watermark level for capture FIFO. The capture flags in
432                                          the status register will set if the word count in the FIFO
433                                          is greater than this watermark level */
434 } pwm_input_capture_param_t;
435 
436 /*******************************************************************************
437  * API
438  ******************************************************************************/
439 
440 #if defined(__cplusplus)
441 extern "C" {
442 #endif
443 
444 /*!
445  * @name Initialization and deinitialization
446  * @{
447  */
448 
449 /*!
450  * @brief Ungates the PWM submodule clock and configures the peripheral for basic operation.
451  *
452  * @note This API should be called at the beginning of the application using the PWM driver.
453  *
454  * @param base      PWM peripheral base address
455  * @param subModule PWM submodule to configure
456  * @param config    Pointer to user's PWM config structure.
457  *
458  * @return kStatus_Success means success; else failed.
459  */
460 status_t PWM_Init(PWM_Type *base, pwm_submodule_t subModule, const pwm_config_t *config);
461 
462 /*!
463  * @brief Gate the PWM submodule clock
464  *
465  * @param base      PWM peripheral base address
466  * @param subModule PWM submodule to deinitialize
467  */
468 void PWM_Deinit(PWM_Type *base, pwm_submodule_t subModule);
469 
470 /*!
471  * @brief  Fill in the PWM config struct with the default settings
472  *
473  * The default values are:
474  * @code
475  *   config->enableDebugMode = false;
476  *   config->enableWait = false;
477  *   config->reloadSelect = kPWM_LocalReload;
478  *   config->clockSource = kPWM_BusClock;
479  *   config->prescale = kPWM_Prescale_Divide_1;
480  *   config->initializationControl = kPWM_Initialize_LocalSync;
481  *   config->forceTrigger = kPWM_Force_Local;
482  *   config->reloadFrequency = kPWM_LoadEveryOportunity;
483  *   config->reloadLogic = kPWM_ReloadImmediate;
484  *   config->pairOperation = kPWM_Independent;
485  * @endcode
486  * @param config Pointer to user's PWM config structure.
487  */
488 void PWM_GetDefaultConfig(pwm_config_t *config);
489 
490 /*! @}*/
491 
492 /*!
493  * @name Module PWM output
494  * @{
495  */
496 /*!
497  * @brief Sets up the PWM signals for a PWM submodule.
498  *
499  * The function initializes the submodule according to the parameters passed in by the user. The function
500  * also sets up the value compare registers to match the PWM signal requirements.
501  * If the dead time insertion logic is enabled, the pulse period is reduced by the
502  * dead time period specified by the user.
503  *
504  * @param base        PWM peripheral base address
505  * @param subModule   PWM submodule to configure
506  * @param chnlParams  Array of PWM channel parameters to configure the channel(s), PWMX submodule is not supported.
507  * @param numOfChnls  Number of channels to configure, this should be the size of the array passed in.
508  *                    Array size should not be more than 2 as each submodule has 2 pins to output PWM
509  * @param mode        PWM operation mode, options available in enumeration ::pwm_mode_t
510  * @param pwmFreq_Hz  PWM signal frequency in Hz
511  * @param srcClock_Hz PWM source clock of correspond submodule in Hz. If source clock of submodule1,2,3 is from
512  *                    submodule0 AUX_CLK, its source clock is submodule0 source clock divided with submodule0
513  *                    prescaler value instead of submodule0 source clock.
514  *
515  * @return Returns kStatus_Fail if there was error setting up the signal; kStatus_Success otherwise
516  */
517 status_t PWM_SetupPwm(PWM_Type *base,
518                       pwm_submodule_t subModule,
519                       const pwm_signal_param_t *chnlParams,
520                       uint8_t numOfChnls,
521                       pwm_mode_t mode,
522                       uint32_t pwmFreq_Hz,
523                       uint32_t srcClock_Hz);
524 
525 /*!
526  * @brief Set PWM phase shift for PWM channel running on channel PWM_A, PWM_B which with 50% duty cycle.
527  *
528  * @param base        PWM peripheral base address
529  * @param subModule   PWM submodule to configure
530  * @param pwmChannel  PWM channel to configure
531  * @param pwmFreq_Hz  PWM signal frequency in Hz
532  * @param srcClock_Hz PWM main counter clock in Hz.
533  * @param shiftvalue  Phase shift value, range in 0 ~ 50
534  * @param doSync      true: Set LDOK bit for the submodule list;
535  *                    false: LDOK bit don't set, need to call PWM_SetPwmLdok to sync update.
536  *
537  * @return Returns kStatus_Fail if there was error setting up the signal; kStatus_Success otherwise
538  */
539 status_t PWM_SetupPwmPhaseShift(PWM_Type *base,
540                                 pwm_submodule_t subModule,
541                                 pwm_channels_t pwmChannel,
542                                 uint32_t pwmFreq_Hz,
543                                 uint32_t srcClock_Hz,
544                                 uint8_t shiftvalue,
545                                 bool doSync);
546 
547 /*!
548  * @brief Updates the PWM signal's dutycycle.
549  *
550  * The function updates the PWM dutycyle to the new value that is passed in.
551  * If the dead time insertion logic is enabled then the pulse period is reduced by the
552  * dead time period specified by the user.
553  *
554  * @param base              PWM peripheral base address
555  * @param subModule         PWM submodule to configure
556  * @param pwmSignal         Signal (PWM A or PWM B) to update
557  * @param currPwmMode       The current PWM mode set during PWM setup
558  * @param dutyCyclePercent  New PWM pulse width, value should be between 0 to 100
559  *                          0=inactive signal(0% duty cycle)...
560  *                          100=active signal (100% duty cycle)
561  */
562 void PWM_UpdatePwmDutycycle(PWM_Type *base,
563                             pwm_submodule_t subModule,
564                             pwm_channels_t pwmSignal,
565                             pwm_mode_t currPwmMode,
566                             uint8_t dutyCyclePercent);
567 
568 /*!
569  * @brief Updates the PWM signal's dutycycle with 16-bit accuracy.
570  *
571  * The function updates the PWM dutycyle to the new value that is passed in.
572  * If the dead time insertion logic is enabled then the pulse period is reduced by the
573  * dead time period specified by the user.
574  *
575  * @param base              PWM peripheral base address
576  * @param subModule         PWM submodule to configure
577  * @param pwmSignal         Signal (PWM A or PWM B) to update
578  * @param currPwmMode       The current PWM mode set during PWM setup
579  * @param dutyCycle         New PWM pulse width, value should be between 0 to 65535
580  *                          0=inactive signal(0% duty cycle)...
581  *                          65535=active signal (100% duty cycle)
582  */
583 void PWM_UpdatePwmDutycycleHighAccuracy(
584     PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmSignal, pwm_mode_t currPwmMode, uint16_t dutyCycle);
585 
586 /*!
587  * @brief Update the PWM signal's period and dutycycle for a PWM submodule.
588  *
589  * The function updates PWM signal period generated by a specific submodule according to the parameters
590  * passed in by the user. This function can also set dutycycle weather you want to keep original dutycycle
591  * or update new dutycycle. Call this function in local sync control mode because PWM period is depended by
592  * INIT and VAL1 register of each submodule. In master sync initialization control mode, call this function
593  * to update INIT and VAL1 register of all submodule because PWM period is depended by INIT and VAL1 register
594  * in submodule0. If the dead time insertion logic is enabled, the pulse period is reduced by the dead time
595  * period specified by the user. PWM signal will not be generated if its period is less than dead time duration.
596  *
597  * @param base        PWM peripheral base address
598  * @param subModule   PWM submodule to configure
599  * @param pwmSignal   Signal (PWM A or PWM B) to update
600  * @param currPwmMode The current PWM mode set during PWM setup, options available in enumeration ::pwm_mode_t
601  * @param pulseCnt    New PWM period, value should be between 0 to 65535
602  *                    0=minimum PWM period...
603  *                    65535=maximum PWM period
604  * @param dutyCycle   New PWM pulse width of channel, value should be between 0 to 65535
605  *                    0=inactive signal(0% duty cycle)...
606  *                    65535=active signal (100% duty cycle)
607  *                    You can keep original duty cycle or update new duty cycle
608  */
609 void PWM_UpdatePwmPeriodAndDutycycle(PWM_Type *base,
610                                          pwm_submodule_t subModule,
611                                          pwm_channels_t pwmSignal,
612                                          pwm_mode_t currPwmMode,
613                                          uint16_t pulseCnt,
614                                          uint16_t dutyCycle);
615 
616 /*! @}*/
617 
618 /*!
619  * @brief Sets up the PWM input capture
620  *
621  * Each PWM submodule has 3 pins that can be configured for use as input capture pins. This function
622  * sets up the capture parameters for each pin and enables the pin for input capture operation.
623  *
624  * @param base               PWM peripheral base address
625  * @param subModule          PWM submodule to configure
626  * @param pwmChannel         Channel in the submodule to setup
627  * @param inputCaptureParams Parameters passed in to set up the input pin
628  */
629 void PWM_SetupInputCapture(PWM_Type *base,
630                            pwm_submodule_t subModule,
631                            pwm_channels_t pwmChannel,
632                            const pwm_input_capture_param_t *inputCaptureParams);
633 
634 /*!
635  * @brief Sets up the PWM fault input filter.
636  *
637  * @param base                   PWM peripheral base address
638  * @param faultInputFilterParams Parameters passed in to set up the fault input filter.
639  */
640 void PWM_SetupFaultInputFilter(PWM_Type *base, const pwm_fault_input_filter_param_t *faultInputFilterParams);
641 
642 /*!
643  * @brief Sets up the PWM fault protection.
644  *
645  * PWM has 4 fault inputs.
646  *
647  * @param base        PWM peripheral base address
648  * @param faultNum    PWM fault to configure.
649  * @param faultParams Pointer to the PWM fault config structure
650  */
651 void PWM_SetupFaults(PWM_Type *base, pwm_fault_input_t faultNum, const pwm_fault_param_t *faultParams);
652 
653 /*!
654  * @brief  Fill in the PWM fault config struct with the default settings
655  *
656  * The default values are:
657  * @code
658  *   config->faultClearingMode = kPWM_Automatic;
659  *   config->faultLevel = false;
660  *   config->enableCombinationalPath = true;
661  *   config->recoverMode = kPWM_NoRecovery;
662  * @endcode
663  * @param config Pointer to user's PWM fault config structure.
664  */
665 void PWM_FaultDefaultConfig(pwm_fault_param_t *config);
666 
667 /*!
668  * @brief Selects the signal to output on a PWM pin when a FORCE_OUT signal is asserted.
669  *
670  * The user specifies which channel to configure by supplying the submodule number and whether
671  * to modify PWM A or PWM B within that submodule.
672  *
673  * @param base       PWM peripheral base address
674  * @param subModule  PWM submodule to configure
675  * @param pwmChannel Channel to configure
676  * @param mode       Signal to output when a FORCE_OUT is triggered
677  */
678 void PWM_SetupForceSignal(PWM_Type *base,
679                           pwm_submodule_t subModule,
680                           pwm_channels_t pwmChannel,
681                           pwm_force_signal_t mode);
682 
683 /*!
684  * @name Interrupts Interface
685  * @{
686  */
687 
688 /*!
689  * @brief Enables the selected PWM interrupts
690  *
691  * @param base      PWM peripheral base address
692  * @param subModule PWM submodule to configure
693  * @param mask      The interrupts to enable. This is a logical OR of members of the
694  *                  enumeration ::pwm_interrupt_enable_t
695  */
696 void PWM_EnableInterrupts(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask);
697 
698 /*!
699  * @brief Disables the selected PWM interrupts
700  *
701  * @param base      PWM peripheral base address
702  * @param subModule PWM submodule to configure
703  * @param mask      The interrupts to enable. This is a logical OR of members of the
704  *                  enumeration ::pwm_interrupt_enable_t
705  */
706 void PWM_DisableInterrupts(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask);
707 
708 /*!
709  * @brief Gets the enabled PWM interrupts
710  *
711  * @param base      PWM peripheral base address
712  * @param subModule PWM submodule to configure
713  *
714  * @return The enabled interrupts. This is the logical OR of members of the
715  *         enumeration ::pwm_interrupt_enable_t
716  */
717 uint32_t PWM_GetEnabledInterrupts(PWM_Type *base, pwm_submodule_t subModule);
718 
719 /*! @}*/
720 
721 /*!
722  * @name DMA Interface
723  * @{
724  */
725 
726 /*!
727  * @brief Capture DMA Enable Source Select.
728  *
729  * @param base                  PWM peripheral base address
730  * @param subModule             PWM submodule to configure
731  * @param pwm_watermark_control PWM FIFO watermark and control
732  */
PWM_DMAFIFOWatermarkControl(PWM_Type * base,pwm_submodule_t subModule,pwm_watermark_control_t pwm_watermark_control)733 static inline void PWM_DMAFIFOWatermarkControl(PWM_Type *base,
734                                                pwm_submodule_t subModule,
735                                                pwm_watermark_control_t pwm_watermark_control)
736 {
737     uint16_t reg = base->SM[subModule].DMAEN;
738     if (pwm_watermark_control == kPWM_FIFOWatermarksOR)
739     {
740         reg &= ~((uint16_t)PWM_DMAEN_FAND_MASK);
741     }
742     else
743     {
744         reg |= ((uint16_t)PWM_DMAEN_FAND_MASK);
745     }
746     base->SM[subModule].DMAEN = reg;
747 }
748 
749 /*!
750  * @brief Capture DMA Enable Source Select.
751  *
752  * @param base                  PWM peripheral base address
753  * @param subModule             PWM submodule to configure
754  * @param pwm_dma_source_select PWM capture DMA enable source select
755  */
PWM_DMACaptureSourceSelect(PWM_Type * base,pwm_submodule_t subModule,pwm_dma_source_select_t pwm_dma_source_select)756 static inline void PWM_DMACaptureSourceSelect(PWM_Type *base,
757                                               pwm_submodule_t subModule,
758                                               pwm_dma_source_select_t pwm_dma_source_select)
759 {
760     uint16_t reg = base->SM[subModule].DMAEN;
761 
762     reg &= ~((uint16_t)PWM_DMAEN_CAPTDE_MASK);
763     reg |= (((uint16_t)pwm_dma_source_select << (uint16_t)PWM_DMAEN_CAPTDE_SHIFT) & (uint16_t)PWM_DMAEN_CAPTDE_MASK);
764 
765     base->SM[subModule].DMAEN = reg;
766 }
767 
768 /*!
769  * @brief Enables or disables the selected PWM DMA Capture read request.
770  *
771  * @param base      PWM peripheral base address
772  * @param subModule PWM submodule to configure
773  * @param mask      The DMA to enable or disable. This is a logical OR of members of the
774  *                  enumeration ::pwm_dma_enable_t
775  * @param activate  true: Enable DMA read request; false: Disable DMA read request
776  */
PWM_EnableDMACapture(PWM_Type * base,pwm_submodule_t subModule,uint16_t mask,bool activate)777 static inline void PWM_EnableDMACapture(PWM_Type *base, pwm_submodule_t subModule, uint16_t mask, bool activate)
778 {
779     uint16_t reg = base->SM[subModule].DMAEN;
780     if (activate)
781     {
782         reg |= (uint16_t)(mask);
783     }
784     else
785     {
786         reg &= ~((uint16_t)(mask));
787     }
788     base->SM[subModule].DMAEN = reg;
789 }
790 
791 /*!
792  * @brief Enables or disables the PWM DMA write request.
793  *
794  * @param base      PWM peripheral base address
795  * @param subModule PWM submodule to configure
796  * @param activate  true: Enable DMA write request; false: Disable DMA write request
797  */
PWM_EnableDMAWrite(PWM_Type * base,pwm_submodule_t subModule,bool activate)798 static inline void PWM_EnableDMAWrite(PWM_Type *base, pwm_submodule_t subModule, bool activate)
799 {
800     uint16_t reg = base->SM[subModule].DMAEN;
801     if (activate)
802     {
803         reg |= ((uint16_t)PWM_DMAEN_VALDE_MASK);
804     }
805     else
806     {
807         reg &= ~((uint16_t)PWM_DMAEN_VALDE_MASK);
808     }
809     base->SM[subModule].DMAEN = reg;
810 }
811 
812 /*! @}*/
813 
814 /*!
815  * @name Status Interface
816  * @{
817  */
818 
819 /*!
820  * @brief Gets the PWM status flags
821  *
822  * @param base      PWM peripheral base address
823  * @param subModule PWM submodule to configure
824  *
825  * @return The status flags. This is the logical OR of members of the
826  *         enumeration ::pwm_status_flags_t
827  */
828 uint32_t PWM_GetStatusFlags(PWM_Type *base, pwm_submodule_t subModule);
829 
830 /*!
831  * @brief Clears the PWM status flags
832  *
833  * @param base      PWM peripheral base address
834  * @param subModule PWM submodule to configure
835  * @param mask      The status flags to clear. This is a logical OR of members of the
836  *                  enumeration ::pwm_status_flags_t
837  */
838 void PWM_ClearStatusFlags(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask);
839 
840 /*! @}*/
841 
842 /*!
843  * @name Timer Start and Stop
844  * @{
845  */
846 
847 /*!
848  * @brief Starts the PWM counter for a single or multiple submodules.
849  *
850  * Sets the Run bit which enables the clocks to the PWM submodule. This function can start multiple
851  * submodules at the same time.
852  *
853  * @param base              PWM peripheral base address
854  * @param subModulesToStart PWM submodules to start. This is a logical OR of members of the
855  *                          enumeration ::pwm_module_control_t
856  */
PWM_StartTimer(PWM_Type * base,uint8_t subModulesToStart)857 static inline void PWM_StartTimer(PWM_Type *base, uint8_t subModulesToStart)
858 {
859     base->MCTRL |= PWM_MCTRL_RUN(subModulesToStart);
860 }
861 
862 /*!
863  * @brief Stops the PWM counter for a single or multiple submodules.
864  *
865  * Clears the Run bit which resets the submodule's counter. This function can stop multiple
866  * submodules at the same time.
867  *
868  * @param base             PWM peripheral base address
869  * @param subModulesToStop PWM submodules to stop. This is a logical OR of members of the
870  *                         enumeration ::pwm_module_control_t
871  */
PWM_StopTimer(PWM_Type * base,uint8_t subModulesToStop)872 static inline void PWM_StopTimer(PWM_Type *base, uint8_t subModulesToStop)
873 {
874     base->MCTRL &= ~(PWM_MCTRL_RUN(subModulesToStop));
875 }
876 
877 /*! @}*/
878 
879 /*!
880  * @brief Set the PWM VALx registers.
881  *
882  * This function allows the user to write value into VAL registers directly. And it will destroying the PWM clock period
883  * set by the PWM_SetupPwm()/PWM_SetupPwmPhaseShift() functions.
884  * Due to VALx registers are bufferd, the new value will not active uless call PWM_SetPwmLdok() and the reload point is
885  * reached.
886  *
887  * @param base          PWM peripheral base address
888  * @param subModule     PWM submodule to configure
889  * @param valueRegister VALx register that will be writen new value
890  * @param value         Value that will been write into VALx register
891  */
PWM_SetVALxValue(PWM_Type * base,pwm_submodule_t subModule,pwm_value_register_t valueRegister,uint16_t value)892 static inline void PWM_SetVALxValue(PWM_Type *base,
893                                     pwm_submodule_t subModule,
894                                     pwm_value_register_t valueRegister,
895                                     uint16_t value)
896 {
897     switch (valueRegister)
898     {
899         case kPWM_ValueRegister_0:
900             base->SM[subModule].VAL0 = value;
901             break;
902         case kPWM_ValueRegister_1:
903             base->SM[subModule].VAL1 = value;
904             break;
905         case kPWM_ValueRegister_2:
906             base->SM[subModule].VAL2 = value;
907             break;
908         case kPWM_ValueRegister_3:
909             base->SM[subModule].VAL3 = value;
910             break;
911         case kPWM_ValueRegister_4:
912             base->SM[subModule].VAL4 = value;
913             break;
914         case kPWM_ValueRegister_5:
915             base->SM[subModule].VAL5 = value;
916             break;
917         default:
918             assert(false);
919             break;
920     }
921 }
922 
923 /*!
924  * @brief Get the PWM VALx registers.
925  *
926  * @param base          PWM peripheral base address
927  * @param subModule     PWM submodule to configure
928  * @param valueRegister VALx register that will be read value
929  * @return The VALx register value
930  */
PWM_GetVALxValue(PWM_Type * base,pwm_submodule_t subModule,pwm_value_register_t valueRegister)931 static inline uint16_t PWM_GetVALxValue(PWM_Type *base, pwm_submodule_t subModule, pwm_value_register_t valueRegister)
932 {
933     uint16_t temp = 0U;
934 
935     switch (valueRegister)
936     {
937         case kPWM_ValueRegister_0:
938             temp = base->SM[subModule].VAL0;
939             break;
940         case kPWM_ValueRegister_1:
941             temp = base->SM[subModule].VAL1;
942             break;
943         case kPWM_ValueRegister_2:
944             temp = base->SM[subModule].VAL2;
945             break;
946         case kPWM_ValueRegister_3:
947             temp = base->SM[subModule].VAL3;
948             break;
949         case kPWM_ValueRegister_4:
950             temp = base->SM[subModule].VAL4;
951             break;
952         case kPWM_ValueRegister_5:
953             temp = base->SM[subModule].VAL5;
954             break;
955         default:
956             assert(false);
957             break;
958     }
959 
960     return temp;
961 }
962 
963 /*!
964  * @brief Enables or disables the PWM output trigger.
965  *
966  * This function allows the user to enable or disable the PWM trigger. The PWM has 2 triggers. Trigger 0
967  * is activated when the counter matches VAL 0, VAL 2, or VAL 4 register. Trigger 1 is activated
968  * when the counter matches VAL 1, VAL 3, or VAL 5 register.
969  *
970  * @param base          PWM peripheral base address
971  * @param subModule     PWM submodule to configure
972  * @param valueRegister Value register that will activate the trigger
973  * @param activate      true: Enable the trigger; false: Disable the trigger
974  */
PWM_OutputTriggerEnable(PWM_Type * base,pwm_submodule_t subModule,pwm_value_register_t valueRegister,bool activate)975 static inline void PWM_OutputTriggerEnable(PWM_Type *base,
976                                            pwm_submodule_t subModule,
977                                            pwm_value_register_t valueRegister,
978                                            bool activate)
979 {
980     if (activate)
981     {
982         base->SM[subModule].TCTRL |= ((uint16_t)1U << (uint16_t)valueRegister);
983     }
984     else
985     {
986         base->SM[subModule].TCTRL &= ~((uint16_t)1U << (uint16_t)valueRegister);
987     }
988 }
989 
990 /*!
991  * @brief Enables the PWM output trigger.
992  *
993  * This function allows the user to enable one or more (VAL0-5) PWM trigger.
994  *
995  * @param base              PWM peripheral base address
996  * @param subModule         PWM submodule to configure
997  * @param valueRegisterMask Value register mask that will activate one or more (VAL0-5) trigger
998  *                          enumeration ::_pwm_value_register_mask
999  */
PWM_ActivateOutputTrigger(PWM_Type * base,pwm_submodule_t subModule,uint16_t valueRegisterMask)1000 static inline void PWM_ActivateOutputTrigger(PWM_Type *base, pwm_submodule_t subModule, uint16_t valueRegisterMask)
1001 {
1002     base->SM[subModule].TCTRL |= (PWM_TCTRL_OUT_TRIG_EN_MASK & (valueRegisterMask));
1003 }
1004 
1005 /*!
1006  * @brief Disables the PWM output trigger.
1007  *
1008  * This function allows the user to disables one or more (VAL0-5) PWM trigger.
1009  *
1010  * @param base              PWM peripheral base address
1011  * @param subModule         PWM submodule to configure
1012  * @param valueRegisterMask Value register mask that will Deactivate one or more (VAL0-5) trigger
1013  *                          enumeration ::_pwm_value_register_mask
1014  */
PWM_DeactivateOutputTrigger(PWM_Type * base,pwm_submodule_t subModule,uint16_t valueRegisterMask)1015 static inline void PWM_DeactivateOutputTrigger(PWM_Type *base, pwm_submodule_t subModule, uint16_t valueRegisterMask)
1016 {
1017     base->SM[subModule].TCTRL &= ~(PWM_TCTRL_OUT_TRIG_EN_MASK & (valueRegisterMask));
1018 }
1019 
1020 /*!
1021  * @brief Sets the software control output for a pin to high or low.
1022  *
1023  * The user specifies which channel to modify by supplying the submodule number and whether
1024  * to modify PWM A or PWM B within that submodule.
1025  *
1026  * @param base       PWM peripheral base address
1027  * @param subModule  PWM submodule to configure
1028  * @param pwmChannel Channel to configure
1029  * @param value      true: Supply a logic 1, false: Supply a logic 0.
1030  */
PWM_SetupSwCtrlOut(PWM_Type * base,pwm_submodule_t subModule,pwm_channels_t pwmChannel,bool value)1031 static inline void PWM_SetupSwCtrlOut(PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmChannel, bool value)
1032 {
1033     if (value)
1034     {
1035         base->SWCOUT |=
1036             ((uint16_t)1U << (((uint16_t)subModule * (uint16_t)PWM_SUBMODULE_SWCONTROL_WIDTH) + (uint16_t)pwmChannel));
1037     }
1038     else
1039     {
1040         base->SWCOUT &=
1041             ~((uint16_t)1U << (((uint16_t)subModule * (uint16_t)PWM_SUBMODULE_SWCONTROL_WIDTH) + (uint16_t)pwmChannel));
1042     }
1043 }
1044 
1045 /*!
1046  * @brief Sets or clears the PWM LDOK bit on a single or multiple submodules
1047  *
1048  * Set LDOK bit to load buffered values into CTRL[PRSC] and the INIT, FRACVAL and VAL registers. The
1049  * values are loaded immediately if kPWM_ReloadImmediate option was choosen during config. Else the
1050  * values are loaded at the next PWM reload point.
1051  * This function can issue the load command to multiple submodules at the same time.
1052  *
1053  * @param base               PWM peripheral base address
1054  * @param subModulesToUpdate PWM submodules to update with buffered values. This is a logical OR of
1055  *                           members of the enumeration ::pwm_module_control_t
1056  * @param value              true: Set LDOK bit for the submodule list; false: Clear LDOK bit
1057  */
PWM_SetPwmLdok(PWM_Type * base,uint8_t subModulesToUpdate,bool value)1058 static inline void PWM_SetPwmLdok(PWM_Type *base, uint8_t subModulesToUpdate, bool value)
1059 {
1060     if (value)
1061     {
1062         base->MCTRL |= PWM_MCTRL_LDOK(subModulesToUpdate);
1063     }
1064     else
1065     {
1066         base->MCTRL |= PWM_MCTRL_CLDOK(subModulesToUpdate);
1067     }
1068 }
1069 
1070 /*!
1071  * @brief Set PWM output fault status
1072  *
1073  * These bits determine the fault state for the PWM_A output in fault conditions
1074  * and STOP mode. It may also define the output state in WAIT and DEBUG modes
1075  * depending on the settings of CTRL2[WAITEN] and CTRL2[DBGEN].
1076  * This function can update PWM output fault status.
1077  *
1078  * @param base       PWM peripheral base address
1079  * @param subModule  PWM submodule to configure
1080  * @param pwmChannel Channel to configure
1081  * @param faultState PWM output fault status
1082  */
PWM_SetPwmFaultState(PWM_Type * base,pwm_submodule_t subModule,pwm_channels_t pwmChannel,pwm_fault_state_t faultState)1083 static inline void PWM_SetPwmFaultState(PWM_Type *base,
1084                                         pwm_submodule_t subModule,
1085                                         pwm_channels_t pwmChannel,
1086                                         pwm_fault_state_t faultState)
1087 {
1088     uint16_t reg = base->SM[subModule].OCTRL;
1089     switch (pwmChannel)
1090     {
1091         case kPWM_PwmA:
1092             reg &= ~((uint16_t)PWM_OCTRL_PWMAFS_MASK);
1093             reg |= (((uint16_t)faultState << (uint16_t)PWM_OCTRL_PWMAFS_SHIFT) & (uint16_t)PWM_OCTRL_PWMAFS_MASK);
1094             break;
1095         case kPWM_PwmB:
1096             reg &= ~((uint16_t)PWM_OCTRL_PWMBFS_MASK);
1097             reg |= (((uint16_t)faultState << (uint16_t)PWM_OCTRL_PWMBFS_SHIFT) & (uint16_t)PWM_OCTRL_PWMBFS_MASK);
1098             break;
1099         case kPWM_PwmX:
1100             reg &= ~((uint16_t)PWM_OCTRL_PWMXFS_MASK);
1101             reg |= (((uint16_t)faultState << (uint16_t)PWM_OCTRL_PWMXFS_SHIFT) & (uint16_t)PWM_OCTRL_PWMXFS_MASK);
1102             break;
1103         default:
1104             assert(false);
1105             break;
1106     }
1107     base->SM[subModule].OCTRL = reg;
1108 }
1109 
1110 /*!
1111  * @brief Set PWM fault disable mapping
1112  *
1113  * Each of the four bits of this read/write field is one-to-one associated
1114  * with the four FAULTx inputs of fault channel 0/1. The PWM output will be turned
1115  * off if there is a logic 1 on an FAULTx input and a 1 in the corresponding
1116  * bit of this field. A reset sets all bits in this field.
1117  *
1118  * @param base               PWM peripheral base address
1119  * @param subModule          PWM submodule to configure
1120  * @param pwmChannel         PWM channel to configure
1121  * @param pwm_fault_channels PWM fault channel to configure
1122  * @param value              Fault disable mapping mask value
1123  *                           enumeration ::pwm_fault_disable_t
1124  */
PWM_SetupFaultDisableMap(PWM_Type * base,pwm_submodule_t subModule,pwm_channels_t pwmChannel,pwm_fault_channels_t pwm_fault_channels,uint16_t value)1125 static inline void PWM_SetupFaultDisableMap(PWM_Type *base,
1126                                             pwm_submodule_t subModule,
1127                                             pwm_channels_t pwmChannel,
1128                                             pwm_fault_channels_t pwm_fault_channels,
1129                                             uint16_t value)
1130 {
1131     uint16_t reg = base->SM[subModule].DISMAP[pwm_fault_channels];
1132     switch (pwmChannel)
1133     {
1134         case kPWM_PwmA:
1135             reg &= ~((uint16_t)PWM_DISMAP_DIS0A_MASK);
1136             reg |= (((uint16_t)(value) << (uint16_t)PWM_DISMAP_DIS0A_SHIFT) & (uint16_t)PWM_DISMAP_DIS0A_MASK);
1137             break;
1138         case kPWM_PwmB:
1139             reg &= ~((uint16_t)PWM_DISMAP_DIS0B_MASK);
1140             reg |= (((uint16_t)(value) << (uint16_t)PWM_DISMAP_DIS0B_SHIFT) & (uint16_t)PWM_DISMAP_DIS0B_MASK);
1141             break;
1142         case kPWM_PwmX:
1143             reg &= ~((uint16_t)PWM_DISMAP_DIS0X_MASK);
1144             reg |= (((uint16_t)(value) << (uint16_t)PWM_DISMAP_DIS0X_SHIFT) & (uint16_t)PWM_DISMAP_DIS0X_MASK);
1145             break;
1146         default:
1147             assert(false);
1148             break;
1149     }
1150     base->SM[subModule].DISMAP[pwm_fault_channels] = reg;
1151 }
1152 
1153 /*!
1154  * @brief Set PWM output enable
1155  *
1156  * This feature allows the user to enable the PWM Output.
1157  *
1158  * @param base               PWM peripheral base address
1159  * @param pwmChannel         PWM channel to configure
1160  * @param subModule          PWM submodule to configure
1161  */
PWM_OutputEnable(PWM_Type * base,pwm_channels_t pwmChannel,pwm_submodule_t subModule)1162 static inline void PWM_OutputEnable(PWM_Type *base, pwm_channels_t pwmChannel, pwm_submodule_t subModule)
1163 {
1164     /* Set PWM output */
1165     switch (pwmChannel)
1166     {
1167         case kPWM_PwmA:
1168             base->OUTEN |= ((uint16_t)1U << ((uint16_t)PWM_OUTEN_PWMA_EN_SHIFT + (uint16_t)subModule));
1169             break;
1170         case kPWM_PwmB:
1171             base->OUTEN |= ((uint16_t)1U << ((uint16_t)PWM_OUTEN_PWMB_EN_SHIFT + (uint16_t)subModule));
1172             break;
1173         case kPWM_PwmX:
1174             base->OUTEN |= ((uint16_t)1U << ((uint16_t)PWM_OUTEN_PWMX_EN_SHIFT + (uint16_t)subModule));
1175             break;
1176         default:
1177             assert(false);
1178             break;
1179     }
1180 }
1181 
1182 /*!
1183  * @brief Set PWM output disable
1184  *
1185  *This feature allows the user to disable the PWM output.
1186  *
1187  * @param base               PWM peripheral base address
1188  * @param pwmChannel         PWM channel to configure
1189  * @param subModule          PWM submodule to configure
1190  */
PWM_OutputDisable(PWM_Type * base,pwm_channels_t pwmChannel,pwm_submodule_t subModule)1191 static inline void PWM_OutputDisable(PWM_Type *base, pwm_channels_t pwmChannel, pwm_submodule_t subModule)
1192 {
1193     switch (pwmChannel)
1194     {
1195         case kPWM_PwmA:
1196             base->OUTEN &= ~((uint16_t)1U << ((uint16_t)PWM_OUTEN_PWMA_EN_SHIFT + (uint16_t)subModule));
1197             break;
1198         case kPWM_PwmB:
1199             base->OUTEN &= ~((uint16_t)1U << ((uint16_t)PWM_OUTEN_PWMB_EN_SHIFT + (uint16_t)subModule));
1200             break;
1201         case kPWM_PwmX:
1202             base->OUTEN &= ~((uint16_t)1U << ((uint16_t)PWM_OUTEN_PWMX_EN_SHIFT + (uint16_t)subModule));
1203             break;
1204         default:
1205             assert(false);
1206             break;
1207     }
1208 }
1209 
1210 /*!
1211  * @brief Get the dutycycle value.
1212  *
1213  * @param base        PWM peripheral base address
1214  * @param subModule   PWM submodule to configure
1215  * @param pwmChannel  PWM channel to configure
1216  *
1217  * @return Current channel dutycycle value.
1218  */
1219 uint8_t PWM_GetPwmChannelState(PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmChannel);
1220 
1221 /*!
1222  * @brief Set PWM output in idle status (high or low).
1223  *
1224  * @note This API should call after PWM_SetupPwm() APIs, and PWMX submodule is not supported.
1225  *
1226  * @param base               PWM peripheral base address
1227  * @param pwmChannel         PWM channel to configure
1228  * @param subModule          PWM submodule to configure
1229  * @param idleStatus         True: PWM output is high in idle status; false: PWM output is low in idle status.
1230  *
1231  * @return kStatus_Fail if there was error setting up the signal; kStatus_Success if set output idle success
1232  */
1233 status_t PWM_SetOutputToIdle(PWM_Type *base, pwm_channels_t pwmChannel, pwm_submodule_t subModule, bool idleStatus);
1234 
1235 /*!
1236  * @brief Set the pwm submodule prescaler.
1237  *
1238  * @param base               PWM peripheral base address
1239  * @param subModule          PWM submodule to configure
1240  * @param prescaler          Set prescaler value
1241  */
1242 void PWM_SetClockMode(PWM_Type *base, pwm_submodule_t subModule, pwm_clock_prescale_t prescaler);
1243 
1244 /*!
1245  * @brief This function enables-disables the forcing of the output of a given eFlexPwm channel to logic 0.
1246  *
1247  * @param base               PWM peripheral base address
1248  * @param pwmChannel         PWM channel to configure
1249  * @param subModule          PWM submodule to configure
1250  * @param forcetozero        True: Enable the pwm force output to zero; False: Disable the pwm output resumes normal
1251  *                           function.
1252  */
1253 void PWM_SetPwmForceOutputToZero(PWM_Type *base,
1254                                  pwm_submodule_t subModule,
1255                                  pwm_channels_t pwmChannel,
1256                                  bool forcetozero);
1257 
1258 /*!
1259  * @brief This function set the output state of the PWM pin as requested for the current cycle.
1260  *
1261  * @param base               PWM peripheral base address
1262  * @param subModule          PWM submodule to configure
1263  * @param pwmChannel         PWM channel to configure
1264  * @param outputstate        Set pwm output state, see @ref pwm_output_state_t.
1265  */
1266 void PWM_SetChannelOutput(PWM_Type *base,
1267                           pwm_submodule_t subModule,
1268                           pwm_channels_t pwmChannel,
1269                           pwm_output_state_t outputstate);
1270 
1271 #if defined(FSL_FEATURE_PWM_HAS_PHASE_DELAY) && FSL_FEATURE_PWM_HAS_PHASE_DELAY
1272 /*!
1273  * @brief This function set the phase delay from the master sync signal of submodule 0.
1274  *
1275  * @param base               PWM peripheral base address
1276  * @param subModule          PWM submodule to configure
1277  * @param pwmChannel         PWM channel to configure
1278  * @param delayCycles        Number of cycles delayed from submodule 0.
1279  *
1280  * @return kStatus_Fail if the number of delay cycles is set larger than the period defined in submodule 0;
1281  *        kStatus_Success if set phase delay success
1282  */
1283 status_t PWM_SetPhaseDelay(PWM_Type *base, pwm_channels_t pwmChannel, pwm_submodule_t subModule, uint16_t delayCycles);
1284 #endif
1285 
1286 #if defined(FSL_FEATURE_PWM_HAS_INPUT_FILTER_CAPTURE) && FSL_FEATURE_PWM_HAS_INPUT_FILTER_CAPTURE
1287 /*!
1288  * @brief This function set the number of consecutive samples that must agree prior to the input filter.
1289  *
1290  * @param base               PWM peripheral base address
1291  * @param subModule          PWM submodule to configure
1292  * @param pwmChannel         PWM channel to configure
1293  * @param filterSampleCount  Number of consecutive samples.
1294  */
PWM_SetFilterSampleCount(PWM_Type * base,pwm_channels_t pwmChannel,pwm_submodule_t subModule,uint8_t filterSampleCount)1295 static inline void PWM_SetFilterSampleCount(PWM_Type *base,
1296                                              pwm_channels_t pwmChannel,
1297                                              pwm_submodule_t subModule,
1298                                              uint8_t filterSampleCount)
1299 {
1300     switch(pwmChannel)
1301     {
1302 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA
1303         case kPWM_PwmA:
1304             base->SM[subModule].CAPTFILTA &= ~((uint16_t)PWM_CAPTFILTA_CAPTA_FILT_CNT_MASK);
1305             base->SM[subModule].CAPTFILTA |= PWM_CAPTFILTA_CAPTA_FILT_CNT(filterSampleCount);
1306             break;
1307 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA */
1308 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB
1309         case kPWM_PwmB:
1310             base->SM[subModule].CAPTFILTB &= ~((uint16_t)PWM_CAPTFILTB_CAPTB_FILT_CNT_MASK);
1311             base->SM[subModule].CAPTFILTB |= PWM_CAPTFILTB_CAPTB_FILT_CNT(filterSampleCount);
1312             break;
1313 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB */
1314 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX
1315         case kPWM_PwmX:
1316             base->SM[subModule].CAPTFILTX &= ~((uint16_t)PWM_CAPTFILTX_CAPTX_FILT_CNT_MASK);
1317             base->SM[subModule].CAPTFILTX |= PWM_CAPTFILTX_CAPTX_FILT_CNT(filterSampleCount);
1318             break;
1319 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX */
1320         default:
1321             assert(false);
1322             break;
1323     }
1324 }
1325 
1326 /*!
1327  * @brief This function set the sampling period of the fault pin input filter.
1328  *
1329  * @param base                 PWM peripheral base address
1330  * @param subModule            PWM submodule to configure
1331  * @param pwmChannel           PWM channel to configure
1332  * @param filterSamplePeriod   Sampling period of input filter.
1333  */
PWM_SetFilterSamplePeriod(PWM_Type * base,pwm_channels_t pwmChannel,pwm_submodule_t subModule,uint8_t filterSamplePeriod)1334 static inline void PWM_SetFilterSamplePeriod(PWM_Type *base,
1335                                              pwm_channels_t pwmChannel,
1336                                              pwm_submodule_t subModule,
1337                                              uint8_t filterSamplePeriod)
1338 {
1339     switch(pwmChannel)
1340     {
1341 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA
1342         case kPWM_PwmA:
1343             base->SM[subModule].CAPTFILTA &= ~((uint16_t)PWM_CAPTFILTA_CAPTA_FILT_PER_MASK);
1344             base->SM[subModule].CAPTFILTA |= PWM_CAPTFILTA_CAPTA_FILT_PER(filterSamplePeriod);
1345             break;
1346 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA */
1347 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB
1348         case kPWM_PwmB:
1349             base->SM[subModule].CAPTFILTB &= ~((uint16_t)PWM_CAPTFILTB_CAPTB_FILT_PER_MASK);
1350             base->SM[subModule].CAPTFILTB |= PWM_CAPTFILTB_CAPTB_FILT_PER(filterSamplePeriod);
1351             break;
1352 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB */
1353 #if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX) && FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX
1354         case kPWM_PwmX:
1355             base->SM[subModule].CAPTFILTX &= ~((uint16_t)PWM_CAPTFILTX_CAPTX_FILT_PER_MASK);
1356             base->SM[subModule].CAPTFILTX |= PWM_CAPTFILTX_CAPTX_FILT_PER(filterSamplePeriod);
1357             break;
1358 #endif /* FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX */
1359         default:
1360             assert(false);
1361             break;
1362     }
1363 }
1364 #endif
1365 
1366 #if defined(__cplusplus)
1367 }
1368 #endif
1369 
1370 /*! @}*/
1371 
1372 #endif /* FSL_PWM_H_ */
1373