1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_PIT_H_
9 #define _FSL_PIT_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup pit
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief PIT Driver Version 2.0.4 */
25 #define FSL_PIT_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
26 /*@}*/
27 
28 /*!
29  * @brief List of PIT channels
30  * @note Actual number of available channels is SoC dependent
31  */
32 typedef enum _pit_chnl
33 {
34     kPIT_Chnl_0 = 0U, /*!< PIT channel number 0*/
35     kPIT_Chnl_1,      /*!< PIT channel number 1 */
36     kPIT_Chnl_2,      /*!< PIT channel number 2 */
37     kPIT_Chnl_3,      /*!< PIT channel number 3 */
38 } pit_chnl_t;
39 
40 /*! @brief List of PIT interrupts */
41 typedef enum _pit_interrupt_enable
42 {
43     kPIT_TimerInterruptEnable = PIT_TCTRL_TIE_MASK, /*!< Timer interrupt enable*/
44 } pit_interrupt_enable_t;
45 
46 /*! @brief List of PIT status flags */
47 typedef enum _pit_status_flags
48 {
49     kPIT_TimerFlag = PIT_TFLG_TIF_MASK, /*!< Timer flag */
50 } pit_status_flags_t;
51 
52 /*!
53  * @brief PIT configuration structure
54  *
55  * This structure holds the configuration settings for the PIT peripheral. To initialize this
56  * structure to reasonable defaults, call the PIT_GetDefaultConfig() function and pass a
57  * pointer to your config structure instance.
58  *
59  * The configuration structure can be made constant so it resides in flash.
60  */
61 typedef struct _pit_config
62 {
63     bool enableRunInDebug; /*!< true: Timers run in debug mode; false: Timers stop in debug mode */
64 } pit_config_t;
65 
66 /*******************************************************************************
67  * API
68  ******************************************************************************/
69 
70 #if defined(__cplusplus)
71 extern "C" {
72 #endif
73 
74 /*!
75  * @name Initialization and deinitialization
76  * @{
77  */
78 
79 /*!
80  * @brief Ungates the PIT clock, enables the PIT module, and configures the peripheral for basic operations.
81  *
82  * @note This API should be called at the beginning of the application using the PIT driver.
83  *
84  * @param base   PIT peripheral base address
85  * @param config Pointer to the user's PIT config structure
86  */
87 void PIT_Init(PIT_Type *base, const pit_config_t *config);
88 
89 /*!
90  * @brief Gates the PIT clock and disables the PIT module.
91  *
92  * @param base PIT peripheral base address
93  */
94 void PIT_Deinit(PIT_Type *base);
95 
96 /*!
97  * @brief Fills in the PIT configuration structure with the default settings.
98  *
99  * The default values are as follows.
100  * @code
101  *     config->enableRunInDebug = false;
102  * @endcode
103  * @param config Pointer to the configuration structure.
104  */
PIT_GetDefaultConfig(pit_config_t * config)105 static inline void PIT_GetDefaultConfig(pit_config_t *config)
106 {
107     assert(NULL != config);
108 
109     /* Timers are stopped in Debug mode */
110     config->enableRunInDebug = false;
111 }
112 
113 #if defined(FSL_FEATURE_PIT_HAS_CHAIN_MODE) && FSL_FEATURE_PIT_HAS_CHAIN_MODE
114 
115 /*!
116  * @brief Enables or disables chaining a timer with the previous timer.
117  *
118  * When a timer has a chain mode enabled, it only counts after the previous
119  * timer has expired. If the timer n-1 has counted down to 0, counter n
120  * decrements the value by one. Each timer is 32-bits, which allows the developers
121  * to chain timers together and form a longer timer (64-bits and larger). The first timer
122  * (timer 0) can't be chained to any other timer.
123  *
124  * @param base    PIT peripheral base address
125  * @param channel Timer channel number which is chained with the previous timer
126  * @param enable  Enable or disable chain.
127  *                true:  Current timer is chained with the previous timer.
128  *                false: Timer doesn't chain with other timers.
129  */
PIT_SetTimerChainMode(PIT_Type * base,pit_chnl_t channel,bool enable)130 static inline void PIT_SetTimerChainMode(PIT_Type *base, pit_chnl_t channel, bool enable)
131 {
132     if (enable)
133     {
134         base->CHANNEL[channel].TCTRL |= PIT_TCTRL_CHN_MASK;
135     }
136     else
137     {
138         base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_CHN_MASK;
139     }
140 }
141 
142 #endif /* FSL_FEATURE_PIT_HAS_CHAIN_MODE */
143 
144 /*! @}*/
145 
146 /*!
147  * @name Interrupt Interface
148  * @{
149  */
150 
151 /*!
152  * @brief Enables the selected PIT interrupts.
153  *
154  * @param base    PIT peripheral base address
155  * @param channel Timer channel number
156  * @param mask    The interrupts to enable. This is a logical OR of members of the
157  *                enumeration ::pit_interrupt_enable_t
158  */
PIT_EnableInterrupts(PIT_Type * base,pit_chnl_t channel,uint32_t mask)159 static inline void PIT_EnableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
160 {
161     base->CHANNEL[channel].TCTRL |= mask;
162 }
163 
164 /*!
165  * @brief Disables the selected PIT interrupts.
166  *
167  * @param base    PIT peripheral base address
168  * @param channel Timer channel number
169  * @param mask    The interrupts to disable. This is a logical OR of members of the
170  *                enumeration ::pit_interrupt_enable_t
171  */
PIT_DisableInterrupts(PIT_Type * base,pit_chnl_t channel,uint32_t mask)172 static inline void PIT_DisableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
173 {
174     base->CHANNEL[channel].TCTRL &= ~mask;
175 }
176 
177 /*!
178  * @brief Gets the enabled PIT interrupts.
179  *
180  * @param base    PIT peripheral base address
181  * @param channel Timer channel number
182  *
183  * @return The enabled interrupts. This is the logical OR of members of the
184  *         enumeration ::pit_interrupt_enable_t
185  */
PIT_GetEnabledInterrupts(PIT_Type * base,pit_chnl_t channel)186 static inline uint32_t PIT_GetEnabledInterrupts(PIT_Type *base, pit_chnl_t channel)
187 {
188     return (base->CHANNEL[channel].TCTRL & PIT_TCTRL_TIE_MASK);
189 }
190 
191 /*! @}*/
192 
193 /*!
194  * @name Status Interface
195  * @{
196  */
197 
198 /*!
199  * @brief Gets the PIT status flags.
200  *
201  * @param base    PIT peripheral base address
202  * @param channel Timer channel number
203  *
204  * @return The status flags. This is the logical OR of members of the
205  *         enumeration ::pit_status_flags_t
206  */
PIT_GetStatusFlags(PIT_Type * base,pit_chnl_t channel)207 static inline uint32_t PIT_GetStatusFlags(PIT_Type *base, pit_chnl_t channel)
208 {
209     return (base->CHANNEL[channel].TFLG & PIT_TFLG_TIF_MASK);
210 }
211 
212 /*!
213  * @brief  Clears the PIT status flags.
214  *
215  * @param base    PIT peripheral base address
216  * @param channel Timer channel number
217  * @param mask    The status flags to clear. This is a logical OR of members of the
218  *                enumeration ::pit_status_flags_t
219  */
PIT_ClearStatusFlags(PIT_Type * base,pit_chnl_t channel,uint32_t mask)220 static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
221 {
222     base->CHANNEL[channel].TFLG = mask;
223 }
224 
225 /*! @}*/
226 
227 /*!
228  * @name Read and Write the timer period
229  * @{
230  */
231 
232 /*!
233  * @brief Sets the timer period in units of count.
234  *
235  * Timers begin counting from the value set by this function until it reaches 0,
236  * then it generates an interrupt and load this register value again.
237  * Writing a new value to this register does not restart the timer. Instead, the value
238  * is loaded after the timer expires.
239  *
240  * @note Users can call the utility macros provided in fsl_common.h to convert to ticks.
241  *
242  * @param base    PIT peripheral base address
243  * @param channel Timer channel number
244  * @param count   Timer period in units of ticks
245  */
PIT_SetTimerPeriod(PIT_Type * base,pit_chnl_t channel,uint32_t count)246 static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32_t count)
247 {
248     assert(count != 0U);
249     /* According to RM, the LDVAL trigger = clock ticks -1 */
250     base->CHANNEL[channel].LDVAL = count - 1U;
251 }
252 
253 /*!
254  * @brief Reads the current timer counting value.
255  *
256  * This function returns the real-time timer counting value, in a range from 0 to a
257  * timer period.
258  *
259  * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec.
260  *
261  * @param base    PIT peripheral base address
262  * @param channel Timer channel number
263  *
264  * @return Current timer counting value in ticks
265  */
PIT_GetCurrentTimerCount(PIT_Type * base,pit_chnl_t channel)266 static inline uint32_t PIT_GetCurrentTimerCount(PIT_Type *base, pit_chnl_t channel)
267 {
268     return base->CHANNEL[channel].CVAL;
269 }
270 
271 /*! @}*/
272 
273 /*!
274  * @name Timer Start and Stop
275  * @{
276  */
277 
278 /*!
279  * @brief Starts the timer counting.
280  *
281  * After calling this function, timers load period value, count down to 0 and
282  * then load the respective start value again. Each time a timer reaches 0,
283  * it generates a trigger pulse and sets the timeout interrupt flag.
284  *
285  * @param base    PIT peripheral base address
286  * @param channel Timer channel number.
287  */
PIT_StartTimer(PIT_Type * base,pit_chnl_t channel)288 static inline void PIT_StartTimer(PIT_Type *base, pit_chnl_t channel)
289 {
290     base->CHANNEL[channel].TCTRL |= PIT_TCTRL_TEN_MASK;
291 }
292 
293 /*!
294  * @brief Stops the timer counting.
295  *
296  * This function stops every timer counting. Timers reload their periods
297  * respectively after the next time they call the PIT_DRV_StartTimer.
298  *
299  * @param base    PIT peripheral base address
300  * @param channel Timer channel number.
301  */
PIT_StopTimer(PIT_Type * base,pit_chnl_t channel)302 static inline void PIT_StopTimer(PIT_Type *base, pit_chnl_t channel)
303 {
304     base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_TEN_MASK;
305 }
306 
307 /*! @}*/
308 
309 #if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER
310 
311 /*!
312  * @brief Reads the current lifetime counter value.
313  *
314  * The lifetime timer is a 64-bit timer which chains timer 0 and timer 1 together.
315  * Timer 0 and 1 are chained by calling the PIT_SetTimerChainMode before using this timer.
316  * The period of lifetime timer is equal to the "period of timer 0 * period of timer 1".
317  * For the 64-bit value, the higher 32-bit has the value of timer 1, and the lower 32-bit
318  * has the value of timer 0.
319  *
320  * @param base PIT peripheral base address
321  *
322  * @return Current lifetime timer value
323  */
324 uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base);
325 
326 #endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */
327 
328 #if defined(__cplusplus)
329 }
330 #endif
331 
332 /*! @}*/
333 
334 #endif /* _FSL_PIT_H_ */
335