344 lines
9.8 KiB
C
344 lines
9.8 KiB
C
/*
|
|
* @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_ */
|