1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017, 2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #ifndef FSL_MRT_H_
9 #define FSL_MRT_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup mrt
15 * @{
16 */
17
18 /*! @file */
19
20 /*******************************************************************************
21 * Definitions
22 ******************************************************************************/
23
24 /*! @name Driver version */
25 /*! @{ */
26 #define FSL_MRT_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) /*!< Version 2.0.3 */
27 /*! @} */
28
29 /*! @brief List of MRT channels */
30 typedef enum _mrt_chnl
31 {
32 kMRT_Channel_0 = 0U, /*!< MRT channel number 0*/
33 kMRT_Channel_1, /*!< MRT channel number 1 */
34 kMRT_Channel_2, /*!< MRT channel number 2 */
35 kMRT_Channel_3 /*!< MRT channel number 3 */
36 } mrt_chnl_t;
37
38 /*! @brief List of MRT timer modes */
39 typedef enum _mrt_timer_mode
40 {
41 kMRT_RepeatMode = (0 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< Repeat Interrupt mode */
42 kMRT_OneShotMode = (1 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< One-shot Interrupt mode */
43 kMRT_OneShotStallMode = (2 << MRT_CHANNEL_CTRL_MODE_SHIFT) /*!< One-shot stall mode */
44 } mrt_timer_mode_t;
45
46 /*! @brief List of MRT interrupts */
47 typedef enum _mrt_interrupt_enable
48 {
49 kMRT_TimerInterruptEnable = MRT_CHANNEL_CTRL_INTEN_MASK /*!< Timer interrupt enable*/
50 } mrt_interrupt_enable_t;
51
52 /*! @brief List of MRT status flags */
53 typedef enum _mrt_status_flags
54 {
55 kMRT_TimerInterruptFlag = MRT_CHANNEL_STAT_INTFLAG_MASK, /*!< Timer interrupt flag */
56 kMRT_TimerRunFlag = MRT_CHANNEL_STAT_RUN_MASK, /*!< Indicates state of the timer */
57 } mrt_status_flags_t;
58
59 /*!
60 * @brief MRT configuration structure
61 *
62 * This structure holds the configuration settings for the MRT peripheral. To initialize this
63 * structure to reasonable defaults, call the MRT_GetDefaultConfig() function and pass a
64 * pointer to your config structure instance.
65 *
66 * The config struct can be made const so it resides in flash
67 */
68 typedef struct _mrt_config
69 {
70 bool enableMultiTask; /*!< true: Timers run in multi-task mode; false: Timers run in hardware status mode */
71 } mrt_config_t;
72
73 /*******************************************************************************
74 * API
75 ******************************************************************************/
76
77 #if defined(__cplusplus)
78 extern "C" {
79 #endif
80
81 /*!
82 * @name Initialization and deinitialization
83 * @{
84 */
85
86 /*!
87 * @brief Ungates the MRT clock and configures the peripheral for basic operation.
88 *
89 * @note This API should be called at the beginning of the application using the MRT driver.
90 *
91 * @param base Multi-Rate timer peripheral base address
92 * @param config Pointer to user's MRT config structure. If MRT has MULTITASK bit field in
93 * MODCFG reigster, param config is useless.
94 */
95 void MRT_Init(MRT_Type *base, const mrt_config_t *config);
96
97 /*!
98 * @brief Gate the MRT clock
99 *
100 * @param base Multi-Rate timer peripheral base address
101 */
102 void MRT_Deinit(MRT_Type *base);
103
104 /*!
105 * @brief Fill in the MRT config struct with the default settings
106 *
107 * The default values are:
108 * @code
109 * config->enableMultiTask = false;
110 * @endcode
111 * @param config Pointer to user's MRT config structure.
112 */
MRT_GetDefaultConfig(mrt_config_t * config)113 static inline void MRT_GetDefaultConfig(mrt_config_t *config)
114 {
115 assert(config != NULL);
116 #if !(defined(FSL_FEATURE_MRT_HAS_NO_MODCFG_MULTITASK) && FSL_FEATURE_MRT_HAS_NO_MODCFG_MULTITASK)
117 /* Use hardware status operating mode */
118 config->enableMultiTask = false;
119 #endif
120 }
121
122 /*!
123 * @brief Sets up an MRT channel mode.
124 *
125 * @param base Multi-Rate timer peripheral base address
126 * @param channel Channel that is being configured.
127 * @param mode Timer mode to use for the channel.
128 */
MRT_SetupChannelMode(MRT_Type * base,mrt_chnl_t channel,const mrt_timer_mode_t mode)129 static inline void MRT_SetupChannelMode(MRT_Type *base, mrt_chnl_t channel, const mrt_timer_mode_t mode)
130 {
131 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
132
133 uint32_t reg = base->CHANNEL[channel].CTRL;
134
135 /* Clear old value */
136 reg &= ~MRT_CHANNEL_CTRL_MODE_MASK;
137 /* Add the new mode */
138 reg |= (uint32_t)mode;
139
140 base->CHANNEL[channel].CTRL = reg;
141 }
142
143 /*! @}*/
144
145 /*!
146 * @name Interrupt Interface
147 * @{
148 */
149
150 /*!
151 * @brief Enables the MRT interrupt.
152 *
153 * @param base Multi-Rate timer peripheral base address
154 * @param channel Timer channel number
155 * @param mask The interrupts to enable. This is a logical OR of members of the
156 * enumeration ::mrt_interrupt_enable_t
157 */
MRT_EnableInterrupts(MRT_Type * base,mrt_chnl_t channel,uint32_t mask)158 static inline void MRT_EnableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask)
159 {
160 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
161 base->CHANNEL[channel].CTRL |= mask;
162 }
163
164 /*!
165 * @brief Disables the selected MRT interrupt.
166 *
167 * @param base Multi-Rate timer 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 ::mrt_interrupt_enable_t
171 */
MRT_DisableInterrupts(MRT_Type * base,mrt_chnl_t channel,uint32_t mask)172 static inline void MRT_DisableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask)
173 {
174 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
175 base->CHANNEL[channel].CTRL &= ~mask;
176 }
177
178 /*!
179 * @brief Gets the enabled MRT interrupts.
180 *
181 * @param base Multi-Rate timer peripheral base address
182 * @param channel Timer channel number
183 *
184 * @return The enabled interrupts. This is the logical OR of members of the
185 * enumeration ::mrt_interrupt_enable_t
186 */
MRT_GetEnabledInterrupts(MRT_Type * base,mrt_chnl_t channel)187 static inline uint32_t MRT_GetEnabledInterrupts(MRT_Type *base, mrt_chnl_t channel)
188 {
189 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
190 return (base->CHANNEL[channel].CTRL & MRT_CHANNEL_CTRL_INTEN_MASK);
191 }
192
193 /*! @}*/
194
195 /*!
196 * @name Status Interface
197 * @{
198 */
199
200 /*!
201 * @brief Gets the MRT status flags
202 *
203 * @param base Multi-Rate timer peripheral base address
204 * @param channel Timer channel number
205 *
206 * @return The status flags. This is the logical OR of members of the
207 * enumeration ::mrt_status_flags_t
208 */
MRT_GetStatusFlags(MRT_Type * base,mrt_chnl_t channel)209 static inline uint32_t MRT_GetStatusFlags(MRT_Type *base, mrt_chnl_t channel)
210 {
211 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
212 return (base->CHANNEL[channel].STAT & (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK));
213 }
214
215 /*!
216 * @brief Clears the MRT status flags.
217 *
218 * @param base Multi-Rate timer peripheral base address
219 * @param channel Timer channel number
220 * @param mask The status flags to clear. This is a logical OR of members of the
221 * enumeration ::mrt_status_flags_t
222 */
MRT_ClearStatusFlags(MRT_Type * base,mrt_chnl_t channel,uint32_t mask)223 static inline void MRT_ClearStatusFlags(MRT_Type *base, mrt_chnl_t channel, uint32_t mask)
224 {
225 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
226 base->CHANNEL[channel].STAT = (mask & MRT_CHANNEL_STAT_INTFLAG_MASK);
227 }
228
229 /*! @}*/
230
231 /*!
232 * @name Read and Write the timer period
233 * @{
234 */
235
236 /*!
237 * @brief Used to update the timer period in units of count.
238 *
239 * The new value will be immediately loaded or will be loaded at the end of the current time
240 * interval. For one-shot interrupt mode the new value will be immediately loaded.
241 *
242 * @note User can call the utility macros provided in fsl_common.h to convert to ticks
243 *
244 * @param base Multi-Rate timer peripheral base address
245 * @param channel Timer channel number
246 * @param count Timer period in units of ticks
247 * @param immediateLoad true: Load the new value immediately into the TIMER register;
248 * false: Load the new value at the end of current timer interval
249 */
250 void MRT_UpdateTimerPeriod(MRT_Type *base, mrt_chnl_t channel, uint32_t count, bool immediateLoad);
251
252 /*!
253 * @brief Reads the current timer counting value.
254 *
255 * This function returns the real-time timer counting value, in a range from 0 to a
256 * timer period.
257 *
258 * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec
259 *
260 * @param base Multi-Rate timer peripheral base address
261 * @param channel Timer channel number
262 *
263 * @return Current timer counting value in ticks
264 */
MRT_GetCurrentTimerCount(MRT_Type * base,mrt_chnl_t channel)265 static inline uint32_t MRT_GetCurrentTimerCount(MRT_Type *base, mrt_chnl_t channel)
266 {
267 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
268 return base->CHANNEL[channel].TIMER;
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, counts down to 0 and
282 * depending on the timer mode it will either load the respective start value again or stop.
283 *
284 * @note User can call the utility macros provided in fsl_common.h to convert to ticks
285 *
286 * @param base Multi-Rate timer peripheral base address
287 * @param channel Timer channel number.
288 * @param count Timer period in units of ticks. Count can contain the LOAD bit, which control the force load feature.
289 */
MRT_StartTimer(MRT_Type * base,mrt_chnl_t channel,uint32_t count)290 static inline void MRT_StartTimer(MRT_Type *base, mrt_chnl_t channel, uint32_t count)
291 {
292 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
293 assert((uint32_t)(count & ~MRT_CHANNEL_INTVAL_LOAD_MASK) <= (uint32_t)MRT_CHANNEL_INTVAL_IVALUE_MASK);
294 /* Write the timer interval value */
295 base->CHANNEL[channel].INTVAL = count;
296 }
297
298 /*!
299 * @brief Stops the timer counting.
300 *
301 * This function stops the timer from counting.
302 *
303 * @param base Multi-Rate timer peripheral base address
304 * @param channel Timer channel number.
305 */
MRT_StopTimer(MRT_Type * base,mrt_chnl_t channel)306 static inline void MRT_StopTimer(MRT_Type *base, mrt_chnl_t channel)
307 {
308 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
309 /* Stop the timer immediately */
310 base->CHANNEL[channel].INTVAL = MRT_CHANNEL_INTVAL_LOAD_MASK;
311 }
312
313 /*! @}*/
314
315 /*!
316 * @name Get & release channel
317 * @{
318 */
319
320 /*!
321 * @brief Find the available channel.
322 *
323 * This function returns the lowest available channel number.
324 *
325 * @param base Multi-Rate timer peripheral base address
326 */
MRT_GetIdleChannel(MRT_Type * base)327 static inline uint32_t MRT_GetIdleChannel(MRT_Type *base)
328 {
329 return base->IDLE_CH;
330 }
331
332 #if !(defined(FSL_FEATURE_MRT_HAS_NO_CHANNEL_STAT_INUSE) && FSL_FEATURE_MRT_HAS_NO_CHANNEL_STAT_INUSE)
333 /*!
334 * @brief Release the channel when the timer is using the multi-task mode.
335 *
336 * In multi-task mode, the INUSE flags allow more control over when MRT channels are released for
337 * further use. The user can hold on to a channel acquired by calling MRT_GetIdleChannel() for as
338 * long as it is needed and release it by calling this function. This removes the need to ask for
339 * an available channel for every use.
340 *
341 * @param base Multi-Rate timer peripheral base address
342 * @param channel Timer channel number.
343 */
MRT_ReleaseChannel(MRT_Type * base,mrt_chnl_t channel)344 static inline void MRT_ReleaseChannel(MRT_Type *base, mrt_chnl_t channel)
345 {
346 assert((uint8_t)channel < (uint8_t)FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
347
348 uint32_t reg = base->CHANNEL[channel].STAT;
349
350 /* Clear flag bits to prevent accidentally clearing anything when writing back */
351 reg = ~MRT_CHANNEL_STAT_INTFLAG_MASK;
352 reg |= MRT_CHANNEL_STAT_INUSE_MASK;
353
354 base->CHANNEL[channel].STAT = reg;
355 }
356 #endif
357
358 /*! @}*/
359
360 #if defined(__cplusplus)
361 }
362 #endif
363
364 /*! @}*/
365
366 #endif /* FSL_MRT_H_ */
367