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
|
/*
* @brief LPC8xx Multi-Rate Timer (MRT) registers and driver functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __MRT_8XX_H_
#define __MRT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup MRT_8XX CHIP: LPC8xx Multi-Rate Timer driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx MRT chip configuration
*/
#define MRT_CHANNELS_NUM (4)
#define MRT_NO_IDLE_CHANNEL (0x40)
/**
* @brief MRT register block structure
*/
typedef struct {
__IO uint32_t INTVAL; /*!< Timer interval register */
__O uint32_t TIMER; /*!< Timer register */
__IO uint32_t CTRL; /*!< Timer control register */
__IO uint32_t STAT; /*!< Timer status register */
} LPC_MRT_CH_T;
/**
* @brief MRT register block structure
*/
typedef struct {
LPC_MRT_CH_T CHANNEL[MRT_CHANNELS_NUM];
uint32_t unused[45];
__O uint32_t IDLE_CH;
__IO uint32_t IRQ_FLAG;
} LPC_MRT_T;
/* Reserved bits masks for registers */
#define MRT_CTRL_RESERVED (~7)
#define MRT_STAT_RESERVED (~3)
/**
* @brief MRT Interrupt Modes enum
*/
typedef enum MRT_MODE {
MRT_MODE_REPEAT = (0 << 1), /*!< MRT Repeat interrupt mode */
MRT_MODE_ONESHOT = (1 << 1) /*!< MRT One-shot interrupt mode */
} MRT_MODE_T;
/**
* @brief MRT register bit fields & masks
*/
/* MRT Time interval register bit fields */
#define MRT_INTVAL_IVALUE (0x7FFFFFFFUL) /* Maximum interval load value and mask */
#define MRT_INTVAL_LOAD (0x80000000UL) /* Force immediate load of timer interval register bit */
/* MRT Control register bit fields & masks */
#define MRT_CTRL_INTEN_MASK (0x01)
#define MRT_CTRL_MODE_MASK (0x06)
/* MRT Status register bit fields & masks */
#define MRT_STAT_INTFLAG (0x01)
#define MRT_STAT_RUNNING (0x02)
/* Pointer to individual MR register blocks */
#define LPC_MRT_CH0 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[0])
#define LPC_MRT_CH1 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[1])
#define LPC_MRT_CH2 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[2])
#define LPC_MRT_CH3 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[3])
#define LPC_MRT_CH(ch) ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[(ch)])
/* Global interrupt flag register interrupt mask/clear values */
#define MRT0_INTFLAG (1)
#define MRT1_INTFLAG (2)
#define MRT2_INTFLAG (4)
#define MRT3_INTFLAG (8)
#define MRTn_INTFLAG(ch) (1 << (ch))
/**
* @brief Initializes the MRT
* @return Nothing
*/
STATIC INLINE void Chip_MRT_Init(void)
{
/* Enable the clock to the register interface */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MRT);
/* Reset MRT */
Chip_SYSCTL_PeriphReset(RESET_MRT);
}
/**
* @brief De-initializes the MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_DeInit(void)
{
/* Disable the clock to the MRT */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_MRT);
}
/**
* @brief Returns a pointer to the register block for a MRT channel
* @param ch : MRT channel tog et register block for (0..3)
* @return Pointer to the MRT register block for the channel
*/
STATIC INLINE LPC_MRT_CH_T *Chip_MRT_GetRegPtr(uint8_t ch)
{
return LPC_MRT_CH(ch);
}
/**
* @brief Returns the timer time interval value
* @param pMRT : Pointer to selected MRT Channel
* @return Timer time interval value (IVALUE)
*/
STATIC INLINE uint32_t Chip_MRT_GetInterval(LPC_MRT_CH_T *pMRT)
{
return pMRT->INTVAL;
}
/**
* @brief Sets the timer time interval value
* @param pMRT : Pointer to selected MRT Channel
* @param interval : The interval timeout (31-bits)
* @return Nothing
* @note Setting bit 31 in timer time interval register causes the time interval value
* to load immediately, otherwise the time interval value will be loaded in
* next timer cycle.<br>
* Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately<br>
* Example: Chip_MRT_SetInterval(pMRT, 0x500); // Will load timer interval after internal expires
*/
STATIC INLINE void Chip_MRT_SetInterval(LPC_MRT_CH_T *pMRT, uint32_t interval)
{
pMRT->INTVAL = interval;
}
/**
* @brief Returns the current timer value
* @param pMRT : Pointer to selected MRT Channel
* @return The current timer value
*/
STATIC INLINE uint32_t Chip_MRT_GetTimer(LPC_MRT_CH_T *pMRT)
{
return pMRT->TIMER;
}
/**
* @brief Returns true if the timer is enabled
* @param pMRT : Pointer to selected MRT Channel
* @return True if enabled, Flase if not enabled
*/
STATIC INLINE bool Chip_MRT_GetEnabled(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->CTRL & MRT_CTRL_INTEN_MASK) != 0);
}
/**
* @brief Enables the timer
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetEnabled(LPC_MRT_CH_T *pMRT)
{
pMRT->CTRL = MRT_CTRL_INTEN_MASK | (pMRT->CTRL & ~MRT_CTRL_RESERVED);
}
/**
* @brief Disables the timer
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetDisabled(LPC_MRT_CH_T *pMRT)
{
pMRT->CTRL &= ~(MRT_CTRL_INTEN_MASK | MRT_CTRL_RESERVED);
}
/**
* @brief Returns the timer mode (repeat or one-shot)
* @param pMRT : Pointer to selected MRT Channel
* @return The current timer mode
*/
STATIC INLINE MRT_MODE_T Chip_MRT_GetMode(LPC_MRT_CH_T *pMRT)
{
return (MRT_MODE_T) (pMRT->CTRL & MRT_CTRL_MODE_MASK);
}
/**
* @brief Sets the timer mode (repeat or one-shot)
* @param pMRT : Pointer to selected MRT Channel
* @param mode : Timer mode
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetMode(LPC_MRT_CH_T *pMRT, MRT_MODE_T mode)
{
uint32_t reg;
reg = pMRT->CTRL & ~(MRT_CTRL_MODE_MASK | MRT_CTRL_RESERVED);
pMRT->CTRL = reg | (uint32_t) mode;
}
/**
* @brief Check if the timer is configured in repeat mode
* @param pMRT : Pointer to selected MRT Channel
* @return True if in repeat mode, False if in one-shot mode
*/
STATIC INLINE bool Chip_MRT_IsRepeatMode(LPC_MRT_CH_T *pMRT)
{
return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? false : true;
}
/**
* @brief Check if the timer is configured in one-shot mode
* @param pMRT : Pointer to selected MRT Channel
* @return True if in one-shot mode, False if in repeat mode
*/
STATIC INLINE bool Chip_MRT_IsOneShotMode(LPC_MRT_CH_T *pMRT)
{
return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? true : false;
}
/**
* @brief Check if the timer has an interrupt pending
* @param pMRT : Pointer to selected MRT Channel
* @return True if interrupt is pending, False if no interrupt is pending
*/
STATIC INLINE bool Chip_MRT_IntPending(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->STAT & MRT_STAT_INTFLAG) != 0);
}
/**
* @brief Clears the pending interrupt (if any)
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_IntClear(LPC_MRT_CH_T *pMRT)
{
pMRT->STAT = MRT_STAT_INTFLAG | (pMRT->STAT & ~MRT_STAT_RESERVED);
}
/**
* @brief Check if the timer is running
* @param pMRT : Pointer to selected MRT Channel
* @return True if running, False if stopped
*/
STATIC INLINE bool Chip_MRT_Running(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->STAT & MRT_STAT_RUNNING) != 0);
}
/**
* @brief Returns the IDLE channel value
* @return IDLE channel value (unshifted in bits 7..4)
*/
STATIC INLINE uint8_t Chip_MRT_GetIdleChannel(void)
{
return (uint8_t) (LPC_MRT->IDLE_CH);
}
/**
* @brief Returns the IDLE channel value
* @return IDLE channel value (shifted in bits 3..0)
*/
STATIC INLINE uint8_t Chip_MRT_GetIdleChannelShifted(void)
{
return (uint8_t) (Chip_MRT_GetIdleChannel() >> 4);
}
/**
* @brief Returns the interrupt pending status for all MRT channels
* @return IRQ pending channel bitfield(bit 0 = MRT0, bit 1 = MRT1, etc.)
*/
STATIC INLINE uint32_t Chip_MRT_GetIntPending(void)
{
return LPC_MRT->IRQ_FLAG;
}
/**
* @brief Returns the interrupt pending status for a singel MRT channel
* @param ch : Channel to check pending interrupt status for
* @return IRQ pending channel number
*/
STATIC INLINE bool Chip_MRT_GetIntPendingByChannel(uint8_t ch)
{
return (bool) (((LPC_MRT->IRQ_FLAG >> ch) & 1) != 0);
}
/**
* @brief Clears the interrupt pending status for one or more MRT channels
* @param mask : Channels to clear (bit 0 = MRT0, bit 1 = MRT1, etc.)
* @return Nothing
* @note Use this function to clear multiple interrupt pending states in
* a single call via the IRQ_FLAG register. Performs the same function for
* all MRT channels in a single call as the Chip_MRT_IntClear() does for a
* single channel.
*/
STATIC INLINE void Chip_MRT_ClearIntPending(uint32_t mask)
{
LPC_MRT->IRQ_FLAG = mask;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __MRT_8XX_H_ */
|