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