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