/* * @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.
* Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately
* 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_ */