MCUXpresso_MCXA153/devices/MCXA153/drivers/fsl_freqme.h
Yilin Sun 35e678394a
Initial commit v2.14.2
Signed-off-by: Yilin Sun <imi415@imi.moe>
2024-02-11 19:33:06 +08:00

442 lines
15 KiB
C

/*
* Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_FREQME_
#define _FSL_FREQME_
#include "fsl_common.h"
/*!
* @addtogroup lpc_freqme
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FREQME driver version 2.1.2. */
#define FSL_FREQME_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
/*@}*/
/*!
* @brief The enumeration of interrupt status flags.
* @anchor _freqme_interrupt_status_flags
*/
enum _freqme_interrupt_status_flags
{
kFREQME_UnderflowInterruptStatusFlag = FREQME_CTRLSTAT_LT_MIN_STAT_MASK, /*!< Indicate the measurement is
just done and the result is less
than minimun value. */
kFREQME_OverflowInterruptStatusFlag = FREQME_CTRLSTAT_GT_MAX_STAT_MASK, /*!< Indicate the measurement is
just done and the result is greater
than maximum value. */
kFREQME_ReadyInterruptStatusFlag = FREQME_CTRLSTAT_RESULT_READY_STAT_MASK, /*!< Indicate the measurement is
just done and the result is ready to
read. */
kFREQME_AllInterruptStatusFlags = FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_STAT_MASK |
FREQME_CTRLSTAT_RESULT_READY_STAT_MASK, /*!< All interrupt
status flags. */
};
/*!
* @brief The enumeration of interrupts, including underflow interrupt, overflow interrupt,
* and result ready interrupt.
* @anchor _freqme_interrupt_enable
*/
enum _freqme_interrupt_enable
{
kFREQME_UnderflowInterruptEnable = FREQME_CTRL_W_LT_MIN_INT_EN_MASK, /*!< Enable interrupt when the result is
less than minimum value. */
kFREQME_OverflowInterruptEnable = FREQME_CTRL_W_GT_MAX_INT_EN_MASK, /*!< Enable interrupt when the result is
greater than maximum value. */
kFREQME_ReadyInterruptEnable = FREQME_CTRL_W_RESULT_READY_INT_EN_MASK, /*!< Enable interrupt when a
measurement completes and the result
is ready. */
};
/*!
* @brief FREQME module operate mode enumeration, including frequency measurement mode
* and pulse width measurement mode.
*/
typedef enum _freqme_operate_mode
{
kFREQME_FreqMeasurementMode = 0U, /*!< The module works in the frequency measurement mode. */
kFREOME_PulseWidthMeasurementMode, /*!< The module works in the pulse width measurement mode. */
} freqme_operate_mode_t;
/*!
* @brief The enumeration of pulse polarity.
*/
typedef enum _freqme_pulse_polarity
{
kFREQME_PulseHighPeriod = 0U, /*!< Select high period of the reference clock. */
kFREQME_PulseLowPeriod, /*!< Select low period of the reference clock. */
} freqme_pulse_polarity_t;
/*!
* @brief The union of operate mode attribute.
* @note If the operate mode is selected as frequency measurement mode the member \b refClkScaleFactor should be used,
* if the operate mode is selected as pulse width measurement mode the member \b pulsePolarity should be used.
*/
typedef union _freqme_mode_attribute
{
uint8_t refClkScaleFactor; /*!< Only useful in frequency measurement operate mode,
used to set the reference clock counter scaling factor. */
freqme_pulse_polarity_t pulsePolarity; /*!< Only Useful in pulse width measurement operate mode,
used to set period polarity. */
} freqme_mode_attribute_t;
/*!
* @brief The structure of freqme module basic configuration,
* including operate mode, operate mode attribute and so on.
*/
typedef struct _freq_measure_config
{
freqme_operate_mode_t operateMode; /*!< Select operate mode, please refer to @ref freqme_operate_mode_t. */
freqme_mode_attribute_t operateModeAttribute; /*!< Used to set the attribute of the selected operate mode, if
the operate mode is selected as @ref kFREQME_FreqMeasurementMode
set freqme_mode_attribute_t::refClkScaleFactor, if operate mode is
selected as @ref kFREOME_PulseWidthMeasurementMode, please set
freqme_mode_attribute_t::pulsePolarity. */
bool enableContinuousMode; /*!< Enable/disable continuous mode, if continuous mode is enable,
the measurement is performed continuously and the result for the
last completed measurement is available in the result register. */
bool startMeasurement;
} freq_measure_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Basic Control APIs
* @{
*/
/*!
* @brief Initialize freqme module, set operate mode, operate mode attribute and initialize measurement cycle.
*
* @param base FREQME peripheral base address.
* @param config The pointer to module basic configuration, please refer to @ref freq_measure_config_t.
*/
void FREQME_Init(FREQME_Type *base, const freq_measure_config_t *config);
/*!
* @brief Get default configuration.
*
* @code
* config->operateMode = kFREQME_FreqMeasurementMode;
* config->operateModeAttribute.refClkScaleFactor = 0U;
* config->enableContinuousMode = false;
* config->startMeasurement = false;
* @endcode
*
* @param config The pointer to module basic configuration, please refer to @ref freq_measure_config_t.
*/
void FREQME_GetDefaultConfig(freq_measure_config_t *config);
/*!
* @brief Start frequency or pulse width measurement process.
*
* @param base FREQME peripheral base address.
*/
static inline void FREQME_StartMeasurementCycle(FREQME_Type *base)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_MEASURE_IN_PROGRESS_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
tmp32 |= FREQME_CTRL_W_MEASURE_IN_PROGRESS_MASK;
base->CTRL_W = tmp32;
}
/*!
* @brief Force the termination of any measurement cycle currently in progress and resets RESULT or just reset
* RESULT if the module in idle state.
*
* @param base FREQME peripheral base address.
*/
static inline void FREQME_TerminateMeasurementCycle(FREQME_Type *base)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_MEASURE_IN_PROGRESS_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
base->CTRL_W = tmp32;
}
/*!
* @brief Enable/disable Continuous mode.
*
* @param base FREQME peripheral base address.
* @param enable Used to enable/disable continuous mode,
* - \b true Enable Continuous mode.
* - \b false Disable Continuous mode.
*/
static inline void FREQME_EnableContinuousMode(FREQME_Type *base, bool enable)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_CONTINUOUS_MODE_EN_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
if (enable)
{
tmp32 |= FREQME_CTRL_W_CONTINUOUS_MODE_EN_MASK;
}
base->CTRL_W = tmp32;
}
/*!
* @brief Check whether continuous mode is enabled.
*
* @param base FREQME peripheral base address.
* @retval True Continuous mode is enabled, the measurement is performed continuously.
* @retval False Continuous mode is disabled.
*/
static inline bool FREQME_CheckContinuousMode(FREQME_Type *base)
{
return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_CONTINUOUS_MODE_EN_MASK) != 0UL);
}
/*!
* @brief Set operate mode of freqme module.
*
* @param base FREQME peripheral base address.
* @param operateMode The operate mode to be set, please refer to @ref freqme_operate_mode_t.
*/
static inline void FREQME_SetOperateMode(FREQME_Type *base, freqme_operate_mode_t operateMode)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_PULSE_MODE_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
if (operateMode == kFREOME_PulseWidthMeasurementMode)
{
tmp32 |= FREQME_CTRL_W_PULSE_MODE_MASK;
}
base->CTRL_W = tmp32;
}
/*!
* @brief Check module's operate mode.
*
* @param base FREQME peripheral base address.
* @retval True Pulse width measurement mode.
* @retval False Frequency measurement mode.
*/
static inline bool FREQME_CheckOperateMode(FREQME_Type *base)
{
return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_PULSE_MODE_MASK) != 0UL);
}
/*!
* @brief Set the minimum expected value for the measurement result.
*
* @param base FREQME peripheral base address.
* @param minValue The minimum value to set, please note that this value is 31 bits width.
*/
static inline void FREQME_SetMinExpectedValue(FREQME_Type *base, uint32_t minValue)
{
base->MIN = minValue;
}
/*!
* @brief Set the maximum expected value for the measurement result.
*
* @param base FREQME peripheral base address.
* @param maxValue The maximum value to set, please note that this value is 31 bits width.
*/
static inline void FREQME_SetMaxExpectedValue(FREQME_Type *base, uint32_t maxValue)
{
base->MAX = maxValue;
}
/*! @} */
/*!
* @name Frequency Measurement Mode Control APIs
* @{
*/
/*!
* @brief Calculate the frequency of selected target clock。
*
* @note The formula: Ftarget = (RESULT - 2) * Freference / 2 ^ REF_SCALE.
*
* @note This function only useful when the operate mode is selected as frequency measurement mode.
*
* @param base FREQME peripheral base address.
* @param refClkFrequency The frequency of reference clock.
* @return The frequency of target clock the unit is Hz, if the output result is 0, please check the module's
* operate mode.
*/
uint32_t FREQME_CalculateTargetClkFreq(FREQME_Type *base, uint32_t refClkFrequency);
/*!
* @brief Get reference clock scaling factor.
*
* @param base FREQME peripheral base address.
* @return Reference clock scaling factor, the reference count cycle is 2 ^ ref_scale.
*/
static inline uint8_t FREQME_GetReferenceClkScaleValue(FREQME_Type *base)
{
return (uint8_t)(base->CTRLSTAT & FREQME_CTRLSTAT_REF_SCALE_MASK);
}
/*! @} */
/*!
* @name Pulse Width Measurement Mode Control APIs
* @{
*/
/*!
* @brief Set pulse polarity when operate mode is selected as Pulse Width Measurement mode.
*
* @param base FREQME peripheral base address.
* @param pulsePolarity The pulse polarity to be set, please refer to @ref freqme_pulse_polarity_t.
*/
static inline void FREQME_SetPulsePolarity(FREQME_Type *base, freqme_pulse_polarity_t pulsePolarity)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_PULSE_POL_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
if (pulsePolarity != kFREQME_PulseHighPeriod)
{
tmp32 |= FREQME_CTRL_W_PULSE_POL_MASK;
}
base->CTRL_W = tmp32;
}
/*!
* @brief Check pulse polarity when the operate mode is selected as pulse width measurement mode.
*
* @param base FREQME peripheral base address.
* @retval True Low period.
* @retval False High period.
*/
static inline bool FREQME_CheckPulsePolarity(FREQME_Type *base)
{
return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_PULSE_POL_MASK) != 0UL);
}
/*!
* @brief Get measurement result, if operate mode is selected as pulse width measurement mode this function can
* be used to calculate pulse width.
*
* @note Pulse width = counter result / Frequency of target clock.
*
* @param base FREQME peripheral base address.
* @return Measurement result.
*/
static inline uint32_t FREQME_GetMeasurementResult(FREQME_Type *base)
{
return base->CTRL_R & FREQME_CTRL_R_RESULT_MASK;
}
/*! @} */
/*!
* @name Status Control APIs
* @{
*/
/*!
* @brief Get interrupt status flags, such as overflow interrupt status flag,
* underflow interrupt status flag, and so on.
*
* @param base FREQME peripheral base address.
* @return Current interrupt status flags, should be the OR'ed value of @ref _freqme_interrupt_status_flags.
*/
static inline uint32_t FREQME_GetInterruptStatusFlags(FREQME_Type *base)
{
return (base->CTRLSTAT & (uint32_t)kFREQME_AllInterruptStatusFlags);
}
/*!
* @brief Clear interrupt status flags.
*
* @param base FREQME peripheral base address.
* @param statusFlags The combination of interrupt status flags to clear,
* should be the OR'ed value of @ref _freqme_interrupt_status_flags.
*/
static inline void FREQME_ClearInterruptStatusFlags(FREQME_Type *base, uint32_t statusFlags)
{
base->CTRLSTAT |= statusFlags;
}
/*! @} */
/*!
* @name Interrupt Control APIs
* @{
*/
/*!
* @brief Enable interrupts, such as result ready interrupt, overflow interrupt and so on.
*
* @param base FREQME peripheral base address.
* @param masks The mask of interrupts to enable, should be the OR'ed value of @ref _freqme_interrupt_enable.
*/
static inline void FREQME_EnableInterrupts(FREQME_Type *base, uint32_t masks)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_LT_MIN_INT_EN_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_INT_EN_MASK |
FREQME_CTRLSTAT_RESULT_READY_INT_EN_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
tmp32 |= masks;
base->CTRL_W = tmp32;
}
/*!
* @brief Disable interrupts, such as result ready interrupt, overflow interrupt and so on.
*
* @param base FREQME peripheral base address.
* @param masks The mask of interrupts to disable, should be the OR'ed value of @ref _freqme_interrupt_enable.
*/
static inline void FREQME_DisableInterrupts(FREQME_Type *base, uint32_t masks)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_STAT_MASK |
FREQME_CTRLSTAT_RESULT_READY_STAT_MASK | masks);
base->CTRL_W = tmp32;
}
/*! @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* __FSL_FREQME_H__ */