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