| /* |
| * Copyright (c) 2016, Freescale Semiconductor, Inc. |
| * Copyright 2016-2017 NXP |
| * All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| #ifndef _FSL_MRT_H_ |
| #define _FSL_MRT_H_ |
| |
| #include "fsl_common.h" |
| |
| /*! |
| * @addtogroup mrt |
| * @{ |
| */ |
| |
| /*! @file */ |
| |
| /******************************************************************************* |
| * Definitions |
| ******************************************************************************/ |
| |
| /*! @name Driver version */ |
| /*@{*/ |
| #define FSL_MRT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1 */ |
| /*@}*/ |
| |
| /*! @brief List of MRT channels */ |
| typedef enum _mrt_chnl |
| { |
| kMRT_Channel_0 = 0U, /*!< MRT channel number 0*/ |
| kMRT_Channel_1, /*!< MRT channel number 1 */ |
| kMRT_Channel_2, /*!< MRT channel number 2 */ |
| kMRT_Channel_3 /*!< MRT channel number 3 */ |
| } mrt_chnl_t; |
| |
| /*! @brief List of MRT timer modes */ |
| typedef enum _mrt_timer_mode |
| { |
| kMRT_RepeatMode = (0 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< Repeat Interrupt mode */ |
| kMRT_OneShotMode = (1 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< One-shot Interrupt mode */ |
| kMRT_OneShotStallMode = (2 << MRT_CHANNEL_CTRL_MODE_SHIFT) /*!< One-shot stall mode */ |
| } mrt_timer_mode_t; |
| |
| /*! @brief List of MRT interrupts */ |
| typedef enum _mrt_interrupt_enable |
| { |
| kMRT_TimerInterruptEnable = MRT_CHANNEL_CTRL_INTEN_MASK /*!< Timer interrupt enable*/ |
| } mrt_interrupt_enable_t; |
| |
| /*! @brief List of MRT status flags */ |
| typedef enum _mrt_status_flags |
| { |
| kMRT_TimerInterruptFlag = MRT_CHANNEL_STAT_INTFLAG_MASK, /*!< Timer interrupt flag */ |
| kMRT_TimerRunFlag = MRT_CHANNEL_STAT_RUN_MASK, /*!< Indicates state of the timer */ |
| } mrt_status_flags_t; |
| |
| /*! |
| * @brief MRT configuration structure |
| * |
| * This structure holds the configuration settings for the MRT peripheral. To initialize this |
| * structure to reasonable defaults, call the MRT_GetDefaultConfig() function and pass a |
| * pointer to your config structure instance. |
| * |
| * The config struct can be made const so it resides in flash |
| */ |
| typedef struct _mrt_config |
| { |
| bool enableMultiTask; /*!< true: Timers run in multi-task mode; false: Timers run in hardware status mode */ |
| } mrt_config_t; |
| |
| /******************************************************************************* |
| * API |
| ******************************************************************************/ |
| |
| #if defined(__cplusplus) |
| extern "C" { |
| #endif |
| |
| /*! |
| * @name Initialization and deinitialization |
| * @{ |
| */ |
| |
| /*! |
| * @brief Ungates the MRT clock and configures the peripheral for basic operation. |
| * |
| * @note This API should be called at the beginning of the application using the MRT driver. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param config Pointer to user's MRT config structure. If MRT has MULTITASK bit field in |
| * MODCFG reigster, param config is useless. |
| */ |
| void MRT_Init(MRT_Type *base, const mrt_config_t *config); |
| |
| /*! |
| * @brief Gate the MRT clock |
| * |
| * @param base Multi-Rate timer peripheral base address |
| */ |
| void MRT_Deinit(MRT_Type *base); |
| |
| /*! |
| * @brief Fill in the MRT config struct with the default settings |
| * |
| * The default values are: |
| * @code |
| * config->enableMultiTask = false; |
| * @endcode |
| * @param config Pointer to user's MRT config structure. |
| */ |
| static inline void MRT_GetDefaultConfig(mrt_config_t *config) |
| { |
| assert(config); |
| #if !(defined(FSL_FEATURE_MRT_HAS_NO_MODCFG_MULTITASK) && FSL_FEATURE_MRT_HAS_NO_MODCFG_MULTITASK) |
| /* Use hardware status operating mode */ |
| config->enableMultiTask = false; |
| #endif |
| } |
| |
| /*! |
| * @brief Sets up an MRT channel mode. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Channel that is being configured. |
| * @param mode Timer mode to use for the channel. |
| */ |
| static inline void MRT_SetupChannelMode(MRT_Type *base, mrt_chnl_t channel, const mrt_timer_mode_t mode) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| |
| uint32_t reg = base->CHANNEL[channel].CTRL; |
| |
| /* Clear old value */ |
| reg &= ~MRT_CHANNEL_CTRL_MODE_MASK; |
| /* Add the new mode */ |
| reg |= mode; |
| |
| base->CHANNEL[channel].CTRL = reg; |
| } |
| |
| /*! @}*/ |
| |
| /*! |
| * @name Interrupt Interface |
| * @{ |
| */ |
| |
| /*! |
| * @brief Enables the MRT interrupt. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * @param mask The interrupts to enable. This is a logical OR of members of the |
| * enumeration ::mrt_interrupt_enable_t |
| */ |
| static inline void MRT_EnableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| base->CHANNEL[channel].CTRL |= mask; |
| } |
| |
| /*! |
| * @brief Disables the selected MRT interrupt. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * @param mask The interrupts to disable. This is a logical OR of members of the |
| * enumeration ::mrt_interrupt_enable_t |
| */ |
| static inline void MRT_DisableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| base->CHANNEL[channel].CTRL &= ~mask; |
| } |
| |
| /*! |
| * @brief Gets the enabled MRT interrupts. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * |
| * @return The enabled interrupts. This is the logical OR of members of the |
| * enumeration ::mrt_interrupt_enable_t |
| */ |
| static inline uint32_t MRT_GetEnabledInterrupts(MRT_Type *base, mrt_chnl_t channel) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| return (base->CHANNEL[channel].CTRL & MRT_CHANNEL_CTRL_INTEN_MASK); |
| } |
| |
| /*! @}*/ |
| |
| /*! |
| * @name Status Interface |
| * @{ |
| */ |
| |
| /*! |
| * @brief Gets the MRT status flags |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * |
| * @return The status flags. This is the logical OR of members of the |
| * enumeration ::mrt_status_flags_t |
| */ |
| static inline uint32_t MRT_GetStatusFlags(MRT_Type *base, mrt_chnl_t channel) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| return (base->CHANNEL[channel].STAT & (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK)); |
| } |
| |
| /*! |
| * @brief Clears the MRT status flags. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * @param mask The status flags to clear. This is a logical OR of members of the |
| * enumeration ::mrt_status_flags_t |
| */ |
| static inline void MRT_ClearStatusFlags(MRT_Type *base, mrt_chnl_t channel, uint32_t mask) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| base->CHANNEL[channel].STAT = (mask & MRT_CHANNEL_STAT_INTFLAG_MASK); |
| } |
| |
| /*! @}*/ |
| |
| /*! |
| * @name Read and Write the timer period |
| * @{ |
| */ |
| |
| /*! |
| * @brief Used to update the timer period in units of count. |
| * |
| * The new value will be immediately loaded or will be loaded at the end of the current time |
| * interval. For one-shot interrupt mode the new value will be immediately loaded. |
| * |
| * @note User can call the utility macros provided in fsl_common.h to convert to ticks |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * @param count Timer period in units of ticks |
| * @param immediateLoad true: Load the new value immediately into the TIMER register; |
| * false: Load the new value at the end of current timer interval |
| */ |
| void MRT_UpdateTimerPeriod(MRT_Type *base, mrt_chnl_t channel, uint32_t count, bool immediateLoad); |
| |
| /*! |
| * @brief Reads the current timer counting value. |
| * |
| * This function returns the real-time timer counting value, in a range from 0 to a |
| * timer period. |
| * |
| * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number |
| * |
| * @return Current timer counting value in ticks |
| */ |
| static inline uint32_t MRT_GetCurrentTimerCount(MRT_Type *base, mrt_chnl_t channel) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| return base->CHANNEL[channel].TIMER; |
| } |
| |
| /*! @}*/ |
| |
| /*! |
| * @name Timer Start and Stop |
| * @{ |
| */ |
| |
| /*! |
| * @brief Starts the timer counting. |
| * |
| * After calling this function, timers load period value, counts down to 0 and |
| * depending on the timer mode it will either load the respective start value again or stop. |
| * |
| * @note User can call the utility macros provided in fsl_common.h to convert to ticks |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number. |
| * @param count Timer period in units of ticks |
| */ |
| static inline void MRT_StartTimer(MRT_Type *base, mrt_chnl_t channel, uint32_t count) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| /* Write the timer interval value */ |
| base->CHANNEL[channel].INTVAL = count; |
| } |
| |
| /*! |
| * @brief Stops the timer counting. |
| * |
| * This function stops the timer from counting. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number. |
| */ |
| static inline void MRT_StopTimer(MRT_Type *base, mrt_chnl_t channel) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| /* Stop the timer immediately */ |
| base->CHANNEL[channel].INTVAL = MRT_CHANNEL_INTVAL_LOAD_MASK; |
| } |
| |
| /*! @}*/ |
| |
| /*! |
| * @name Get & release channel |
| * @{ |
| */ |
| |
| /*! |
| * @brief Find the available channel. |
| * |
| * This function returns the lowest available channel number. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| */ |
| static inline uint32_t MRT_GetIdleChannel(MRT_Type *base) |
| { |
| return base->IDLE_CH; |
| } |
| |
| #if !(defined(FSL_FEATURE_MRT_HAS_NO_CHANNEL_STAT_INUSE) && FSL_FEATURE_MRT_HAS_NO_CHANNEL_STAT_INUSE) |
| /*! |
| * @brief Release the channel when the timer is using the multi-task mode. |
| * |
| * In multi-task mode, the INUSE flags allow more control over when MRT channels are released for |
| * further use. The user can hold on to a channel acquired by calling MRT_GetIdleChannel() for as |
| * long as it is needed and release it by calling this function. This removes the need to ask for |
| * an available channel for every use. |
| * |
| * @param base Multi-Rate timer peripheral base address |
| * @param channel Timer channel number. |
| */ |
| static inline void MRT_ReleaseChannel(MRT_Type *base, mrt_chnl_t channel) |
| { |
| assert(channel < FSL_FEATURE_MRT_NUMBER_OF_CHANNELS); |
| |
| uint32_t reg = base->CHANNEL[channel].STAT; |
| |
| /* Clear flag bits to prevent accidentally clearing anything when writing back */ |
| reg = ~MRT_CHANNEL_STAT_INTFLAG_MASK; |
| reg |= MRT_CHANNEL_STAT_INUSE_MASK; |
| |
| base->CHANNEL[channel].STAT = reg; |
| } |
| #endif |
| |
| /*! @}*/ |
| |
| #if defined(__cplusplus) |
| } |
| #endif |
| |
| /*! @}*/ |
| |
| #endif /* _FSL_MRT_H_ */ |