1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_fmeas.h"
10 
11 /*******************************************************************************
12  * Definitions
13  *******************************************************************************/
14 
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.fmeas"
18 #endif
19 
20 #if defined(FSL_FEATURE_FMEAS_ASYNC_SYSCON_FREQMECTRL) && (FSL_FEATURE_FMEAS_ASYNC_SYSCON_FREQMECTRL)
21 
22 /*! @brief Target clock counter value  */
23 #define TARGET_CLOCK_COUNT(base)                                                                    \
24     ((uint32_t)(((((FMEAS_SYSCON_Type *)base)->FREQMECTRL & FMEAS_SYSCON_FREQMECTRL_CAPVAL_MASK) >> \
25                  FMEAS_SYSCON_FREQMECTRL_CAPVAL_SHIFT) +                                            \
26                 1))
27 
28 /*! @brief Reference clock counter value */
29 #define REFERENCE_CLOCK_COUNT ((1 << FMEAS_INDEX) - 1)
30 
31 #elif defined(FSL_FEATURE_SOC_FREQME_COUNT) && (FSL_FEATURE_SOC_FREQME_COUNT)
32 /*! @brief Target clock counter value.
33  * According to user manual, 2 has to be subtracted from RESULT field. */
34 #define TARGET_CLOCK_COUNT(base) \
35     ((uint32_t)((((FREQME_Type *)base)->FREQMECTRL_R & FREQME_FREQMECTRL_R_RESULT_MASK) - 2U))
36 
37 /*! @brief Reference clock counter value. */
38 #define REFERENCE_CLOCK_COUNT ((uint32_t)(((uint32_t)1U) << 20U))
39 
40 #else
41 /*! @brief Target clock counter value.
42  * According to user manual, 2 has to be subtracted from captured value (CAPVAL). */
43 #define TARGET_CLOCK_COUNT(base) \
44     ((uint32_t)(                 \
45         ((((SYSCON_Type *)base)->FREQMECTRL & SYSCON_FREQMECTRL_CAPVAL_MASK) >> SYSCON_FREQMECTRL_CAPVAL_SHIFT) - 2U))
46 
47 /*! @brief Reference clock counter value. */
48 #define REFERENCE_CLOCK_COUNT \
49     ((uint32_t)((((uint32_t)SYSCON_FREQMECTRL_CAPVAL_MASK) >> (uint32_t)SYSCON_FREQMECTRL_CAPVAL_SHIFT) + (uint32_t)1U))
50 
51 #endif
52 
53 /*******************************************************************************
54  * Code
55  ******************************************************************************/
56 
57 /*!
58  * brief    Returns the computed value for a frequency measurement cycle
59  *
60  * param    base         : SYSCON peripheral base address.
61  * param    refClockRate : Reference clock rate used during the frequency measurement cycle.
62  *
63  * return   Frequency in Hz.
64  */
FMEAS_GetFrequency(FMEAS_SYSCON_Type * base,uint32_t refClockRate)65 uint32_t FMEAS_GetFrequency(FMEAS_SYSCON_Type *base, uint32_t refClockRate)
66 {
67     uint32_t targetClockCount = TARGET_CLOCK_COUNT(base);
68     uint64_t clkrate          = 0;
69 
70     if (((int32_t)targetClockCount) > 0)
71     {
72         clkrate = (((uint64_t)targetClockCount) * (uint64_t)refClockRate) / REFERENCE_CLOCK_COUNT;
73     }
74 
75 #if defined(SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK) && defined(SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK)
76     /* Assume measurement complete - gate high freq clock FRO1M and XTAL32M to FMEAS */
77     SYSCON->CLOCK_CTRL &= ~(SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK | SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK);
78 #endif
79 
80     return (uint32_t)clkrate;
81 }
82 
83 #if defined(FSL_FEATURE_FMEAS_GET_COUNT_SCALE) && (FSL_FEATURE_FMEAS_GET_COUNT_SCALE)
FMEAS_GetCountWithScale(FMEAS_SYSCON_Type * base,uint8_t scale,uint32_t * refClockCount,uint32_t * targetClockCount)84 void FMEAS_GetCountWithScale(FMEAS_SYSCON_Type *base,
85                              uint8_t scale,
86                              uint32_t *refClockCount,
87                              uint32_t *targetClockCount)
88 {
89     *targetClockCount = TARGET_CLOCK_COUNT(base);
90     *refClockCount    = ((1 << scale) - 1);
91 
92     /* Assume measurement complete - gate high freq clock FRO1M and XTAL32M to FMEAS */
93     SYSCON->CLOCK_CTRL &= ~(SYSCON_CLOCK_CTRL_FRO1MHZ_FREQM_ENA_MASK | SYSCON_CLOCK_CTRL_XTAL32MHZ_FREQM_ENA_MASK);
94 }
95 #endif /*FSL_FEATURE_FMEAS_GET_COUNT_SCALE*/
96