1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
|
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_MRT_H_
#define _FSL_MRT_H_
#include "fsl_common.h"
/*!
* @addtogroup mrt
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_MRT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
/*@}*/
/*! @brief List of MRT channels */
typedef enum _mrt_chnl
{
kMRT_Channel_0 = 0U, /*!< MRT channel number 0*/
kMRT_Channel_1, /*!< MRT channel number 1 */
kMRT_Channel_2, /*!< MRT channel number 2 */
kMRT_Channel_3 /*!< MRT channel number 3 */
} mrt_chnl_t;
/*! @brief List of MRT timer modes */
typedef enum _mrt_timer_mode
{
kMRT_RepeatMode = (0 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< Repeat Interrupt mode */
kMRT_OneShotMode = (1 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< One-shot Interrupt mode */
kMRT_OneShotStallMode = (2 << MRT_CHANNEL_CTRL_MODE_SHIFT) /*!< One-shot stall mode */
} mrt_timer_mode_t;
/*! @brief List of MRT interrupts */
typedef enum _mrt_interrupt_enable
{
kMRT_TimerInterruptEnable = MRT_CHANNEL_CTRL_INTEN_MASK /*!< Timer interrupt enable*/
} mrt_interrupt_enable_t;
/*! @brief List of MRT status flags */
typedef enum _mrt_status_flags
{
kMRT_TimerInterruptFlag = MRT_CHANNEL_STAT_INTFLAG_MASK, /*!< Timer interrupt flag */
kMRT_TimerRunFlag = MRT_CHANNEL_STAT_RUN_MASK, /*!< Indicates state of the timer */
} mrt_status_flags_t;
/*!
* @brief MRT configuration structure
*
* This structure holds the configuration settings for the MRT peripheral. To initialize this
* structure to reasonable defaults, call the MRT_GetDefaultConfig() function and pass a
* pointer to your config structure instance.
*
* The config struct can be made const so it resides in flash
*/
typedef struct _mrt_config
{
bool enableMultiTask; /*!< true: Timers run in multi-task mode; false: Timers run in hardware status mode */
} mrt_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the MRT clock and configures the peripheral for basic operation.
*
* @note This API should be called at the beginning of the application using the MRT driver.
*
* @param base Multi-Rate timer peripheral base address
* @param config Pointer to user's MRT config structure. If MRT has MULTITASK bit field in
* MODCFG reigster, param config is useless.
*/
void MRT_Init(MRT_Type *base, const mrt_config_t *config);
/*!
* @brief Gate the MRT clock
*
* @param base Multi-Rate timer peripheral base address
*/
void MRT_Deinit(MRT_Type *base);
/*!
* @brief Fill in the MRT config struct with the default settings
*
* The default values are:
* @code
* config->enableMultiTask = false;
* @endcode
* @param config Pointer to user's MRT config structure.
*/
static inline void MRT_GetDefaultConfig(mrt_config_t *config)
{
assert(config);
#if !(defined(FSL_FEATURE_MRT_HAS_NO_MODCFG_MULTITASK) && FSL_FEATURE_MRT_HAS_NO_MODCFG_MULTITASK)
/* Use hardware status operating mode */
config->enableMultiTask = false;
#endif
}
/*!
* @brief Sets up an MRT channel mode.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Channel that is being configured.
* @param mode Timer mode to use for the channel.
*/
static inline void MRT_SetupChannelMode(MRT_Type *base, mrt_chnl_t channel, const mrt_timer_mode_t mode)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
uint32_t reg = base->CHANNEL[channel].CTRL;
/* Clear old value */
reg &= ~MRT_CHANNEL_CTRL_MODE_MASK;
/* Add the new mode */
reg |= mode;
base->CHANNEL[channel].CTRL = reg;
}
/*! @}*/
/*!
* @name Interrupt Interface
* @{
*/
/*!
* @brief Enables the MRT interrupt.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
* @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::mrt_interrupt_enable_t
*/
static inline void MRT_EnableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
base->CHANNEL[channel].CTRL |= mask;
}
/*!
* @brief Disables the selected MRT interrupt.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
* @param mask The interrupts to disable. This is a logical OR of members of the
* enumeration ::mrt_interrupt_enable_t
*/
static inline void MRT_DisableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
base->CHANNEL[channel].CTRL &= ~mask;
}
/*!
* @brief Gets the enabled MRT interrupts.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
*
* @return The enabled interrupts. This is the logical OR of members of the
* enumeration ::mrt_interrupt_enable_t
*/
static inline uint32_t MRT_GetEnabledInterrupts(MRT_Type *base, mrt_chnl_t channel)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
return (base->CHANNEL[channel].CTRL & MRT_CHANNEL_CTRL_INTEN_MASK);
}
/*! @}*/
/*!
* @name Status Interface
* @{
*/
/*!
* @brief Gets the MRT status flags
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
*
* @return The status flags. This is the logical OR of members of the
* enumeration ::mrt_status_flags_t
*/
static inline uint32_t MRT_GetStatusFlags(MRT_Type *base, mrt_chnl_t channel)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
return (base->CHANNEL[channel].STAT & (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK));
}
/*!
* @brief Clears the MRT status flags.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
* @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::mrt_status_flags_t
*/
static inline void MRT_ClearStatusFlags(MRT_Type *base, mrt_chnl_t channel, uint32_t mask)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
base->CHANNEL[channel].STAT = (mask & MRT_CHANNEL_STAT_INTFLAG_MASK);
}
/*! @}*/
/*!
* @name Read and Write the timer period
* @{
*/
/*!
* @brief Used to update the timer period in units of count.
*
* The new value will be immediately loaded or will be loaded at the end of the current time
* interval. For one-shot interrupt mode the new value will be immediately loaded.
*
* @note User can call the utility macros provided in fsl_common.h to convert to ticks
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
* @param count Timer period in units of ticks
* @param immediateLoad true: Load the new value immediately into the TIMER register;
* false: Load the new value at the end of current timer interval
*/
void MRT_UpdateTimerPeriod(MRT_Type *base, mrt_chnl_t channel, uint32_t count, bool immediateLoad);
/*!
* @brief Reads the current timer counting value.
*
* This function returns the real-time timer counting value, in a range from 0 to a
* timer period.
*
* @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number
*
* @return Current timer counting value in ticks
*/
static inline uint32_t MRT_GetCurrentTimerCount(MRT_Type *base, mrt_chnl_t channel)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
return base->CHANNEL[channel].TIMER;
}
/*! @}*/
/*!
* @name Timer Start and Stop
* @{
*/
/*!
* @brief Starts the timer counting.
*
* After calling this function, timers load period value, counts down to 0 and
* depending on the timer mode it will either load the respective start value again or stop.
*
* @note User can call the utility macros provided in fsl_common.h to convert to ticks
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number.
* @param count Timer period in units of ticks
*/
static inline void MRT_StartTimer(MRT_Type *base, mrt_chnl_t channel, uint32_t count)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
/* Write the timer interval value */
base->CHANNEL[channel].INTVAL = count;
}
/*!
* @brief Stops the timer counting.
*
* This function stops the timer from counting.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number.
*/
static inline void MRT_StopTimer(MRT_Type *base, mrt_chnl_t channel)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
/* Stop the timer immediately */
base->CHANNEL[channel].INTVAL = MRT_CHANNEL_INTVAL_LOAD_MASK;
}
/*! @}*/
/*!
* @name Get & release channel
* @{
*/
/*!
* @brief Find the available channel.
*
* This function returns the lowest available channel number.
*
* @param base Multi-Rate timer peripheral base address
*/
static inline uint32_t MRT_GetIdleChannel(MRT_Type *base)
{
return base->IDLE_CH;
}
#if !(defined(FSL_FEATURE_MRT_HAS_NO_CHANNEL_STAT_INUSE) && FSL_FEATURE_MRT_HAS_NO_CHANNEL_STAT_INUSE)
/*!
* @brief Release the channel when the timer is using the multi-task mode.
*
* In multi-task mode, the INUSE flags allow more control over when MRT channels are released for
* further use. The user can hold on to a channel acquired by calling MRT_GetIdleChannel() for as
* long as it is needed and release it by calling this function. This removes the need to ask for
* an available channel for every use.
*
* @param base Multi-Rate timer peripheral base address
* @param channel Timer channel number.
*/
static inline void MRT_ReleaseChannel(MRT_Type *base, mrt_chnl_t channel)
{
assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS);
uint32_t reg = base->CHANNEL[channel].STAT;
/* Clear flag bits to prevent accidentally clearing anything when writing back */
reg = ~MRT_CHANNEL_STAT_INTFLAG_MASK;
reg |= MRT_CHANNEL_STAT_INUSE_MASK;
base->CHANNEL[channel].STAT = reg;
}
#endif
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_MRT_H_ */
|