1 /*
2  * Copyright 2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_SYSCTR_H_
9 #define FSL_SYSCTR_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup sysctr
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 /*! @name Driver version */
22 /*! @{ */
23 /*! @brief System Counter driver version. */
24 #define FSL_SYSCTR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
25 /*! @{ */
26 
27 /*! @brief System Counter clock source selection. */
28 typedef enum _sysctr_clock_source
29 {
30     kSYSCTR_BaseFrequency = 0U,     /*!< 24MHz base clock from crystal oscillator is used as the clock. */
31     kSYSCTR_AlternateFrequency      /*!< 32kHz alternate slow clock from crystal oscillator is used as the clock. */
32 } sysctr_clock_source_t;
33 
34 /*! @brief System Counter compare frame selection. */
35 typedef enum _sysctr_compare_frame
36 {
37     kSYSCTR_CompareFrame_0 = 0U,        /*!< Select compare frame 0. */
38     kSYSCTR_CompareFrame_1              /*!< Select compare frame 1. */
39 } sysctr_compare_frame_t;
40 
41 /*! @brief System Counter frequency modes table selection. */
42 typedef enum _sysctr_frequency_modes_table
43 {
44     kSYSCTR_FrequencyModesTable_0 = 0U,     /*!< Select frequency modes table 0. */
45     kSYSCTR_FrequencyModesTable_1,          /*!< Select frequency modes table 1. */
46     kSYSCTR_FrequencyModesTable_2           /*!< Select frequency modes table 2. */
47 } sysctr_frequency_modes_table_t;
48 
49 /*! @brief List of System Counter interrupt options. */
50 typedef enum _sysctr_interrupt_enable
51 {
52     kSYSCTR_Compare0InterruptEnable = SYS_CTR_COMPARE_CMPCR0_IMASK_MASK,            /*!< Compare frame 0 interrupt. */
53     kSYSCTR_Compare1InterruptEnable = SYS_CTR_COMPARE_CMPCR1_IMASK_MASK << 16U      /*!< Compare frame 1 interrupt. */
54 } sysctr_interrupt_enable_t;
55 
56 /*! @brief List of System Counter status flags. */
57 typedef enum _sysctr_status_flags
58 {
59     kSYSCTR_Compare0Flag = SYS_CTR_COMPARE_CMPCR0_ISTAT_MASK,               /*!< Compare frame 0 compare flag. */
60     kSYSCTR_Compare1Flag = SYS_CTR_COMPARE_CMPCR1_ISTAT_MASK << 16U         /*!< Compare frame 1 compare flag. */
61 } sysctr_status_flags_t;
62 
63 /*!
64  * @brief System Counter config structure
65  *
66  * This structure holds the configuration settings for the System Counter peripheral.
67  * To initialize this structure to reasonable defaults, call the PWM_GetDefaultConfig()
68  * function and pass a pointer to your config structure instance.
69  */
70 typedef struct _sysctr_config
71 {
72     bool enableDebugHalt;                       /*!< true: Debug input causes the System Counter to halt;
73                                                      false: Debug input is ignored */
74     bool enableHardwareFrequencyChange;         /*!< true: Hardware changes frequency automatically when entering
75                                                            or exiting low power mode;
76                                                      false: Frequency changes are fully under software control */
77 } sysctr_config_t;
78 
79 /*!
80  * @brief System Counter status flags.
81  *
82  * This provides constants for the System Counter status flags for use in the System Counter functions.
83  * The system counter status flags provide information concerning the clock frequency and debug state.
84  */
85 enum _sysctr_flags
86 {
87     kSYSCTR_DebugHalt = SYS_CTR_CONTROL_CNTSR_DBGH_MASK,
88     kSYSCTR_FrequencyChangeAck_0 = SYS_CTR_CONTROL_CNTSR_FCA0_MASK,
89     kSYSCTR_FrequencyChangeAck_1 = SYS_CTR_CONTROL_CNTSR_FCA1_MASK
90 };
91 
92 /*******************************************************************************
93  * API
94  ******************************************************************************/
95 
96 #if defined(__cplusplus)
97 extern "C" {
98 #endif
99 
100 /*!
101  * @name Initialization and deinitialization
102  * @{
103  */
104 
105 /*!
106  * @brief Initializes a System Counter instance.
107  *
108  * This function initializes the System Counter module with user-defined settings.
109  * This example shows how to set up the sysctr_config_t parameters and how to call
110  * the SYSCTR_Init function by passing in these parameters. Default clock source
111  * is 24MHz base clock from crystal oscillator.
112  * @code
113  *   sysctr_config_t sysctrConfig;
114  *   sysctrConfig.enableDebugHalt               = false;
115  *   sysctrConfig.enableHardwareFrequencyChange = false;
116  *   SYSCTR_Init(SYS_CTR_CONTROL, SYS_CTR_COMPARE, &sysctr_config_t);
117  * @endcode
118  *
119  * @param ctrlBase System Counter peripheral control model base address.
120  * @param cmpBase  System Counter peripheral compare model base address.
121  * @param pConfig  Configuration pointer to user's System Counter config structure.
122  */
123 void SYSCTR_Init(SYS_CTR_CONTROL_Type *ctrlBase, SYS_CTR_COMPARE_Type *cmpBase, const sysctr_config_t *pConfig);
124 
125 /*!
126  * @brief De-initializes a System Counter instance.
127  *
128  * This function disables the System Counter module clock and sets all register values
129  * to the reset value.
130  *
131  * @param ctrlBase System Counter peripheral control model base address.
132  * @param cmpBase  System Counter peripheral compare model base address.
133  */
134 void SYSCTR_Deinit(SYS_CTR_CONTROL_Type *ctrlBase, SYS_CTR_COMPARE_Type *cmpBase);
135 
136 /*!
137  * @brief Fill in the System Counter config struct with the default settings.
138  *
139  * The default values are:
140  * @code
141  *   config->enableDebugHalt = false;
142  *   config->enableHardwareFrequencyChange = false;
143  * @endcode
144  *
145  * @param pConfig Configuration pointer to user's System Counter config structure.
146  */
147 void SYSCTR_GetDefaultConfig(sysctr_config_t *pConfig);
148 
149 /*! @}*/
150 
151 /*!
152  * @name Interrupts Interface
153  * @{
154  */
155 
156 /*!
157  * @brief Enables the selected System Counter interrupts
158  *
159  * @param base System Counter peripheral compare model base address.
160  * @param mask The interrupts to enable. This is a logical OR of members of the
161  *             enumeration ::sysctr_interrupt_enable_t.
162  */
SYSCTR_EnableInterrupts(SYS_CTR_COMPARE_Type * base,uint32_t mask)163 static inline void SYSCTR_EnableInterrupts(SYS_CTR_COMPARE_Type *base, uint32_t mask)
164 {
165     base->CMPCR0 &= ~(mask & SYS_CTR_COMPARE_CMPCR0_IMASK_MASK);
166     base->CMPCR1 &= ~((mask >> 16U) & SYS_CTR_COMPARE_CMPCR1_IMASK_MASK);
167 }
168 
169 /*!
170  * @brief Disable the selected System Counter interrupts
171  *
172  * @param base System Counter peripheral compare model base address.
173  * @param mask The interrupts to disable. This is a logical OR of members of the
174  *             enumeration ::sysctr_interrupt_enable_t.
175  */
SYSCTR_DisableInterrupts(SYS_CTR_COMPARE_Type * base,uint32_t mask)176 static inline void SYSCTR_DisableInterrupts(SYS_CTR_COMPARE_Type *base, uint32_t mask)
177 {
178     base->CMPCR0 |= mask & SYS_CTR_COMPARE_CMPCR0_IMASK_MASK;
179     base->CMPCR1 |= ((mask >> 16U) & SYS_CTR_COMPARE_CMPCR1_IMASK_MASK);
180 }
181 
182 /*! @}*/
183 
184 /*!
185  * @name Status Interface
186  * @{
187  */
188 
189 /*!
190  * @brief Get System Counter status flags
191  *
192  * @param base System Counter peripheral compare model base address.
193  *
194  * @return The status flags. This is the logical OR of members of the
195  *         enumeration ::sysctr_status_flags_t.
196  */
SYSCTR_GetStatusFlags(SYS_CTR_COMPARE_Type * base)197 static inline uint32_t SYSCTR_GetStatusFlags(SYS_CTR_COMPARE_Type *base)
198 {
199     uint32_t statusFlags;
200 
201     statusFlags = base->CMPCR0 & SYS_CTR_COMPARE_CMPCR0_ISTAT_MASK;
202     statusFlags |= ((base->CMPCR1 & SYS_CTR_COMPARE_CMPCR1_ISTAT_MASK) << 16U);
203 
204     return statusFlags;
205 }
206 
207 /*! @}*/
208 
209 /*!
210  * @name Counter Start and Stop
211  * @{
212  */
213 
214 /*!
215  * @brief Enables the System Counter counting.
216  *
217  * @param base System Counter peripheral control model base address.
218  */
SYSCTR_StartCounter(SYS_CTR_CONTROL_Type * base)219 static inline void SYSCTR_StartCounter(SYS_CTR_CONTROL_Type *base)
220 {
221     base->CNTCR |= SYS_CTR_CONTROL_CNTCR_EN_MASK;
222 }
223 
224 /*!
225  * @brief Disables the System Counter counting.
226  *
227  * @param base System Counter peripheral control model base address.
228  */
SYSCTR_StopCounter(SYS_CTR_CONTROL_Type * base)229 static inline void SYSCTR_StopCounter(SYS_CTR_CONTROL_Type *base)
230 {
231     base->CNTCR &= ~SYS_CTR_CONTROL_CNTCR_EN_MASK;
232 }
233 
234 /*! @}*/
235 
236 /*!
237  * @brief Set System Counter count value.
238  *
239  * User can set System Counter initial count value before starting counter.
240  * Be cautious that user must set count value while operating on the base frequency only.
241  * Set count value while running on the alternate frequency may have unpredictable results.
242  *
243  * @param base  System Counter peripheral control model base address.
244  * @param value System Counter count value.
245  */
SYSCTR_SetCounterlValue(SYS_CTR_CONTROL_Type * base,uint64_t value)246 static inline void SYSCTR_SetCounterlValue(SYS_CTR_CONTROL_Type *base, uint64_t value)
247 {
248     assert((base->CNTSR & SYS_CTR_CONTROL_CNTSR_FCA1_MASK) == 0);
249 
250     base->CNTCV0 = (uint32_t)(value & SYS_CTR_CONTROL_CNTCV0_CNTCV0_MASK);
251     base->CNTCV1 = (uint32_t)((value >> 32U) & SYS_CTR_CONTROL_CNTCV1_CNTCV1_MASK);
252 }
253 
254 /*!
255  * @brief Get System Counter current count value.
256  *
257  * @param base System Counter peripheral read model base address.
258  *
259  * @return System Counter current count value.
260  */
SYSCTR_GetCounterlValue(SYS_CTR_READ_Type * base)261 static inline uint64_t SYSCTR_GetCounterlValue(SYS_CTR_READ_Type *base)
262 {
263     uint64_t value;
264 
265     value = base->CNTCV0;
266     value |= ((uint64_t)base->CNTCV1 << 32U);
267 
268     return value;
269 }
270 
271 /*!
272  * @brief Set System Counter clock source.
273  *
274  * @param base                  System Counter peripheral control model base address.
275  * @param sysctr_clock_source_t System Counter clock source.
276  */
277 void SYSCTR_SetCounterClockSource(SYS_CTR_CONTROL_Type *base, sysctr_clock_source_t clockSource);
278 
279 /*!
280  * @brief Enable or disable compare function of specific compare frame.
281  *
282  * @param base     System Counter peripheral control model base address.
283  * @param cmpFrame System Counter compare frame selection.
284  * @param enable   true: Enable compare function; false: Disable compare function
285  */
286 void SYSCTR_EnableCompare(SYS_CTR_COMPARE_Type *base, sysctr_compare_frame_t cmpFrame, bool enable);
287 
288 /*!
289  * @brief Set System Counter compare value of specific compare frame.
290  *
291  * Be cautious that user must set compare value while operating on the base frequency only.
292  * Set compare value while running on the alternate frequency may have unpredictable results.
293  *
294  * @param ctrlBase System Counter peripheral control model base address.
295  * @param cmpBase  System Counter peripheral compare model base address.
296  * @param cmpFrame System Counter compare frame selection.
297  * @param value    System Counter compare value.
298  */
299 void SYSCTR_SetCompareValue(SYS_CTR_CONTROL_Type *ctrlBase,
300                             SYS_CTR_COMPARE_Type *cmpBase,
301                             sysctr_compare_frame_t cmpFrame,
302                             uint64_t value);
303 
304 /*!
305  * @brief Get specific Frequency Modes Table value.
306  *
307  * @param base  System Counter peripheral control model base address.
308  * @param index Frequency Modes Table index.
309  *
310  * @return Frequency modes table value.
311  */
312 uint32_t SYSCTR_GetFrequencyModesTableValue(SYS_CTR_CONTROL_Type *base, sysctr_frequency_modes_table_t index);
313 
314 
315 #if defined(__cplusplus)
316 }
317 #endif
318 
319 #endif
320