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