1 /*
2  * Copyright 2021-2022 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef FSL_FREQME_H_
8 #define FSL_FREQME_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup lpc_freqme
14  * @{
15  */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*! @name Driver version */
22 /*! @{ */
23 /*! @brief FREQME driver version 2.1.2. */
24 #define FSL_FREQME_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
25 /*! @} */
26 
27 /*!
28  * @brief The enumeration of interrupt status flags.
29  * @anchor _freqme_interrupt_status_flags
30  */
31 enum _freqme_interrupt_status_flags
32 {
33     kFREQME_UnderflowInterruptStatusFlag = FREQME_CTRLSTAT_LT_MIN_STAT_MASK,   /*!< Indicate the measurement is
34                                                                                      just done and the result is less
35                                                                                      than minimun value. */
36     kFREQME_OverflowInterruptStatusFlag = FREQME_CTRLSTAT_GT_MAX_STAT_MASK,    /*!< Indicate the measurement is
37                                                                                      just done and the result is greater
38                                                                                      than maximum value. */
39     kFREQME_ReadyInterruptStatusFlag = FREQME_CTRLSTAT_RESULT_READY_STAT_MASK, /*!< Indicate the measurement is
40                                                                                  just done and the result is ready to
41                                                                                  read. */
42     kFREQME_AllInterruptStatusFlags = FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_STAT_MASK |
43                                       FREQME_CTRLSTAT_RESULT_READY_STAT_MASK, /*!< All interrupt
44                                                                                         status flags. */
45 };
46 
47 /*!
48  * @brief The enumeration of interrupts, including underflow interrupt, overflow interrupt,
49  * and result ready interrupt.
50  * @anchor _freqme_interrupt_enable
51  */
52 enum _freqme_interrupt_enable
53 {
54     kFREQME_UnderflowInterruptEnable = FREQME_CTRL_W_LT_MIN_INT_EN_MASK, /*!< Enable interrupt when the result is
55                                                                                    less than minimum value. */
56     kFREQME_OverflowInterruptEnable = FREQME_CTRL_W_GT_MAX_INT_EN_MASK,  /*!< Enable interrupt when the result is
57                                                                                    greater than maximum value. */
58     kFREQME_ReadyInterruptEnable = FREQME_CTRL_W_RESULT_READY_INT_EN_MASK, /*!< Enable interrupt when a
59                                                                                  measurement completes and the result
60                                                                                  is ready. */
61 };
62 
63 /*!
64  * @brief FREQME module operate mode enumeration, including frequency measurement mode
65  * and pulse width measurement mode.
66  */
67 typedef enum _freqme_operate_mode
68 {
69     kFREQME_FreqMeasurementMode = 0U,  /*!< The module works in the frequency measurement mode. */
70     kFREOME_PulseWidthMeasurementMode, /*!< The module works in the pulse width measurement mode. */
71 } freqme_operate_mode_t;
72 
73 /*!
74  * @brief The enumeration of pulse polarity.
75  */
76 typedef enum _freqme_pulse_polarity
77 {
78     kFREQME_PulseHighPeriod = 0U, /*!< Select high period of the reference clock. */
79     kFREQME_PulseLowPeriod,       /*!< Select low period of the reference clock. */
80 } freqme_pulse_polarity_t;
81 
82 /*!
83  * @brief The union of operate mode attribute.
84  * @note If the operate mode is selected as frequency measurement mode the member \b refClkScaleFactor should be used,
85  * if the operate mode is selected as pulse width measurement mode the member \b pulsePolarity should be used.
86  */
87 typedef union _freqme_mode_attribute
88 {
89     uint8_t refClkScaleFactor;             /*!< Only useful in frequency measurement operate mode,
90                                                used to set the reference clock counter scaling factor. */
91     freqme_pulse_polarity_t pulsePolarity; /*!< Only Useful in pulse width measurement operate mode,
92                                                used to set period polarity. */
93 } freqme_mode_attribute_t;
94 
95 /*!
96  * @brief The structure of freqme module basic configuration,
97  * including operate mode, operate mode attribute and so on.
98  */
99 typedef struct _freq_measure_config
100 {
101     freqme_operate_mode_t operateMode; /*!< Select operate mode, please refer to @ref freqme_operate_mode_t. */
102     freqme_mode_attribute_t operateModeAttribute; /*!< Used to set the attribute of the selected operate mode, if
103                                                 the operate mode is selected as @ref kFREQME_FreqMeasurementMode
104                                                 set freqme_mode_attribute_t::refClkScaleFactor, if operate mode is
105                                                 selected as @ref kFREOME_PulseWidthMeasurementMode, please set
106                                                 freqme_mode_attribute_t::pulsePolarity.  */
107 
108     bool enableContinuousMode; /*!< Enable/disable continuous mode, if continuous mode is enable,
109                                   the measurement is performed continuously and the result for the
110                                   last completed measurement is available in the result register. */
111     bool startMeasurement;
112 } freq_measure_config_t;
113 
114 /*******************************************************************************
115  * API
116  ******************************************************************************/
117 
118 #if defined(__cplusplus)
119 extern "C" {
120 #endif
121 
122 /*!
123  * @name Basic Control APIs
124  * @{
125  */
126 /*!
127  * @brief Initialize freqme module, set operate mode, operate mode attribute and initialize measurement cycle.
128  *
129  * @param base FREQME peripheral base address.
130  * @param config The pointer to module basic configuration, please refer to @ref freq_measure_config_t.
131  */
132 void FREQME_Init(FREQME_Type *base, const freq_measure_config_t *config);
133 
134 /*!
135  * @brief Get default configuration.
136  *
137  * @code
138  *      config->operateMode = kFREQME_FreqMeasurementMode;
139  *      config->operateModeAttribute.refClkScaleFactor = 0U;
140  *      config->enableContinuousMode                   = false;
141  *      config->startMeasurement                       = false;
142  * @endcode
143  *
144  * @param config The pointer to module basic configuration, please refer to @ref freq_measure_config_t.
145  */
146 void FREQME_GetDefaultConfig(freq_measure_config_t *config);
147 
148 /*!
149  * @brief Start frequency or pulse width measurement process.
150  *
151  * @param base FREQME peripheral base address.
152  */
FREQME_StartMeasurementCycle(FREQME_Type * base)153 static inline void FREQME_StartMeasurementCycle(FREQME_Type *base)
154 {
155     uint32_t tmp32;
156 
157     tmp32 = base->CTRLSTAT;
158     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_MEASURE_IN_PROGRESS_MASK |
159                FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
160     tmp32 |= FREQME_CTRL_W_MEASURE_IN_PROGRESS_MASK;
161     base->CTRL_W = tmp32;
162 }
163 
164 /*!
165  * @brief Force the termination of any measurement cycle currently in progress and resets RESULT or just reset
166  * RESULT if the module in idle state.
167  *
168  * @param base FREQME peripheral base address.
169  */
FREQME_TerminateMeasurementCycle(FREQME_Type * base)170 static inline void FREQME_TerminateMeasurementCycle(FREQME_Type *base)
171 {
172     uint32_t tmp32;
173 
174     tmp32 = base->CTRLSTAT;
175     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_MEASURE_IN_PROGRESS_MASK |
176                FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
177     base->CTRL_W = tmp32;
178 }
179 
180 /*!
181  * @brief Enable/disable Continuous mode.
182  *
183  * @param base FREQME peripheral base address.
184  * @param enable Used to enable/disable continuous mode,
185  *              - \b true Enable Continuous mode.
186  *              - \b false Disable Continuous mode.
187  */
FREQME_EnableContinuousMode(FREQME_Type * base,bool enable)188 static inline void FREQME_EnableContinuousMode(FREQME_Type *base, bool enable)
189 {
190     uint32_t tmp32;
191 
192     tmp32 = base->CTRLSTAT;
193     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_CONTINUOUS_MODE_EN_MASK |
194                FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
195     if (enable)
196     {
197         tmp32 |= FREQME_CTRL_W_CONTINUOUS_MODE_EN_MASK;
198     }
199 
200     base->CTRL_W = tmp32;
201 }
202 
203 /*!
204  * @brief Check whether continuous mode is enabled.
205  *
206  * @param base FREQME peripheral base address.
207  * @retval True Continuous mode is enabled, the measurement is performed continuously.
208  * @retval False Continuous mode is disabled.
209  */
FREQME_CheckContinuousMode(FREQME_Type * base)210 static inline bool FREQME_CheckContinuousMode(FREQME_Type *base)
211 {
212     return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_CONTINUOUS_MODE_EN_MASK) != 0UL);
213 }
214 
215 /*!
216  * @brief Set operate mode of freqme module.
217  *
218  * @param base FREQME peripheral base address.
219  * @param operateMode The operate mode to be set, please refer to @ref freqme_operate_mode_t.
220  */
FREQME_SetOperateMode(FREQME_Type * base,freqme_operate_mode_t operateMode)221 static inline void FREQME_SetOperateMode(FREQME_Type *base, freqme_operate_mode_t operateMode)
222 {
223     uint32_t tmp32;
224 
225     tmp32 = base->CTRLSTAT;
226     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_PULSE_MODE_MASK |
227                FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
228     if (operateMode == kFREOME_PulseWidthMeasurementMode)
229     {
230         tmp32 |= FREQME_CTRL_W_PULSE_MODE_MASK;
231     }
232 
233     base->CTRL_W = tmp32;
234 }
235 
236 /*!
237  * @brief Check module's operate mode.
238  *
239  * @param base FREQME peripheral base address.
240  * @retval True Pulse width measurement mode.
241  * @retval False Frequency measurement mode.
242  */
FREQME_CheckOperateMode(FREQME_Type * base)243 static inline bool FREQME_CheckOperateMode(FREQME_Type *base)
244 {
245     return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_PULSE_MODE_MASK) != 0UL);
246 
247 }
248 
249 /*!
250  * @brief Set the minimum expected value for the measurement result.
251  *
252  * @param base FREQME peripheral base address.
253  * @param minValue The minimum value to set, please note that this value is 31 bits width.
254  */
FREQME_SetMinExpectedValue(FREQME_Type * base,uint32_t minValue)255 static inline void FREQME_SetMinExpectedValue(FREQME_Type *base, uint32_t minValue)
256 {
257     base->MIN = minValue;
258 }
259 
260 /*!
261  * @brief Set the maximum expected value for the measurement result.
262  *
263  * @param base FREQME peripheral base address.
264  * @param maxValue The maximum value to set, please note that this value is 31 bits width.
265  */
FREQME_SetMaxExpectedValue(FREQME_Type * base,uint32_t maxValue)266 static inline void FREQME_SetMaxExpectedValue(FREQME_Type *base, uint32_t maxValue)
267 {
268     base->MAX = maxValue;
269 }
270 
271 /*! @} */
272 
273 /*!
274  * @name Frequency Measurement Mode Control APIs
275  * @{
276  */
277 
278 /*!
279  * @brief Calculate the frequency of selected target clock。
280  *
281  * @note The formula: Ftarget = (RESULT - 2) * Freference / 2 ^ REF_SCALE.
282  *
283  * @note This function only useful when the operate mode is selected as frequency measurement mode.
284  *
285  * @param base FREQME peripheral base address.
286  * @param refClkFrequency The frequency of reference clock.
287  * @return The frequency of target clock the unit is Hz, if the output result is 0, please check the module's
288  *         operate mode.
289  */
290 uint32_t FREQME_CalculateTargetClkFreq(FREQME_Type *base, uint32_t refClkFrequency);
291 
292 /*!
293  * @brief Get reference clock scaling factor.
294  *
295  * @param base FREQME peripheral base address.
296  * @return Reference clock scaling factor, the reference count cycle is 2 ^ ref_scale.
297  */
FREQME_GetReferenceClkScaleValue(FREQME_Type * base)298 static inline uint8_t FREQME_GetReferenceClkScaleValue(FREQME_Type *base)
299 {
300     return (uint8_t)(base->CTRLSTAT & FREQME_CTRLSTAT_REF_SCALE_MASK);
301 }
302 
303 /*! @} */
304 
305 /*!
306  * @name Pulse Width Measurement Mode Control APIs
307  * @{
308  */
309 
310 /*!
311  * @brief Set pulse polarity when operate mode is selected as Pulse Width Measurement mode.
312  *
313  * @param base FREQME peripheral base address.
314  * @param pulsePolarity The pulse polarity to be set, please refer to @ref freqme_pulse_polarity_t.
315  */
FREQME_SetPulsePolarity(FREQME_Type * base,freqme_pulse_polarity_t pulsePolarity)316 static inline void FREQME_SetPulsePolarity(FREQME_Type *base, freqme_pulse_polarity_t pulsePolarity)
317 {
318     uint32_t tmp32;
319 
320     tmp32 = base->CTRLSTAT;
321     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_PULSE_POL_MASK |
322                FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
323 
324     if (pulsePolarity != kFREQME_PulseHighPeriod)
325     {
326         tmp32 |= FREQME_CTRL_W_PULSE_POL_MASK;
327     }
328 
329     base->CTRL_W = tmp32;
330 }
331 
332 /*!
333  * @brief Check pulse polarity when the operate mode is selected as pulse width measurement mode.
334  *
335  * @param base FREQME peripheral base address.
336  * @retval True Low period.
337  * @retval False High period.
338  */
FREQME_CheckPulsePolarity(FREQME_Type * base)339 static inline bool FREQME_CheckPulsePolarity(FREQME_Type *base)
340 {
341     return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_PULSE_POL_MASK) != 0UL);
342 }
343 
344 /*!
345  * @brief Get measurement result, if operate mode is selected as pulse width measurement mode this function can
346  * be used to calculate pulse width.
347  *
348  * @note Pulse width = counter result / Frequency of target clock.
349  *
350  * @param base FREQME peripheral base address.
351  * @return Measurement result.
352  */
FREQME_GetMeasurementResult(FREQME_Type * base)353 static inline uint32_t FREQME_GetMeasurementResult(FREQME_Type *base)
354 {
355     return base->CTRL_R & FREQME_CTRL_R_RESULT_MASK;
356 }
357 
358 /*! @} */
359 
360 /*!
361  * @name Status Control APIs
362  * @{
363  */
364 
365 /*!
366  * @brief Get interrupt status flags, such as overflow interrupt status flag,
367  * underflow interrupt status flag, and so on.
368  *
369  * @param base FREQME peripheral base address.
370  * @return Current interrupt status flags, should be the OR'ed value of @ref _freqme_interrupt_status_flags.
371  */
FREQME_GetInterruptStatusFlags(FREQME_Type * base)372 static inline uint32_t FREQME_GetInterruptStatusFlags(FREQME_Type *base)
373 {
374     return (base->CTRLSTAT & (uint32_t)kFREQME_AllInterruptStatusFlags);
375 }
376 
377 /*!
378  * @brief Clear interrupt status flags.
379  *
380  * @param base FREQME peripheral base address.
381  * @param statusFlags The combination of interrupt status flags to clear,
382  *                    should be the OR'ed value of @ref _freqme_interrupt_status_flags.
383  */
FREQME_ClearInterruptStatusFlags(FREQME_Type * base,uint32_t statusFlags)384 static inline void FREQME_ClearInterruptStatusFlags(FREQME_Type *base, uint32_t statusFlags)
385 {
386     base->CTRLSTAT |= statusFlags;
387 }
388 
389 /*! @} */
390 
391 /*!
392  * @name Interrupt Control APIs
393  * @{
394  */
395 
396 /*!
397  * @brief Enable interrupts, such as result ready interrupt, overflow interrupt and so on.
398  *
399  * @param base FREQME peripheral base address.
400  * @param masks The mask of interrupts to enable, should be the OR'ed value of @ref _freqme_interrupt_enable.
401  */
FREQME_EnableInterrupts(FREQME_Type * base,uint32_t masks)402 static inline void FREQME_EnableInterrupts(FREQME_Type *base, uint32_t masks)
403 {
404     uint32_t tmp32;
405 
406     tmp32 = base->CTRLSTAT;
407     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_LT_MIN_INT_EN_MASK |
408                FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_INT_EN_MASK |
409                FREQME_CTRLSTAT_RESULT_READY_INT_EN_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
410 
411     tmp32 |= masks;
412     base->CTRL_W = tmp32;
413 }
414 
415 /*!
416  * @brief Disable interrupts, such as result ready interrupt, overflow interrupt and so on.
417  *
418  * @param base FREQME peripheral base address.
419  * @param masks The mask of interrupts to disable, should be the OR'ed value of @ref _freqme_interrupt_enable.
420  */
FREQME_DisableInterrupts(FREQME_Type * base,uint32_t masks)421 static inline void FREQME_DisableInterrupts(FREQME_Type *base, uint32_t masks)
422 {
423     uint32_t tmp32;
424 
425     tmp32 = base->CTRLSTAT;
426     tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_STAT_MASK |
427                FREQME_CTRLSTAT_RESULT_READY_STAT_MASK | masks);
428 
429     base->CTRL_W = tmp32;
430 }
431 
432 /*! @} */
433 
434 #if defined(__cplusplus)
435 }
436 #endif
437 
438 /*!
439  * @}
440  */
441 #endif /* FSL_FREQME_H_ */
442