1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2022 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #ifndef _FSL_LPIT_H_
9 #define _FSL_LPIT_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup lpit
15 * @{
16 */
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*! @name Driver version */
23 /*@{*/
24 #define FSL_LPIT_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0 */
25 /*@{*/
26
27 /*!
28 * @brief List of LPIT channels
29 * @note Actual number of available channels is SoC-dependent
30 */
31 typedef enum _lpit_chnl
32 {
33 kLPIT_Chnl_0 = 0U, /*!< LPIT channel number 0*/
34 kLPIT_Chnl_1, /*!< LPIT channel number 1 */
35 kLPIT_Chnl_2, /*!< LPIT channel number 2 */
36 kLPIT_Chnl_3, /*!< LPIT channel number 3 */
37 } lpit_chnl_t;
38
39 /*! @brief Mode options available for the LPIT timer. */
40 typedef enum _lpit_timer_modes
41 {
42 kLPIT_PeriodicCounter = 0U, /*!< Use the all 32-bits, counter loads and decrements to zero */
43 kLPIT_DualPeriodicCounter, /*!< Counter loads, lower 16-bits decrement to zero, then
44 upper 16-bits decrement */
45 kLPIT_TriggerAccumulator, /*!< Counter loads on first trigger and decrements on each trigger */
46 kLPIT_InputCapture /*!< Counter loads with 0xFFFFFFFF, decrements to zero. It stores
47 the inverse of the current value when a input trigger is detected */
48 } lpit_timer_modes_t;
49
50 /*!
51 * @brief Trigger options available.
52 *
53 * This is used for both internal and external trigger sources. The actual trigger options
54 * available is SoC-specific, user should refer to the reference manual.
55 */
56 typedef enum _lpit_trigger_select
57 {
58 kLPIT_Trigger_TimerChn0 = 0U, /*!< Channel 0 is selected as a trigger source */
59 kLPIT_Trigger_TimerChn1, /*!< Channel 1 is selected as a trigger source */
60 kLPIT_Trigger_TimerChn2, /*!< Channel 2 is selected as a trigger source */
61 kLPIT_Trigger_TimerChn3, /*!< Channel 3 is selected as a trigger source */
62 kLPIT_Trigger_TimerChn4, /*!< Channel 4 is selected as a trigger source */
63 kLPIT_Trigger_TimerChn5, /*!< Channel 5 is selected as a trigger source */
64 kLPIT_Trigger_TimerChn6, /*!< Channel 6 is selected as a trigger source */
65 kLPIT_Trigger_TimerChn7, /*!< Channel 7 is selected as a trigger source */
66 kLPIT_Trigger_TimerChn8, /*!< Channel 8 is selected as a trigger source */
67 kLPIT_Trigger_TimerChn9, /*!< Channel 9 is selected as a trigger source */
68 kLPIT_Trigger_TimerChn10, /*!< Channel 10 is selected as a trigger source */
69 kLPIT_Trigger_TimerChn11, /*!< Channel 11 is selected as a trigger source */
70 kLPIT_Trigger_TimerChn12, /*!< Channel 12 is selected as a trigger source */
71 kLPIT_Trigger_TimerChn13, /*!< Channel 13 is selected as a trigger source */
72 kLPIT_Trigger_TimerChn14, /*!< Channel 14 is selected as a trigger source */
73 kLPIT_Trigger_TimerChn15 /*!< Channel 15 is selected as a trigger source */
74 } lpit_trigger_select_t;
75
76 /*! @brief Trigger source options available */
77 typedef enum _lpit_trigger_source
78 {
79 kLPIT_TriggerSource_External = 0U, /*!< Use external trigger input */
80 kLPIT_TriggerSource_Internal /*!< Use internal trigger */
81 } lpit_trigger_source_t;
82
83 /*!
84 * @brief List of LPIT interrupts.
85 *
86 * @note Number of timer channels are SoC-specific. See the SoC Reference Manual.
87 */
88 typedef enum _lpit_interrupt_enable
89 {
90 kLPIT_Channel0TimerInterruptEnable = (1U << 0), /*!< Channel 0 Timer interrupt */
91 kLPIT_Channel1TimerInterruptEnable = (1U << 1), /*!< Channel 1 Timer interrupt */
92 kLPIT_Channel2TimerInterruptEnable = (1U << 2), /*!< Channel 2 Timer interrupt */
93 kLPIT_Channel3TimerInterruptEnable = (1U << 3), /*!< Channel 3 Timer interrupt */
94 } lpit_interrupt_enable_t;
95
96 /*!
97 * @brief List of LPIT status flags
98 *
99 * @note Number of timer channels are SoC-specific. See the SoC Reference Manual.
100 */
101 typedef enum _lpit_status_flags
102 {
103 kLPIT_Channel0TimerFlag = (1U << 0), /*!< Channel 0 Timer interrupt flag */
104 kLPIT_Channel1TimerFlag = (1U << 1), /*!< Channel 1 Timer interrupt flag */
105 kLPIT_Channel2TimerFlag = (1U << 2), /*!< Channel 2 Timer interrupt flag */
106 kLPIT_Channel3TimerFlag = (1U << 3), /*!< Channel 3 Timer interrupt flag */
107 } lpit_status_flags_t;
108
109 /*! @brief Structure to configure the channel timer. */
110 typedef struct _lpit_chnl_params
111 {
112 bool chainChannel; /*!< true: Timer chained to previous timer;
113 false: Timer not chained */
114 lpit_timer_modes_t timerMode; /*!< Timers mode of operation. */
115 lpit_trigger_select_t triggerSelect; /*!< Trigger selection for the timer */
116 lpit_trigger_source_t triggerSource; /*!< Decides if we use external or internal trigger. */
117 bool enableReloadOnTrigger; /*!< true: Timer reloads when a trigger is detected;
118 false: No effect */
119 bool enableStopOnTimeout; /*!< true: Timer will stop after timeout;
120 false: does not stop after timeout */
121 bool enableStartOnTrigger; /*!< true: Timer starts when a trigger is detected;
122 false: decrement immediately */
123 } lpit_chnl_params_t;
124
125 /*!
126 * @brief LPIT configuration structure
127 *
128 * This structure holds the configuration settings for the LPIT peripheral. To initialize this
129 * structure to reasonable defaults, call the LPIT_GetDefaultConfig() function and pass a
130 * pointer to the configuration structure instance.
131 *
132 * The configuration structure can be made constant so as to reside in flash.
133 */
134 typedef struct _lpit_config
135 {
136 bool enableRunInDebug; /*!< true: Timers run in debug mode; false: Timers stop in debug mode */
137 bool enableRunInDoze; /*!< true: Timers run in doze mode; false: Timers stop in doze mode */
138 } lpit_config_t;
139
140 /*******************************************************************************
141 * API
142 ******************************************************************************/
143
144 #if defined(__cplusplus)
145 extern "C" {
146 #endif
147
148 /*!
149 * @name Initialization and deinitialization
150 * @{
151 */
152
153 /*!
154 * @brief Ungates the LPIT clock and configures the peripheral for a basic operation.
155 *
156 * This function issues a software reset to reset all channels and registers except the Module
157 * Control register.
158 *
159 * @note This API should be called at the beginning of the application using the LPIT driver.
160 *
161 * @param base LPIT peripheral base address.
162 * @param config Pointer to the user configuration structure.
163 */
164 void LPIT_Init(LPIT_Type *base, const lpit_config_t *config);
165
166 /*!
167 * @brief Disables the module and gates the LPIT clock.
168 *
169 * @param base LPIT peripheral base address.
170 */
171 void LPIT_Deinit(LPIT_Type *base);
172
173 /*!
174 * @brief Fills in the LPIT configuration structure with default settings.
175 *
176 * The default values are:
177 * @code
178 * config->enableRunInDebug = false;
179 * config->enableRunInDoze = false;
180 * @endcode
181 * @param config Pointer to the user configuration structure.
182 */
183 void LPIT_GetDefaultConfig(lpit_config_t *config);
184
185 /*!
186 * @brief Sets up an LPIT channel based on the user's preference.
187 *
188 * This function sets up the operation mode to one of the options available in the
189 * enumeration ::lpit_timer_modes_t. It sets the trigger source as either internal or external,
190 * trigger selection and the timers behaviour when a timeout occurs. It also chains
191 * the timer if a prior timer if requested by the user.
192 *
193 * @param base LPIT peripheral base address.
194 * @param channel Channel that is being configured.
195 * @param chnlSetup Configuration parameters.
196 */
197 status_t LPIT_SetupChannel(LPIT_Type *base, lpit_chnl_t channel, const lpit_chnl_params_t *chnlSetup);
198
199 /*! @}*/
200
201 /*!
202 * @name Interrupt Interface
203 * @{
204 */
205
206 /*!
207 * @brief Enables the selected PIT interrupts.
208 *
209 * @param base LPIT peripheral base address.
210 * @param mask The interrupts to enable. This is a logical OR of members of the
211 * enumeration ::lpit_interrupt_enable_t
212 */
LPIT_EnableInterrupts(LPIT_Type * base,uint32_t mask)213 static inline void LPIT_EnableInterrupts(LPIT_Type *base, uint32_t mask)
214 {
215 base->MIER |= mask;
216 }
217
218 /*!
219 * @brief Disables the selected PIT interrupts.
220 *
221 * @param base LPIT peripheral base address.
222 * @param mask The interrupts to enable. This is a logical OR of members of the
223 * enumeration ::lpit_interrupt_enable_t
224 */
LPIT_DisableInterrupts(LPIT_Type * base,uint32_t mask)225 static inline void LPIT_DisableInterrupts(LPIT_Type *base, uint32_t mask)
226 {
227 base->MIER &= ~mask;
228 }
229
230 /*!
231 * @brief Gets the enabled LPIT interrupts.
232 *
233 * @param base LPIT peripheral base address.
234 *
235 * @return The enabled interrupts. This is the logical OR of members of the
236 * enumeration ::lpit_interrupt_enable_t
237 */
LPIT_GetEnabledInterrupts(LPIT_Type * base)238 static inline uint32_t LPIT_GetEnabledInterrupts(LPIT_Type *base)
239 {
240 return base->MIER;
241 }
242
243 /*! @}*/
244
245 /*!
246 * @name Status Interface
247 * @{
248 */
249
250 /*!
251 * @brief Gets the LPIT status flags.
252 *
253 * @param base LPIT peripheral base address.
254 *
255 * @return The status flags. This is the logical OR of members of the
256 * enumeration ::lpit_status_flags_t
257 */
LPIT_GetStatusFlags(LPIT_Type * base)258 static inline uint32_t LPIT_GetStatusFlags(LPIT_Type *base)
259 {
260 return base->MSR;
261 }
262
263 /*!
264 * @brief Clears the LPIT status flags.
265 *
266 * @param base LPIT peripheral base address.
267 * @param mask The status flags to clear. This is a logical OR of members of the
268 * enumeration ::lpit_status_flags_t
269 */
LPIT_ClearStatusFlags(LPIT_Type * base,uint32_t mask)270 static inline void LPIT_ClearStatusFlags(LPIT_Type *base, uint32_t mask)
271 {
272 /* Writing a 1 to the status bit will clear the flag */
273 base->MSR = mask;
274 }
275
276 /*! @}*/
277
278 /*!
279 * @name Read and Write the timer period
280 * @{
281 */
282
283 /*!
284 * @brief Sets the timer period in units of count.
285 *
286 * Timers begin counting down from the value set by this function until it reaches 0, at which point
287 * it generates an interrupt and loads this register value again.
288 * Writing a new value to this register does not restart the timer. Instead, the value
289 * is loaded after the timer expires.
290 *
291 * @note User can call the utility macros provided in fsl_common.h to convert to ticks.
292 *
293 * @param base LPIT peripheral base address.
294 * @param channel Timer channel number.
295 * @param ticks Timer period in units of ticks.
296 */
LPIT_SetTimerPeriod(LPIT_Type * base,lpit_chnl_t channel,uint32_t ticks)297 static inline void LPIT_SetTimerPeriod(LPIT_Type *base, lpit_chnl_t channel, uint32_t ticks)
298 {
299 assert(ticks > 2U);
300 base->CHANNEL[channel].TVAL = ticks - 1U;
301 }
302
303 /*!
304 * @brief Sets the timer period in units of count.
305 *
306 * In the Dual 16-bit Periodic Counter mode, the counter will load and then the lower
307 * 16-bits will decrement down to zero, which will assert the output pre-trigger. The
308 * upper 16-bits will then decrement down to zero, which will negate the output pre-trigger
309 * and set the timer interrupt flag.
310 *
311 * @note Set TVAL register to 0 or 1 is invalid in compare mode.
312 *
313 * @param base LPIT peripheral base address.
314 * @param channel Timer channel number.
315 * @param ticks Timer period in units of ticks.
316 */
LPIT_SetTimerValue(LPIT_Type * base,lpit_chnl_t channel,uint32_t ticks)317 static inline void LPIT_SetTimerValue(LPIT_Type *base, lpit_chnl_t channel, uint32_t ticks)
318 {
319 assert(ticks > 1U);
320 base->CHANNEL[channel].TVAL = ticks;
321 }
322
323 /*!
324 * @brief Reads the current timer counting value.
325 *
326 * This function returns the real-time timer counting value, in a range from 0 to a
327 * timer period.
328 *
329 * @note User can call the utility macros provided in fsl_common.h to convert ticks to microseconds or milliseconds.
330 *
331 * @param base LPIT peripheral base address.
332 * @param channel Timer channel number.
333 *
334 * @return Current timer counting value in ticks.
335 */
LPIT_GetCurrentTimerCount(LPIT_Type * base,lpit_chnl_t channel)336 static inline uint32_t LPIT_GetCurrentTimerCount(LPIT_Type *base, lpit_chnl_t channel)
337 {
338 return base->CHANNEL[channel].CVAL;
339 }
340
341 /*! @}*/
342
343 /*!
344 * @name Timer Start and Stop
345 * @{
346 */
347
348 /*!
349 * @brief Starts the timer counting.
350 *
351 * After calling this function, timers load the period value and count down to 0. When the timer
352 * reaches 0, it generates a trigger pulse and sets the timeout interrupt flag.
353 *
354 * @param base LPIT peripheral base address.
355 * @param channel Timer channel number.
356 */
LPIT_StartTimer(LPIT_Type * base,lpit_chnl_t channel)357 static inline void LPIT_StartTimer(LPIT_Type *base, lpit_chnl_t channel)
358 {
359 uint32_t shift = LPIT_SETTEN_SET_T_EN_0_MASK;
360
361 base->SETTEN |= shift << ((uint32_t)channel);
362 }
363 /*!
364 * @brief Stops the timer counting.
365 *
366 * @param base LPIT peripheral base address.
367 * @param channel Timer channel number.
368 */
LPIT_StopTimer(LPIT_Type * base,lpit_chnl_t channel)369 static inline void LPIT_StopTimer(LPIT_Type *base, lpit_chnl_t channel)
370 {
371 uint32_t shift = LPIT_CLRTEN_CLR_T_EN_0_MASK;
372
373 base->CLRTEN |= shift << ((uint32_t)channel);
374 }
375
376 /*! @}*/
377
378 /*!
379 * @brief Performs a software reset on the LPIT module.
380 *
381 * This resets all channels and registers except the Module Control Register.
382 *
383 * @param base LPIT peripheral base address.
384 */
LPIT_Reset(LPIT_Type * base)385 static inline void LPIT_Reset(LPIT_Type *base)
386 {
387 base->MCR |= LPIT_MCR_SW_RST_MASK;
388 base->MCR &= ~LPIT_MCR_SW_RST_MASK;
389 }
390
391 #if defined(__cplusplus)
392 }
393 #endif
394
395 /*! @}*/
396
397 #endif /* __FSL_LPIT_H__ */
398