442 lines
15 KiB
C
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__ */
|