1 /*
2 * @brief LPC15xx Multi-Rate Timer (MRT) registers and driver functions
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #ifndef __MRT_15XX_H_
33 #define __MRT_15XX_H_
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 /** @defgroup MRT_15XX CHIP: LPC15xx Multi-Rate Timer driver
40 * @ingroup CHIP_15XX_Drivers
41 * @{
42 */
43
44 /**
45 * @brief LPC15xx MRT chip configuration
46 */
47 #define MRT_CHANNELS_NUM (4)
48 #define MRT_NO_IDLE_CHANNEL (0x40)
49
50 /**
51 * @brief MRT register block structure
52 */
53 typedef struct {
54 __IO uint32_t INTVAL; /*!< Timer interval register */
55 __O uint32_t TIMER; /*!< Timer register */
56 __IO uint32_t CTRL; /*!< Timer control register */
57 __IO uint32_t STAT; /*!< Timer status register */
58 } LPC_MRT_CH_T;
59
60 /**
61 * @brief MRT register block structure
62 */
63 typedef struct {
64 LPC_MRT_CH_T CHANNEL[MRT_CHANNELS_NUM];
65 uint32_t unused[45];
66 __O uint32_t IDLE_CH;
67 __IO uint32_t IRQ_FLAG;
68 } LPC_MRT_T;
69
70 /**
71 * @brief MRT Interrupt Modes enum
72 */
73 typedef enum MRT_MODE {
74 MRT_MODE_REPEAT = (0 << 1), /*!< MRT Repeat interrupt mode */
75 MRT_MODE_ONESHOT = (1 << 1) /*!< MRT One-shot interrupt mode */
76 } MRT_MODE_T;
77
78 /**
79 * @brief MRT register bit fields & masks
80 */
81 /* MRT Time interval register bit fields */
82 #define MRT_INTVAL_IVALUE (0x00FFFFFF) /* Maximum interval load value and mask */
83 #define MRT_INTVAL_LOAD (0x80000000UL) /* Force immediate load of timer interval register bit */
84
85 /* MRT Control register bit fields & masks */
86 #define MRT_CTRL_INTEN_MASK (0x01)
87 #define MRT_CTRL_MODE_MASK (0x06)
88
89 /* MRT Status register bit fields & masks */
90 #define MRT_STAT_INTFLAG (0x01)
91 #define MRT_STAT_RUNNING (0x02)
92
93 /* Pointer to individual MR register blocks */
94 #define LPC_MRT_CH0 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[0])
95 #define LPC_MRT_CH1 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[1])
96 #define LPC_MRT_CH2 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[2])
97 #define LPC_MRT_CH3 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[3])
98 #define LPC_MRT_CH(ch) ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[(ch)])
99
100 /* Global interrupt flag register interrupt mask/clear values */
101 #define MRT0_INTFLAG (1)
102 #define MRT1_INTFLAG (2)
103 #define MRT2_INTFLAG (4)
104 #define MRT3_INTFLAG (8)
105 #define MRTn_INTFLAG(ch) (1 << (ch))
106
107 /**
108 * @brief Initializes the MRT
109 * @return Nothing
110 */
Chip_MRT_Init(void)111 STATIC INLINE void Chip_MRT_Init(void)
112 {
113 /* Enable the clock to the register interface */
114 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MRT);
115
116 /* Reset MRT */
117 Chip_SYSCTL_PeriphReset(RESET_MRT);
118 }
119
120 /**
121 * @brief De-initializes the MRT Channel
122 * @return Nothing
123 */
Chip_MRT_DeInit(void)124 STATIC INLINE void Chip_MRT_DeInit(void)
125 {
126 /* Disable the clock to the MRT */
127 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_MRT);
128 }
129
130 /**
131 * @brief Returns a pointer to the register block for a MRT channel
132 * @param ch : MRT channel tog et register block for (0..3)
133 * @return Pointer to the MRT register block for the channel
134 */
Chip_MRT_GetRegPtr(uint8_t ch)135 STATIC INLINE LPC_MRT_CH_T *Chip_MRT_GetRegPtr(uint8_t ch)
136 {
137 return LPC_MRT_CH(ch);
138 }
139
140 /**
141 * @brief Returns the timer time interval value
142 * @param pMRT : Pointer to selected MRT Channel
143 * @return Timer time interval value (IVALUE)
144 */
Chip_MRT_GetInterval(LPC_MRT_CH_T * pMRT)145 STATIC INLINE uint32_t Chip_MRT_GetInterval(LPC_MRT_CH_T *pMRT)
146 {
147 return pMRT->INTVAL;
148 }
149
150 /**
151 * @brief Sets the timer time interval value
152 * @param pMRT : Pointer to selected MRT Channel
153 * @param interval : The interval timeout (31-bits)
154 * @return Nothing
155 * @note Setting bit 31 in timer time interval register causes the time interval value
156 * to load immediately, otherwise the time interval value will be loaded in
157 * next timer cycle.<br>
158 * Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately<br>
159 * Example: Chip_MRT_SetInterval(pMRT, 0x500); // Will load timer interval after internal expires
160 */
Chip_MRT_SetInterval(LPC_MRT_CH_T * pMRT,uint32_t interval)161 STATIC INLINE void Chip_MRT_SetInterval(LPC_MRT_CH_T *pMRT, uint32_t interval)
162 {
163 pMRT->INTVAL = interval;
164 }
165
166 /**
167 * @brief Returns the current timer value
168 * @param pMRT : Pointer to selected MRT Channel
169 * @return The current timer value
170 */
Chip_MRT_GetTimer(LPC_MRT_CH_T * pMRT)171 STATIC INLINE uint32_t Chip_MRT_GetTimer(LPC_MRT_CH_T *pMRT)
172 {
173 return pMRT->TIMER;
174 }
175
176 /**
177 * @brief Returns true if the timer is enabled
178 * @param pMRT : Pointer to selected MRT Channel
179 * @return True if enabled, Flase if not enabled
180 */
Chip_MRT_GetEnabled(LPC_MRT_CH_T * pMRT)181 STATIC INLINE bool Chip_MRT_GetEnabled(LPC_MRT_CH_T *pMRT)
182 {
183 return (bool) ((pMRT->CTRL & MRT_CTRL_INTEN_MASK) != 0);
184 }
185
186 /**
187 * @brief Enables the timer
188 * @param pMRT : Pointer to selected MRT Channel
189 * @return Nothing
190 */
Chip_MRT_SetEnabled(LPC_MRT_CH_T * pMRT)191 STATIC INLINE void Chip_MRT_SetEnabled(LPC_MRT_CH_T *pMRT)
192 {
193 pMRT->CTRL |= MRT_CTRL_INTEN_MASK;
194 }
195
196 /**
197 * @brief Disables the timer
198 * @param pMRT : Pointer to selected MRT Channel
199 * @return Nothing
200 */
Chip_MRT_SetDisabled(LPC_MRT_CH_T * pMRT)201 STATIC INLINE void Chip_MRT_SetDisabled(LPC_MRT_CH_T *pMRT)
202 {
203 pMRT->CTRL &= ~MRT_CTRL_INTEN_MASK;
204 }
205
206 /**
207 * @brief Returns the timer mode (repeat or one-shot)
208 * @param pMRT : Pointer to selected MRT Channel
209 * @return The current timer mode
210 */
Chip_MRT_GetMode(LPC_MRT_CH_T * pMRT)211 STATIC INLINE MRT_MODE_T Chip_MRT_GetMode(LPC_MRT_CH_T *pMRT)
212 {
213 return (MRT_MODE_T) (pMRT->CTRL & MRT_CTRL_MODE_MASK);
214 }
215
216 /**
217 * @brief Sets the timer mode (repeat or one-shot)
218 * @param pMRT : Pointer to selected MRT Channel
219 * @param mode : Timer mode
220 * @return Nothing
221 */
Chip_MRT_SetMode(LPC_MRT_CH_T * pMRT,MRT_MODE_T mode)222 STATIC INLINE void Chip_MRT_SetMode(LPC_MRT_CH_T *pMRT, MRT_MODE_T mode)
223 {
224 uint32_t reg;
225
226 reg = pMRT->CTRL & ~MRT_CTRL_MODE_MASK;
227 pMRT->CTRL = reg | (uint32_t) mode;
228 }
229
230 /**
231 * @brief Check if the timer is configured in repeat mode
232 * @param pMRT : Pointer to selected MRT Channel
233 * @return True if in repeat mode, False if in one-shot mode
234 */
Chip_MRT_IsRepeatMode(LPC_MRT_CH_T * pMRT)235 STATIC INLINE bool Chip_MRT_IsRepeatMode(LPC_MRT_CH_T *pMRT)
236 {
237 return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? false : true;
238 }
239
240 /**
241 * @brief Check if the timer is configured in one-shot mode
242 * @param pMRT : Pointer to selected MRT Channel
243 * @return True if in one-shot mode, False if in repeat mode
244 */
Chip_MRT_IsOneShotMode(LPC_MRT_CH_T * pMRT)245 STATIC INLINE bool Chip_MRT_IsOneShotMode(LPC_MRT_CH_T *pMRT)
246 {
247 return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? true : false;
248 }
249
250 /**
251 * @brief Check if the timer has an interrupt pending
252 * @param pMRT : Pointer to selected MRT Channel
253 * @return True if interrupt is pending, False if no interrupt is pending
254 */
Chip_MRT_IntPending(LPC_MRT_CH_T * pMRT)255 STATIC INLINE bool Chip_MRT_IntPending(LPC_MRT_CH_T *pMRT)
256 {
257 return (bool) ((pMRT->STAT & MRT_STAT_INTFLAG) != 0);
258 }
259
260 /**
261 * @brief Clears the pending interrupt (if any)
262 * @param pMRT : Pointer to selected MRT Channel
263 * @return Nothing
264 */
Chip_MRT_IntClear(LPC_MRT_CH_T * pMRT)265 STATIC INLINE void Chip_MRT_IntClear(LPC_MRT_CH_T *pMRT)
266 {
267 pMRT->STAT |= MRT_STAT_INTFLAG;
268 }
269
270 /**
271 * @brief Check if the timer is running
272 * @param pMRT : Pointer to selected MRT Channel
273 * @return True if running, False if stopped
274 */
Chip_MRT_Running(LPC_MRT_CH_T * pMRT)275 STATIC INLINE bool Chip_MRT_Running(LPC_MRT_CH_T *pMRT)
276 {
277 return (bool) ((pMRT->STAT & MRT_STAT_RUNNING) != 0);
278 }
279
280 /**
281 * @brief Returns the IDLE channel value
282 * @return IDLE channel value (unshifted in bits 7..4)
283 */
Chip_MRT_GetIdleChannel(void)284 STATIC INLINE uint8_t Chip_MRT_GetIdleChannel(void)
285 {
286 return (uint8_t) (LPC_MRT->IDLE_CH);
287 }
288
289 /**
290 * @brief Returns the IDLE channel value
291 * @return IDLE channel value (shifted in bits 3..0)
292 */
Chip_MRT_GetIdleChannelShifted(void)293 STATIC INLINE uint8_t Chip_MRT_GetIdleChannelShifted(void)
294 {
295 return (uint8_t) (Chip_MRT_GetIdleChannel() >> 4);
296 }
297
298 /**
299 * @brief Returns the interrupt pending status for all MRT channels
300 * @return IRQ pending channel bitfield(bit 0 = MRT0, bit 1 = MRT1, etc.)
301 */
Chip_MRT_GetIntPending(void)302 STATIC INLINE uint32_t Chip_MRT_GetIntPending(void)
303 {
304 return LPC_MRT->IRQ_FLAG;
305 }
306
307 /**
308 * @brief Returns the interrupt pending status for a singel MRT channel
309 * @param ch : Channel to check pending interrupt status for
310 * @return IRQ pending channel number
311 */
Chip_MRT_GetIntPendingByChannel(uint8_t ch)312 STATIC INLINE bool Chip_MRT_GetIntPendingByChannel(uint8_t ch)
313 {
314 return (bool) (((LPC_MRT->IRQ_FLAG >> ch) & 1) != 0);
315 }
316
317 /**
318 * @brief Clears the interrupt pending status for one or more MRT channels
319 * @param mask : Channels to clear (bit 0 = MRT0, bit 1 = MRT1, etc.)
320 * @return Nothing
321 * @note Use this function to clear multiple interrupt pending states in
322 * a single call via the IRQ_FLAG register. Performs the same function for
323 * all MRT channels in a single call as the Chip_MRT_IntClear() does for a
324 * single channel.
325 */
Chip_MRT_ClearIntPending(uint32_t mask)326 STATIC INLINE void Chip_MRT_ClearIntPending(uint32_t mask)
327 {
328 LPC_MRT->IRQ_FLAG = mask;
329 }
330
331 /**
332 * @}
333 */
334
335 #ifdef __cplusplus
336 }
337 #endif
338
339 #endif /* __MRT_15XX_H_ */
340