1 /*
2  * Copyright 2022, 2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef FSL_EQDC_H_
8 #define FSL_EQDC_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup eqdc
14  * @{
15  */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 #define FSL_EQDC_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
21 
22 /*! @brief W1C bits in EQDC CTRL registers. */
23 #define EQDC_CTRL_W1C_FLAGS (EQDC_CTRL_HIRQ_MASK | EQDC_CTRL_XIRQ_MASK | EQDC_CTRL_WDIRQ_MASK)
24 
25 /*! @brief W1C bits in EQDC INTCTRL registers. */
26 #define EQDC_INTCTRL_W1C_FLAGS                                                                                 \
27     (EQDC_INTCTRL_SABIRQ_MASK | EQDC_INTCTRL_DIRIRQ_MASK | EQDC_INTCTRL_RUIRQ_MASK | EQDC_INTCTRL_ROIRQ_MASK | \
28      EQDC_INTCTRL_CMP0IRQ_MASK | EQDC_INTCTRL_CMP1IRQ_MASK | EQDC_INTCTRL_CMP2IRQ_MASK | EQDC_INTCTRL_CMP3IRQ_MASK)
29 
30 /*! @brief Interrupt enable bits in EQDC CTRL registers. */
31 #define EQDC_CTRL_INT_EN (EQDC_CTRL_HIE_MASK | EQDC_CTRL_XIE_MASK | EQDC_CTRL_WDIE_MASK)
32 
33 /*! @brief Interrupt enable bits in EQDC INTCTRL registers. */
34 #if (defined(FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT) && FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT)
35 #define EQDC_INTCTRL_INT_EN                                                                                \
36     (EQDC_INTCTRL_SABIE_MASK | EQDC_INTCTRL_DIRIE_MASK | EQDC_INTCTRL_RUIE_MASK | EQDC_INTCTRL_ROIE_MASK)
37 #else
38 #define EQDC_INTCTRL_INT_EN                                                                                \
39     (EQDC_INTCTRL_SABIE_MASK | EQDC_INTCTRL_DIRIE_MASK | EQDC_INTCTRL_RUIE_MASK | EQDC_INTCTRL_ROIE_MASK | \
40      EQDC_INTCTRL_CMP0IE_MASK | EQDC_INTCTRL_CMP1IE_MASK | EQDC_INTCTRL_CMP2IE_MASK | EQDC_INTCTRL_CMP3IE_MASK)
41 #endif
42 
43 /*! @brief Interrupt flag bits in EQDC CTRL registers. */
44 #define EQDC_CTRL_INT_FLAGS (EQDC_CTRL_HIRQ_MASK | EQDC_CTRL_XIRQ_MASK | EQDC_CTRL_WDIRQ_MASK)
45 
46 /*! @brief Interrupt flag bits in EQDC INTCTRL registers. */
47 #define EQDC_INTCTRL_INT_FLAGS                                                                                 \
48     (EQDC_INTCTRL_SABIRQ_MASK | EQDC_INTCTRL_DIRIRQ_MASK | EQDC_INTCTRL_RUIRQ_MASK | EQDC_INTCTRL_ROIRQ_MASK | \
49      EQDC_INTCTRL_CMP0IRQ_MASK | EQDC_INTCTRL_CMP1IRQ_MASK | EQDC_INTCTRL_CMP2IRQ_MASK | EQDC_INTCTRL_CMP3IRQ_MASK)
50 
51 #if !(defined(FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT) && FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT)
52 #define kEQDC_PositionCompare0InerruptEnable kEQDC_PositionCompare0InterruptEnable
53 #define kEQDC_PositionCompare1InerruptEnable kEQDC_PositionCompare1InterruptEnable
54 #define kEQDC_PositionCompare2InerruptEnable kEQDC_PositionCompare2InterruptEnable
55 #define kEQDC_PositionCompare3InerruptEnable kEQDC_PositionCompare3InterruptEnable
56 #endif
57 
58 /*!
59  * @brief EQDC status flags, these flags indicate the counter's events.
60  * @anchor _eqdc_status_flags
61  */
62 enum _eqdc_status_flags
63 {
64     kEQDC_HomeEnableTransitionFlag = EQDC_CTRL_HIRQ_MASK,  /*!< HOME/ENABLE signal transition occured. */
65     kEQDC_IndexPresetPulseFlag     = EQDC_CTRL_XIRQ_MASK,  /*!< INDEX/PRESET  pulse occured. */
66     kEQDC_WatchdogTimeoutFlag      = EQDC_CTRL_WDIRQ_MASK, /*!< Watchdog timeout occured. */
67 
68     kEQDC_SimultPhaseChangeFlag = (uint32_t)EQDC_INTCTRL_SABIRQ_MASK
69                                   << 16U, /*!< Simultaneous change of PHASEA and PHASEB occured. */
70     kEQDC_CountDirectionChangeFlag = (uint32_t)EQDC_INTCTRL_DIRIRQ_MASK
71                                      << 16U, /*!< Count direction change interrupt enable. */
72     kEQDC_PositionRollOverFlag = (uint32_t)EQDC_INTCTRL_ROIRQ_MASK
73                                  << 16U, /*!< Position counter rolls over from 0xFFFFFFFF to 0, or
74                                          from MOD value to INIT value. */
75     kEQDC_PositionRollUnderFlag = (uint32_t)EQDC_INTCTRL_RUIRQ_MASK
76                                   << 16U, /*!< Position register roll under from 0 to 0xFFFFFFFF, or
77                                               from INIT value to MOD value. */
78 
79     kEQDC_PositionCompare0Flag = (uint32_t)EQDC_INTCTRL_CMP0IRQ_MASK
80                                  << 16U, /*!< Position counter match the COMP0 value. */
81     kEQDC_PositionCompare1Flag = (uint32_t)EQDC_INTCTRL_CMP1IRQ_MASK
82                                  << 16U, /*!< Position counter match the COMP1 value. */
83     kEQDC_PositionCompare2Flag = (uint32_t)EQDC_INTCTRL_CMP2IRQ_MASK
84                                  << 16U, /*!< Position counter match the COMP2 value. */
85     kEQDC_PositionCompare3Flag = (uint32_t)EQDC_INTCTRL_CMP3IRQ_MASK
86                                  << 16U, /*!< Position counter match the COMP3 value. */
87 
88     kEQDC_StatusAllFlags = kEQDC_HomeEnableTransitionFlag | kEQDC_IndexPresetPulseFlag | kEQDC_WatchdogTimeoutFlag |
89                            kEQDC_SimultPhaseChangeFlag | kEQDC_PositionRollOverFlag | kEQDC_PositionRollUnderFlag |
90                            kEQDC_PositionCompare0Flag | kEQDC_PositionCompare1Flag | kEQDC_PositionCompare2Flag |
91                            kEQDC_PositionCompare3Flag
92 };
93 
94 /*!
95  * @brief Signal status, these flags indicate the raw and filtered input signal status.
96  * @anchor _eqdc_signal_status
97  */
98 enum _eqdc_signal_status
99 {
100     kEQDC_SignalStatusRawHomeEnable       = EQDC_IMR_HOME_ENABLE_MASK,  /*!< Raw HOME/ENABLE input. */
101     kEQDC_SignalStatusRawIndexPreset      = EQDC_IMR_INDEX_PRESET_MASK, /*!< Raw INDEX/PRESET input. */
102     kEQDC_SignalStatusRawPhaseB           = EQDC_IMR_PHB_MASK,          /*!< Raw PHASEB input. */
103     kEQDC_SignalStatusRawPhaseA           = EQDC_IMR_PHA_MASK,          /*!< Raw PHASEA input. */
104     kEQDC_SignalStatusFilteredHomeEnable  = EQDC_IMR_FHOM_ENA_MASK,     /*!< The filtered HOME/ENABLE input. */
105     kEQDC_SignalStatusFilteredIndexPreset = EQDC_IMR_FIND_PRE_MASK,     /*!< The filtered INDEX/PRESET input. */
106     kEQDC_SignalStatusFilteredPhaseB      = EQDC_IMR_FPHB_MASK,         /*!< The filtered PHASEB input. */
107     kEQDC_SignalStatusFilteredPhaseA      = EQDC_IMR_FPHA_MASK,         /*!< The filtered PHASEA input. */
108 
109     kEQDC_SignalStatusPositionCompare0Flag   = EQDC_IMR_CMPF0_MASK, /*!< Position Compare 0 Flag Output. */
110     kEQDC_SignalStatusPositionCompare1Flag   = EQDC_IMR_CMP1F_MASK, /*!< Position Compare 1 Flag Output. */
111     kEQDC_SignalStatusPositionCompare2Flag   = EQDC_IMR_CMP2F_MASK, /*!< Position Compare 2 Flag Output. */
112     kEQDC_SignalStatusPositionCompare3Flag   = EQDC_IMR_CMP3F_MASK, /*!< Position Compare 3 Flag Output. */
113     kEQDC_SignalStatusCountDirectionFlagHold = EQDC_IMR_DIRH_MASK,  /*!< Count Direction Flag Hold. */
114     kEQDC_SignalStatusCountDirectionFlag     = EQDC_IMR_DIR_MASK,   /*!< Count Direction Flag Output. */
115 
116     kEQDC_SignalStatusAllFlags = kEQDC_SignalStatusRawHomeEnable | kEQDC_SignalStatusRawIndexPreset |
117                                  kEQDC_SignalStatusRawPhaseB | kEQDC_SignalStatusRawPhaseA |
118                                  kEQDC_SignalStatusFilteredHomeEnable | kEQDC_SignalStatusFilteredIndexPreset |
119                                  kEQDC_SignalStatusFilteredPhaseB | kEQDC_SignalStatusFilteredPhaseA |
120                                  kEQDC_SignalStatusPositionCompare0Flag | kEQDC_SignalStatusPositionCompare1Flag |
121                                  kEQDC_SignalStatusPositionCompare2Flag | kEQDC_SignalStatusPositionCompare3Flag |
122                                  kEQDC_SignalStatusCountDirectionFlagHold | kEQDC_SignalStatusCountDirectionFlag
123 };
124 
125 /*!
126  * @brief Interrupt enable/disable mask.
127  * @anchor _eqdc_interrupt_enable
128  */
129 enum _eqdc_interrupt_enable
130 {
131     kEQDC_HomeEnableTransitionInterruptEnable =
132         EQDC_CTRL_HIE_MASK,                                      /*!< HOME/ENABLE signal transition interrupt enable. */
133     kEQDC_IndexPresetPulseInterruptEnable = EQDC_CTRL_XIE_MASK,  /*!< INDEX/PRESET pulse interrupt enable. */
134     kEQDC_WatchdogTimeoutInterruptEnable  = EQDC_CTRL_WDIE_MASK, /*!< Watchdog timeout interrupt enable. */
135 
136     kEQDC_SimultPhaseChangeInterruptEnable = (uint32_t)EQDC_INTCTRL_SABIE_MASK
137                                              << 16U, /*!< Simultaneous PHASEA and PHASEB change interrupt enable. */
138     kEQDC_CountDirectionChangeInterruptEnable = (uint32_t)EQDC_INTCTRL_DIRIE_MASK
139                                              << 16U, /*!< Count direction change interrupt enable. */
140     kEQDC_PositionRollOverInterruptEnable = (uint32_t)EQDC_INTCTRL_ROIE_MASK << 16U, /*!< Roll-over interrupt enable. */
141     kEQDC_PositionRollUnderInterruptEnable = (uint32_t)EQDC_INTCTRL_RUIE_MASK
142                                              << 16U, /*!< Roll-under interrupt enable. */
143 
144 #if !(defined(FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT) && FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT)
145     kEQDC_PositionCompare0InterruptEnable = (uint32_t)EQDC_INTCTRL_CMP0IE_MASK
146                                            << 16U, /*!< Position compare 0 interrupt enable. */
147     kEQDC_PositionCompare1InterruptEnable = (uint32_t)EQDC_INTCTRL_CMP1IE_MASK
148                                            << 16U, /*!< Position compare 1 interrupt enable. */
149     kEQDC_PositionCompare2InterruptEnable = (uint32_t)EQDC_INTCTRL_CMP2IE_MASK
150                                            << 16U, /*!< Position compare 2 interrupt enable. */
151     kEQDC_PositionCompare3InterruptEnable = (uint32_t)EQDC_INTCTRL_CMP3IE_MASK
152                                            << 16U, /*!< Position compare 3 interrupt enable. */
153 #endif
154 
155 #if (defined(FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT) && FSL_FEATURE_EQDC_HAS_NO_COMPARE_INTERRUPT)
156     kEQDC_AllInterruptEnable = kEQDC_HomeEnableTransitionInterruptEnable | kEQDC_IndexPresetPulseInterruptEnable |
157                                kEQDC_WatchdogTimeoutInterruptEnable | kEQDC_SimultPhaseChangeInterruptEnable |
158                                kEQDC_CountDirectionChangeInterruptEnable | kEQDC_PositionRollOverInterruptEnable |
159                                kEQDC_PositionRollUnderInterruptEnable
160 #else
161     kEQDC_AllInterruptEnable = kEQDC_HomeEnableTransitionInterruptEnable | kEQDC_IndexPresetPulseInterruptEnable |
162                                kEQDC_WatchdogTimeoutInterruptEnable | kEQDC_SimultPhaseChangeInterruptEnable |
163                                kEQDC_CountDirectionChangeInterruptEnable | kEQDC_PositionRollOverInterruptEnable |
164                                kEQDC_PositionRollUnderInterruptEnable | kEQDC_PositionCompare0InterruptEnable |
165                                kEQDC_PositionCompare1InterruptEnable | kEQDC_PositionCompare2InterruptEnable |
166                                kEQDC_PositionCompare3InterruptEnable
167 #endif
168 };
169 
170 /*!
171  * @brief Define HOME/ENABLE signal's trigger mode.
172  */
173 typedef enum _eqdc_home_enable_init_pos_counter_mode
174 {
175     /*! Don't use HOME/ENABLE signal to initialize the position counter. */
176     kEQDC_HomeInitPosCounterDisabled = 0U,
177 
178     /*! Use positive going edge to trigger initialization of position counters. */
179     kEQDC_HomeInitPosCounterOnRisingEdge = EQDC_CTRL_HIP_MASK,
180 
181     /*! Use negative going edge to trigger initialization of position counters. */
182     kEQDC_HomeInitPosCounterOnFallingEdge = EQDC_CTRL_HIP_MASK | EQDC_CTRL_HNE_MASK,
183 } eqdc_home_enable_init_pos_counter_mode_t;
184 
185 /*!
186  * @brief Define INDEX/PRESET signal's trigger mode.
187  */
188 typedef enum _eqdc_index_preset_init_pos_counter_mode
189 {
190     /*! INDEX/PRESET pulse does not initialize the position counter. */
191     kEQDC_IndexInitPosCounterDisabled = 0U,
192 
193     /*! Use INDEX/PRESET pulse rising edge to initialize position counter. */
194     kEQDC_IndexInitPosCounterOnRisingEdge = EQDC_CTRL_XIP_MASK,
195 
196     /*! Use INDEX/PRESET pulse falling edge to initialize position counter. */
197     kEQDC_IndexInitPosCounterOnFallingEdge = EQDC_CTRL_XIP_MASK | EQDC_CTRL_XNE_MASK,
198 } eqdc_index_preset_init_pos_counter_mode_t;
199 
200 /*!
201  * @brief Define type for decoder opertion mode.
202  *
203  * The Quadrature Decoder operates in following 4 operation modes:
204  *   1.Quadrature Decode(QDC) Operation Mode (CTRL[PH1] = 0,CTRL2[OPMODE] = 0)
205  *   In QDC operation mode, Module uses PHASEA, PHASEB, INDEX, HOME, TRIGGER
206  *   and ICAP[3:1] to decode the PHASEA and PHASEB signals from Speed/Position sensor.
207  *   2.Quadrature Count(QCT) Operation Mode (CTRL[PH1] = 0,CTRL2[OPMODE] = 1)
208  *   In QCT operation mode, Module uses PHASEA, PHASEB, PRESET, ENABLE,
209  *   TRIGGER and ICAP[3:1] to count the PHASEA and PHASEB signals from Speed/Position sensor.
210  *   3.Single Phase Decode(PH1DC) Operation Mode (CTRL[PH1] = 1,CTRL2[OPMODE] = 0)
211  *   In PH1DC operation mode, the module uses PHASEA, PHASEB, INDEX, HOME,
212  *   TRIGGER and ICAP[3:1] to decode the PHASEA and PHASEB signals from Speed/Position sensor.
213  *   4.Single Phase Count(PH1CT) Operation Mode (CTRL[PH1] = 1,CTRL2[OPMODE] = 1)
214  *   In PH1CT operation mode, the module uses PHASEA, PHASEB, PRESET, ENABLE,
215  *   TRIGGER and ICAP[3:1] to count the PHASEA and PHASEB signals from Speed/Position sensor.
216  */
217 typedef enum _eqdc_operate_mode
218 {
219     kEQDC_QuadratureDecodeOperationMode = 0U, /*!< Use standard quadrature decoder with PHASEA/PHASEB, INDEX/HOME. */
220     kEQDC_QuadratureCountOperationMode,   /*!< Use quadrature count operation mode with PHASEA/PHASEB, PRESET/ENABLE. */
221     kEQDC_SinglePhaseDecodeOperationMode, /*!< Use single phase quadrature decoder with PHASEA/PHASEB, INDEX/HOME. */
222     kEQDC_SinglePhaseCountOperationMode,  /*!< Use single phase count decoder with PHASEA/PHASEB, PRESET/ENABLE. */
223 } eqdc_operate_mode_t;
224 
225 /*!
226  * @brief Define type for decoder count mode.
227  *
228  * In decode mode, it uses the standard quadrature decoder with PHASEA and PHASEB,
229  * PHASEA = 0 and PHASEB = 0 mean reverse direction.
230  *      - If PHASEA leads PHASEB, then motion is in the positive direction.
231  *      - If PHASEA trails PHASEB,then motion is in the negative direction.
232  * In single phase mode, there are three count modes:
233  *      - In Signed Count mode (Single Edge). Both position counter (POS) and position difference counter (POSD) count
234  *      on the input PHASEA rising edge while the input PHASEB provides the selected position counter direction
235  * (up/down). If CTRL[REV] is 1, then the position counter will count in the opposite direction.
236  *      - In Signed Count mode (double edge), both position counter (POS) and
237  *      position difference counter (POSD) count the input PHASEA on both rising edge and falling edge while the input
238  * PHASEB provides the selected position counter direction (up/down).
239  *      - In UP/DOWN Pulse Count mode. Both position counter (POS) and position difference counter (POSD) count in the
240  * up direction when input PHASEA rising edge occurs. Both counters count in the down direction when input PHASEB rising
241  * edge occurs. If CTRL[REV] is 1, then the position counter will count in the opposite direction.
242  */
243 typedef enum _eqdc_count_mode
244 {
245     kEQDC_QuadratureX4 = 0U, /*!< Active on kEQDC_QuadratureDecodeOperationMode/kEQDC_QuadratureCountOperationMode. */
246     kEQDC_QuadratureX2 = 1U, /*!< Active on kEQDC_QuadratureDecodeOperationMode/kEQDC_QuadratureCountOperationMode. */
247     kEQDC_QuadratureX1 = 2U, /*!< Active on kEQDC_QuadratureDecodeOperationMode/kEQDC_QuadratureCountOperationMode. */
248     kEQDC_UpDownPulseCount =
249         0U, /*!< Active on kEQDC_SinglePhaseDecodeOperationMode/kEQDC_SinglePhaseCountOperationMode. */
250     kEQDC_SignedCountDoubleEdge =
251         1U, /*!< Active on kEQDC_SinglePhaseDecodeOperationMode/kEQDC_SinglePhaseCountOperationMode. */
252     kEQDC_SignedCountSingleEdge =
253         2U, /*!< Active on kEQDC_SinglePhaseDecodeOperationMode/kEQDC_SinglePhaseCountOperationMode. */
254 } eqdc_count_mode_t;
255 
256 /*!
257  * @brief Define type for the condition of POSMATCH pulses.
258  */
259 typedef enum _eqdc_output_pulse_mode
260 {
261     kEQDC_OutputPulseOnCounterEqualCompare = 0U, /*!< POSMATCH pulses when a match occurs between the position counters
262                                                     (POS) and the compare value (UCOMPx/LCOMPx)(x range is 0-3). */
263     kEQDC_OutputPulseOnReadingPositionCounter,   /*!< POSMATCH pulses when reading position counter(POS and LPOS),
264                                                     revolution   counter(REV), position difference counter(POSD). */
265 } eqdc_output_pulse_mode_t;
266 
267 /*!
268  * @brief Define type for determining how the revolution counter (REV) is incremented/decremented.
269  */
270 typedef enum _eqdc_revolution_count_condition
271 {
272     kEQDC_RevolutionCountOnIndexPulse = 0U, /*!< Use INDEX pulse to increment/decrement revolution counter. */
273     kEQDC_RevolutionCountOnRollOverModulus, /*!< Use modulus counting roll-over/under to increment/decrement revolution
274                                               counter. */
275 } eqdc_revolution_count_condition_t;
276 
277 /*!
278  * @brief Input Filter Sample Count
279  *
280  * The Input Filter Sample Count represents the number of consecutive samples
281  * that must agree, before the input filter accepts an input transition
282  */
283 typedef enum _eqdc_filter_sample_count
284 {
285     kEQDC_Filter3Samples  = 0U, /*!< 3  samples. */
286     kEQDC_Filter4Samples  = 1U, /*!< 4  samples. */
287     kEQDC_Filter5Samples  = 2U, /*!< 5  samples. */
288     kEQDC_Filter6Samples  = 3U, /*!< 6  samples. */
289     kEQDC_Filter7Samples  = 4U, /*!< 7  samples. */
290     kEQDC_Filter8Samples  = 5U, /*!< 8  samples. */
291     kEQDC_Filter9Samples  = 6U, /*!< 9  samples. */
292     kEQDC_Filter10Samples = 7U, /*!< 10 samples. */
293 } eqdc_filter_sample_count_t;
294 
295 /*!
296  * @brief Count direction.
297  */
298 typedef enum _eqdc_count_direction_flag
299 {
300     kEQDC_CountDirectionDown = 0U, /*!< Last count was in down direction. */
301     kEQDC_CountDirectionUp,        /*!< Last count was in up direction. */
302 } eqdc_count_direction_flag_t;
303 
304 /*!
305  * @brief Prescaler used by Last Edge Time (LASTEDGE) and
306  * Position Difference Period Counter (POSDPER).
307  */
308 typedef enum _eqdc_prescaler
309 {
310     kEQDC_Prescaler1     = 0U,  /*!< Prescaler value 1. */
311     kEQDC_Prescaler2     = 1U,  /*!< Prescaler value 2. */
312     kEQDC_Prescaler4     = 2U,  /*!< Prescaler value 4. */
313     kEQDC_Prescaler8     = 3U,  /*!< Prescaler value 8. */
314     kEQDC_Prescaler16    = 4U,  /*!< Prescaler value 16. */
315     kEQDC_Prescaler32    = 5U,  /*!< Prescaler value 32. */
316     kEQDC_Prescaler64    = 6U,  /*!< Prescaler value 64. */
317     kEQDC_Prescaler128   = 7U,  /*!< Prescaler value 128. */
318     kEQDC_Prescaler256   = 8U,  /*!< Prescaler value 256. */
319     kEQDC_Prescaler512   = 9U,  /*!< Prescaler value 512. */
320     kEQDC_Prescaler1024  = 10U, /*!< Prescaler value 1024. */
321     kEQDC_Prescaler2048  = 11U, /*!< Prescaler value 2048. */
322     kEQDC_Prescaler4096  = 12U, /*!< Prescaler value 4096. */
323     kEQDC_Prescaler8192  = 13U, /*!< Prescaler value 8192. */
324     kEQDC_Prescaler16384 = 14U, /*!< Prescaler value 16384. */
325     kEQDC_Prescaler32768 = 15U, /*!< Prescaler value 32768. */
326 } eqdc_prescaler_t;
327 
328 /*!
329  * @brief Define user configuration structure for EQDC module.
330  */
331 typedef struct _eqdc_config
332 {
333     /* Basic counter. */
334     bool enableReverseDirection; /*!< Enable reverse direction counting. */
335     bool countOnce;              /*!< Selects modulo loop or one shot counting mode.  */
336 
337     bool enableDma;                /*!< Enable DMA for new written buffer values of COMPx/INIT/MOD(x range is 0-3) */
338     bool bufferedRegisterLoadMode; /*!<selects the loading time point of the buffered compare registers UCOMPx/LCOMPx,
339                                        x=0~3, initial register (UINIT/LINIT), and modulus register (UMOD/LMOD). */
340 
341     bool enableTriggerInitPositionCounter;    /*!< Initialize position counter with initial register(UINIT, LINIT) value
342                                                on TRIGGER's rising edge. */
343 
344 #if (defined(FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD) && FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD)
345  /*!
346  * Enables the feature that the position counter to be initialized by Index Event Edge Mark.
347  *
348  * This option works together with @ref _eqdc_index_preset_init_pos_counter_mode and @ref enableReverseDirection;
349  * If enabled, the behavior is like this:
350  *
351  * When PHA leads PHB (Clockwise):
352  *   If @ref _eqdc_index_preset_init_pos_counter_mode is @ref kEQDC_IndexInitPosCounterOnRisingEdge,
353  *   then INDEX rising edge reset position counter.
354  *   If @ref _eqdc_index_preset_init_pos_counter_mode is @ref kEQDC_IndexInitPosCounterOnFallingEdge,
355  *   then INDEX falling edge reset position counter.
356  *   If @ref enableReverseDirection is false, then Reset position counter to initial value.
357  *   If @ref enableReverseDirection is true, then reset position counter to modulus value.
358  *
359  * When PHA lags PHB (Counter Clockwise):
360  *   If @ref _eqdc_index_preset_init_pos_counter_mode is @ref kEQDC_IndexInitPosCounterOnRisingEdge,
361  *   then INDEX falling edge reset position counter.
362  *   If @ref _eqdc_index_preset_init_pos_counter_mode is @ref kEQDC_IndexInitPosCounterOnFallingEdge,
363  *   then INDEX rising edge reset position counter.
364  *   If @ref enableReverseDirection is false, then Reset position counter to modulus value.
365  *   If @ref enableReverseDirection is true, then reset position counter to initial value.
366  */
367     bool enableIndexInitPositionCounter;
368 #endif /* FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD */
369 
370     bool enableTriggerClearPositionRegisters; /*!< Clear position counter(POS), revolution counter(REV), position
371                                                 difference counter (POSD) on TRIGGER's rising edge. */
372     bool enableTriggerHoldPositionRegisters;  /*!< Load position counter(POS), revolution counter(REV), position
373                                                 difference counter (POSD) values to hold registers  on TRIGGER's rising
374                                                 edge. */
375 
376     bool filterPhaseA; /*!< Filter operation on PHASEA input, when write 1, it means filter for PHASEA input is
377                            bypassed. */
378     bool filterPhaseB; /*!< Filter operation on PHASEB input, when write 1, it means filter for PHASEB input is
379                            bypassed. */
380     bool filterIndPre; /*!< Filter operation on INDEX/PRESET input, when write 1, it means filter for INDEX/PRESET
381                            input is bypassed. */
382     bool filterHomEna; /*!< Filter operation on HOME/ENABLE input, when write 1, it means filter for  HOME/ENABLE input
383                            is bypassed. */
384 
385     /* Watchdog. */
386     bool enableWatchdog;           /*!< Enable the watchdog to detect if the target is moving or not. */
387     uint16_t watchdogTimeoutValue; /*!< Watchdog timeout count value. It stores the timeout count for the quadrature
388                                         decoder module watchdog timer. */
389 
390     /* Filter for input signals: PHASEA, PHASEB, INDEX and HOME. */
391     eqdc_prescaler_t prescaler;                   /*!< Prescaler. */
392     bool filterClockSourceselection;              /*!< Filter Clock Source selection. */
393     eqdc_filter_sample_count_t filterSampleCount; /*!< Input Filter Sample Count. This value should be chosen to reduce
394                                the probability of noisy samples causing an incorrect transition to be recognized. The
395                                value represent the number of consecutive samples that must agree prior to the input
396                                filter accepting an input transition. */
397     uint8_t filterSamplePeriod; /*!< Input Filter Sample Period. This value should be set such that the sampling
398                                      period is larger than the period of the expected noise. This value represents the
399                                       sampling period (in IPBus clock cycles) of the decoder input signals.
400                                       The available range is 0 - 255. */
401 
402     /* Operate mode. */
403     eqdc_operate_mode_t operateMode; /*!< Selects operation mode. */
404     eqdc_count_mode_t countMode;     /*!< Selects count mode. */
405 
406     /* Signal detection. */
407     eqdc_home_enable_init_pos_counter_mode_t homeEnableInitPosCounterMode;   /*!< Select how HOME/Enable signal used to
408                                                                   initialize position counters. */
409     eqdc_index_preset_init_pos_counter_mode_t indexPresetInitPosCounterMode; /*!< Select how INDEX/Preset signal used
410                                                                   to initialize position counters. */
411 
412     /* Position compare. */
413     eqdc_output_pulse_mode_t outputPulseMode; /*!< The condition of POSMATCH pulses. */
414     uint32_t positionCompareValue[4]; /*!< Position compare 0 ~ 3 value. The available value is a 32-bit number.*/
415 
416     /* Modulus counting. */
417     eqdc_revolution_count_condition_t revolutionCountCondition; /*!< Revolution Counter Modulus Enable. */
418     uint32_t positionModulusValue; /*!< Position modulus value. The available value is a 32-bit number. */
419     uint32_t positionInitialValue; /*!< Position initial value. The available value is a 32-bit number. */
420     uint32_t positionCounterValue; /*!< Position counter value. When Modulo mode enabled, the positionCounterValue
421                                            should be in the range of @ref positionInitialValue and
422                                            @ref positionModulusValue. */
423 
424     /* Period measurement. */
425     bool enablePeriodMeasurement; /*!< Enable period measurement. When enabled, the position difference hold register
426                                       (POSDH) is only updated when position difference register (POSD) is read. */
427 
428     /* Interrupts. */
429     uint16_t enabledInterruptsMask; /*!< Mask of interrupts to be enabled, should be OR'ed value of @ref
430                                           _eqdc_interrupt_enable. */
431 } eqdc_config_t;
432 
433 #if defined(__cplusplus)
434 extern "C" {
435 #endif
436 
437 /*******************************************************************************
438  * API
439  ******************************************************************************/
440 
441 /*!
442  * @name Initialization and deinitialization Interfaces
443  * @{
444  */
445 
446 /*!
447  * @brief Initializes the EQDC module.
448  *
449  * This function initializes the EQDC by enabling the IP bus clock (optional).
450  *
451  * @param base   EQDC peripheral base address.
452  * @param psConfig Pointer to configuration structure.
453  */
454 void EQDC_Init(EQDC_Type *base, const eqdc_config_t *psConfig);
455 
456 /*!
457  * @brief Gets an available pre-defined configuration.
458  *
459  * The default value are:
460  * @code
461     psConfig->enableReverseDirection              = false;
462     psConfig->countOnce                           = false;
463     psConfig->operateMode                         = kEQDC_QuadratureDecodeOperationMode;
464     psConfig->countMode                           = kEQDC_QuadratureX4;
465     psConfig->homeEnableInitPosCounterMode        = kEQDC_HomeInitPosCounterDisabled;
466     psConfig->indexPresetInitPosCounterMode       = kEQDC_IndexInitPosCounterDisabled;
467     psConfig->enableIndexInitPositionCounter      = false;
468     psConfig->enableDma                           = false;
469     psConfig->bufferedRegisterLoadMode            = false;
470     psConfig->enableTriggerInitPositionCounter    = false;
471     psConfig->enableTriggerClearPositionRegisters = false;
472     psConfig->enableTriggerHoldPositionRegisters  = false;
473     psConfig->enableWatchdog                      = false;
474     psConfig->watchdogTimeoutValue                = 0xFFFFU;
475     psConfig->filterPhaseA                        = 0U;
476     psConfig->filterPhaseB                        = 0U;
477     psConfig->filterIndPre                        = 0U;
478     psConfig->filterHomEna                        = 0U;
479     psConfig->filterClockSourceselection          = false;
480     psConfig->filterSampleCount                   = kEQDC_Filter3Samples;
481     psConfig->filterSamplePeriod                  = 0U;
482     psConfig->outputPulseMode                     = kEQDC_OutputPulseOnCounterEqualCompare;
483     psConfig->positionCompareValue[0]  	          = 0xFFFFFFFFU;
484     psConfig->positionCompareValue[1]             = 0xFFFFFFFFU;
485     psConfig->positionCompareValue[2]             = 0xFFFFFFFFU;
486     psConfig->positionCompareValue[3]             = 0xFFFFFFFFU;
487     psConfig->revolutionCountCondition            = kEQDC_RevolutionCountOnIndexPulse;
488     psConfig->positionModulusValue                = 0U;
489     psConfig->positionInitialValue                = 0U;
490     psConfig->positionCounterValue                = 0U;
491     psConfig->enablePeriodMeasurement             = false;
492     psConfig->prescaler                           = kEQDC_Prescaler1;
493     psConfig->enabledInterruptsMask               = 0U;
494    @endcode
495  *
496  * @param psConfig Pointer to configuration structure.
497  */
498 void EQDC_GetDefaultConfig(eqdc_config_t *psConfig);
499 
500 /*!
501  * @brief De-initializes the EQDC module.
502  *
503  * This function deinitializes the EQDC by disabling the IP bus clock (optional).
504  *
505  * @param base EQDC peripheral base address.
506  */
507 void EQDC_Deinit(EQDC_Type *base);
508 
509 /*!
510  * @brief Initializes the mode of operation.
511  *
512  * This function initializes mode of operation by enabling the IP bus clock (optional).
513  *
514  * @param base   EQDC peripheral base address.
515  * @param operateMode Select operation mode.
516  */
517 void EQDC_SetOperateMode(EQDC_Type *base, eqdc_operate_mode_t operateMode);
518 
519 /*!
520  * @brief Initializes the mode of count.
521  *
522  * These bits control the basic counting and behavior of Position Counter and Position Difference Counter.
523  * Setting CTRL[REV] to 1 can reverse the counting direction.
524  * 1.In quadrature Mode (CTRL[PH1] = 0):
525  *    00b - CM0: Normal/Reverse Quadrature X4
526  *    01b - CM1: Normal/Reverse Quadrature X2
527  *    10b - CM2: Normal/Reverse Quadrature X1
528  *    11b - CM3: Reserved
529  * 2.In Single Phase Mode (CTRL[PH1] = 1):
530  *    00b - CM0: UP/DOWN Pulse Count Mode
531  *    01b - CM1: Signed Mode, count PHASEA rising/falling edge, position counter counts up when PHASEB
532  *    is low and counts down when PHASEB is high
533  *    10b - CM2: Signed Count Mode,count PHASEA rising edge only, position counter counts up when
534  *    PHASEB is low and counts down when PHASEB is high
535  *    11b - CM3: Reserved
536  *
537  * @param base   EQDC peripheral base address.
538  * @param countMode Select count mode.
539  */
EQDC_SetCountMode(EQDC_Type * base,eqdc_count_mode_t countMode)540 static inline void EQDC_SetCountMode(EQDC_Type *base, eqdc_count_mode_t countMode)
541 {
542     base->CTRL2 = (base->CTRL2 & (uint16_t)(~EQDC_CTRL2_CMODE_MASK)) | EQDC_CTRL2_CMODE(countMode);
543 }
544 
545 /*! @} */
546 
547 /*!
548  * @name Watchdog
549  * @{
550  */
551 
552 /*!
553  * @brief Enable watchdog for EQDC module.
554  *
555  * @param base EQDC peripheral base address
556  * @param bEnable Enables or disables the watchdog
557  */
EQDC_EnableWatchdog(EQDC_Type * base,bool bEnable)558 static inline void EQDC_EnableWatchdog(EQDC_Type *base, bool bEnable)
559 {
560     if (bEnable)
561     {
562         base->CTRL = (base->CTRL & (~EQDC_CTRL_W1C_FLAGS)) | EQDC_CTRL_WDE_MASK;
563     }
564     else
565     {
566         base->CTRL = (base->CTRL & (~(EQDC_CTRL_W1C_FLAGS | EQDC_CTRL_WDE_MASK)));
567     }
568 }
569 
570 /*!
571  * @brief Set watchdog timeout value.
572  *
573  * @param base EQDC peripheral base address
574  * @param u16Timeout Number of clock cycles, plus one clock cycle that the
575  * watchdog timer counts before timing out
576  */
EQDC_SetWatchdogTimeout(EQDC_Type * base,uint16_t u16Timeout)577 static inline void EQDC_SetWatchdogTimeout(EQDC_Type *base, uint16_t u16Timeout)
578 {
579     base->WTR = u16Timeout;
580 }
581 
582 /*! @} */
583 
584 /*!
585  * @name DMA
586  * @{
587  */
588 
589 /*!
590  * @brief Enable DMA for EQDC module.
591  *
592  * @param base EQDC peripheral base address
593  * @param bEnable Enables or disables the DMA
594  */
EQDC_EnableDMA(EQDC_Type * base,bool bEnable)595 static inline void EQDC_EnableDMA(EQDC_Type *base, bool bEnable)
596 {
597     if (bEnable)
598     {
599         base->CTRL |= EQDC_CTRL_DMAEN_MASK;
600     }
601     else
602     {
603 #if (defined(FSL_FEATURE_EQDC_HAS_ERRATA_051383) && FSL_FEATURE_EQDC_HAS_ERRATA_051383)
604         /* Quadrature decoder CTRL[DMAEN] bit can not be cleared except do EQDC reset*/
605         assert(false);
606 #else
607         base->CTRL &= ~EQDC_CTRL_DMAEN_MASK;
608 #endif
609     }
610 }
611 
612 /*! @} */
613 
614 /*!
615  * @name Double-set Registers Loading Operation
616  * @{
617  */
618 
619 /*!
620  * @brief Set Buffered Register Load (Update) Mode.
621  *
622  * This bit selects the loading time point of the buffered compare registers UCOMPx/LCOMPx, x=0~3,
623  * initial register (UINIT/LINIT), and modulus register (UMOD/LMOD).
624  * Buffered registers are loaded and take effect at the next roll-over or roll-under if CTRL[LDOK] is set.
625  *
626  * @param base EQDC peripheral base address
627  */
EQDC_SetBufferedRegisterLoadUpdateMode(EQDC_Type * base)628 static inline void EQDC_SetBufferedRegisterLoadUpdateMode(EQDC_Type *base)
629 {
630     base->CTRL2 |= EQDC_CTRL2_LDMOD_MASK;
631 }
632 
633 /*!
634  * @brief Clear Buffered Register Load (Update) Mode.
635  *
636  * Buffered Register Load (Update) Mode bit selects the loading time point of the buffered compare registers
637  * UCOMPx/LCOMPx, x=0~3, initial register (UINIT/LINIT), and modulus register (UMOD/LMOD). Buffered registers are loaded
638  * and take effect immediately upon CTRL[LDOK] is set.
639  *
640  * @param base EQDC peripheral base address
641  */
EQDC_ClearBufferedRegisterLoadUpdateMode(EQDC_Type * base)642 static inline void EQDC_ClearBufferedRegisterLoadUpdateMode(EQDC_Type *base)
643 {
644     base->CTRL2 &= ~EQDC_CTRL2_LDMOD_MASK;
645 }
646 
647 /*!
648  * @brief Set load okay.
649  *
650  * Load okay enables that the outer-set values of buffered compare registers (UCOMPx/LCOMPx, x=0~3),
651  * initial register(UINIT/LINIT) and modulus register(UMOD/LMOD) can be loaded into their inner-sets and
652  * take effect.
653  * When LDOK is set, this loading action occurs at the next position counter roll-over or roll-under if
654  * CTRL2[LDMOD] is set, or it occurs immediately if CTRL2[LDMOD] is cleared. LDOK is automatically
655  * cleared after the values in outer-set is loaded into the inner-set.
656  *
657  * @param base EQDC peripheral base address.
658  */
EQDC_SetEqdcLdok(EQDC_Type * base)659 static inline void EQDC_SetEqdcLdok(EQDC_Type *base)
660 {
661     base->CTRL |= EQDC_CTRL_LDOK_MASK;
662 }
663 
664 /*!
665  * @brief Get load okay.
666  *
667  * @param base EQDC peripheral base address.
668  */
EQDC_GetEqdcLdok(EQDC_Type * base)669 static inline uint8_t EQDC_GetEqdcLdok(EQDC_Type *base)
670 {
671     return base->CTRL & EQDC_CTRL_LDOK_MASK;
672 }
673 
674 /*!
675  * @brief Clear load okay.
676  *
677  * @param base EQDC peripheral base address.
678  */
EQDC_ClearEqdcLdok(EQDC_Type * base)679 static inline void EQDC_ClearEqdcLdok(EQDC_Type *base)
680 {
681     base->CTRL &= ~EQDC_CTRL_LDOK_MASK;
682 }
683 
684 /*! @} */
685 
686 /*!
687  * @name Status
688  * @{
689  */
690 /*!
691  * @brief  Get the status flags.
692  *
693  * @param  base EQDC peripheral base address.
694  *
695  * @return  Logical OR'ed value of the status flags, @ref _eqdc_status_flags.
696  */
EQDC_GetStatusFlags(EQDC_Type * base)697 static inline uint32_t EQDC_GetStatusFlags(EQDC_Type *base)
698 {
699     uint32_t u32Flags = 0U;
700 
701     u32Flags = (uint32_t)(base->CTRL) & EQDC_CTRL_INT_FLAGS;
702 
703     u32Flags |= ((uint32_t)(base->INTCTRL) & EQDC_INTCTRL_INT_FLAGS) << 16;
704     return u32Flags;
705 }
706 
707 /*!
708  * @brief Clear the status flags.
709  *
710  * @param base EQDC peripheral base address.
711  * @param u32Flags Logical OR'ed value of the flags to clear, @ref _eqdc_status_flags.
712  */
EQDC_ClearStatusFlags(EQDC_Type * base,uint32_t u32Flags)713 static inline void EQDC_ClearStatusFlags(EQDC_Type *base, uint32_t u32Flags)
714 {
715     if (0U != (u32Flags & EQDC_CTRL_INT_FLAGS))
716     {
717         base->CTRL = (base->CTRL & (~EQDC_CTRL_W1C_FLAGS)) | (u32Flags & EQDC_CTRL_INT_FLAGS);
718     }
719 
720     if (0U != ((u32Flags >> 16) & EQDC_INTCTRL_INT_FLAGS))
721     {
722         base->INTCTRL = (base->INTCTRL & (~EQDC_INTCTRL_W1C_FLAGS)) | ((u32Flags >> 16) & EQDC_INTCTRL_INT_FLAGS);
723     }
724 }
725 
726 /*!
727  * @brief  Get the signals' real-time status.
728  *
729  * @param  base EQDC peripheral base address.
730  * @return Logical OR'ed value of the real-time signal status, @ref _eqdc_signal_status.
731  */
EQDC_GetSignalStatusFlags(EQDC_Type * base)732 static inline uint16_t EQDC_GetSignalStatusFlags(EQDC_Type *base)
733 {
734     return base->IMR;
735 }
736 
737 /*!
738  * @brief Get the direction of the last count.
739  *
740  * @param  base EQDC peripheral base address.
741  * @return Direction of the last count.
742  */
EQDC_GetLastCountDirection(EQDC_Type * base)743 static inline eqdc_count_direction_flag_t EQDC_GetLastCountDirection(EQDC_Type *base)
744 {
745     return ((0U != (base->IMR & EQDC_IMR_DIR_MASK)) ? kEQDC_CountDirectionUp : kEQDC_CountDirectionDown);
746 }
747 /*! @} */
748 
749 /*!
750  * @name Interrupts
751  * @{
752  */
753 
754 /*!
755  * @brief Enable the interrupts.
756  *
757  * @param base EQDC peripheral base address.
758  * @param u32Interrupts Logical OR'ed value of the interrupts, @ref _eqdc_interrupt_enable.
759  */
EQDC_EnableInterrupts(EQDC_Type * base,uint32_t u32Interrupts)760 static inline void EQDC_EnableInterrupts(EQDC_Type *base, uint32_t u32Interrupts)
761 {
762     if (0U != (u32Interrupts & EQDC_CTRL_INT_EN))
763     {
764         base->CTRL = (base->CTRL & (~EQDC_CTRL_W1C_FLAGS)) | (u32Interrupts & EQDC_CTRL_INT_EN);
765     }
766 
767     if (0U != ((u32Interrupts >> 16) & EQDC_INTCTRL_INT_EN))
768     {
769         base->INTCTRL = (base->INTCTRL & (~EQDC_INTCTRL_W1C_FLAGS)) | ((u32Interrupts >> 16) & EQDC_INTCTRL_INT_EN);
770     }
771 }
772 
773 /*!
774  * @brief Disable the interrupts.
775  *
776  * @param base EQDC peripheral base address.
777  * @param u32Interrupts Logical OR'ed value of the interrupts, @ref _eqdc_interrupt_enable.
778  */
EQDC_DisableInterrupts(EQDC_Type * base,uint32_t u32Interrupts)779 static inline void EQDC_DisableInterrupts(EQDC_Type *base, uint32_t u32Interrupts)
780 {
781     if (0U != (u32Interrupts & EQDC_CTRL_INT_EN))
782     {
783         base->CTRL = (base->CTRL & (~EQDC_CTRL_W1C_FLAGS)) & (~(u32Interrupts & EQDC_CTRL_INT_EN));
784     }
785 
786     if (0U != ((u32Interrupts >> 16) & EQDC_INTCTRL_INT_EN))
787     {
788         base->INTCTRL = (base->INTCTRL & (~EQDC_INTCTRL_W1C_FLAGS)) & (~((u32Interrupts >> 16) & EQDC_INTCTRL_INT_EN));
789     }
790 }
791 
792 /*! @} */
793 
794 /*!
795  * @name Counter Operation
796  * @{
797  */
798 
799 /*!
800  * @brief Load the initial position value to position counter.
801  *
802  * Software trigger to load the initial position value (UINIT and LINIT) contents
803  * to position counter (UPOS and LPOS), so that to provide the consistent
804  * operation the position counter registers.
805  *
806  * @param base EQDC peripheral base address.
807  */
EQDC_DoSoftwareLoadInitialPositionValue(EQDC_Type * base)808 static inline void EQDC_DoSoftwareLoadInitialPositionValue(EQDC_Type *base)
809 {
810     base->CTRL = (base->CTRL & (~EQDC_CTRL_W1C_FLAGS)) | EQDC_CTRL_SWIP_MASK;
811 }
812 
813 /*!
814  * @brief Set initial position value for EQDC module.
815  *
816  * Set the position counter initial value (UINIT, LINIT).
817  * After writing values to the UINIT and LINIT registers, the values are "buffered" into outer-set
818  * registers temporarily. Values will be loaded into inner-set registers and take effect using
819  * the following two methods:
820  * 1. If CTRL2[LDMODE] is 1, "buffered" values are loaded into inner-set and take effect
821  * at the next roll-over or roll-under if CTRL[LDOK] is set.
822  * 2. If CTRL2[LDMODE] is 0, "buffered" values are loaded into inner-set and take effect
823  * immediately when CTRL[LDOK] is set.
824  *
825  * @param base EQDC peripheral base address
826  * @param u32PositionInitValue Position initial value
827  */
EQDC_SetInitialPositionValue(EQDC_Type * base,uint32_t u32PositionInitValue)828 static inline void EQDC_SetInitialPositionValue(EQDC_Type *base, uint32_t u32PositionInitValue)
829 {
830     base->UINIT = (uint16_t)(u32PositionInitValue >> 16U);
831     base->LINIT = (uint16_t)(u32PositionInitValue);
832 }
833 
834 /*!
835  * @brief Set position counter value.
836  *
837  * Set the position counter value (POS or UPOS, LPOS).
838  *
839  * @param base EQDC peripheral base address
840  * @param positionCounterValue Position counter value
841  */
EQDC_SetPositionCounterValue(EQDC_Type * base,uint32_t positionCounterValue)842 static inline void EQDC_SetPositionCounterValue(EQDC_Type *base, uint32_t positionCounterValue)
843 {
844     base->UPOS = (uint16_t)(positionCounterValue >> 16U);
845     base->LPOS = (uint16_t)(positionCounterValue);
846 }
847 
848 /*!
849  * @brief Set position counter modulus value.
850  *
851  * Set the position counter modulus value (UMOD, LMOD).
852  * After writing values to the UMOD and LMOD registers, the values are "buffered" into outer-set
853  * registers temporarily. Values will be loaded into inner-set registers and take effect using
854  * the following two methods:
855  * 1. If CTRL2[LDMODE] is 1, "buffered" values are loaded into inner-set and take effect
856  * at the next roll-over or roll-under if CTRL[LDOK] is set.
857  * 2. If CTRL2[LDMODE] is 0, "buffered" values are loaded into inner-set and take effect
858  * immediately when CTRL[LDOK] is set.
859  *
860  * @param base EQDC peripheral base address
861  * @param positionModulusValue Position modulus value
862  */
EQDC_SetPositionModulusValue(EQDC_Type * base,uint32_t positionModulusValue)863 static inline void EQDC_SetPositionModulusValue(EQDC_Type *base, uint32_t positionModulusValue)
864 {
865     base->UMOD = (uint16_t)(positionModulusValue >> 16U);
866     base->LMOD = (uint16_t)(positionModulusValue);
867 }
868 
869 /*!
870  * @brief Set position counter compare 0 value.
871  *
872  * Set the position counter compare 0 value (UCOMP0, LCOMP0).
873  * After writing values to the UCOMP0 and LCOMP0 registers, the values are "buffered" into outer-set
874  * registers temporarily. Values will be loaded into inner-set registers and take effect using
875  * the following two methods:
876  * 1. If CTRL2[LDMODE] is 1, "buffered" values are loaded into inner-set and take effect
877  * at the next roll-over or roll-under if CTRL[LDOK] is set.
878  * 2. If CTRL2[LDMODE] is 0, "buffered" values are loaded into inner-set and take effect
879  * immediately when CTRL[LDOK] is set.
880  *
881  * @param base EQDC peripheral base address
882  * @param u32PositionComp0Value Position modulus value
883  */
EQDC_SetPositionCompare0Value(EQDC_Type * base,uint32_t u32PositionComp0Value)884 static inline void EQDC_SetPositionCompare0Value(EQDC_Type *base, uint32_t u32PositionComp0Value)
885 {
886     base->UCOMP0 = (uint16_t)(u32PositionComp0Value >> 16U);
887     base->LCOMP0 = (uint16_t)(u32PositionComp0Value);
888 }
889 
890 /*!
891  * @brief Set position counter compare 1 value.
892  *
893  * Set the position counter compare 1 value (UCOMP1, LCOMP1).
894  * After writing values to the UCOMP1 and LCOMP1 registers, the values are "buffered" into outer-set
895  * registers temporarily. Values will be loaded into inner-set registers and take effect using
896  * the following two methods:
897  * 1. If CTRL2[LDMODE] is 1, "buffered" values are loaded into inner-set and take effect
898  * at the next roll-over or roll-under if CTRL[LDOK] is set.
899  * 2. If CTRL2[LDMODE] is 0, "buffered" values are loaded into inner-set and take effect
900  * immediately when CTRL[LDOK] is set.
901  *
902  * @param base EQDC peripheral base address
903  * @param u32PositionComp1Value Position modulus value
904  */
EQDC_SetPositionCompare1Value(EQDC_Type * base,uint32_t u32PositionComp1Value)905 static inline void EQDC_SetPositionCompare1Value(EQDC_Type *base, uint32_t u32PositionComp1Value)
906 {
907     base->UCOMP1 = (uint16_t)(u32PositionComp1Value >> 16U);
908     base->LCOMP1 = (uint16_t)(u32PositionComp1Value);
909 }
910 
911 /*!
912  * @brief Set position counter compare 2 value.
913  *
914  * Set the position counter compare 2 value (UCOMP2, LCOMP2).
915  * After writing values to the UCOMP2 and LCOMP2 registers, the values are "buffered" into outer-set
916  * registers temporarily. Values will be loaded into inner-set registers and take effect using
917  * the following two methods:
918  * 1. If CTRL2[LDMODE] is 1, "buffered" values are loaded into inner-set and take effect
919  * at the next roll-over or roll-under if CTRL[LDOK] is set.
920  * 2. If CTRL2[LDMODE] is 0, "buffered" values are loaded into inner-set and take effect
921  * immediately when CTRL[LDOK] is set.
922  *
923  * @param base EQDC peripheral base address
924  * @param u32PositionComp2Value Position modulus value
925  */
EQDC_SetPositionCompare2Value(EQDC_Type * base,uint32_t u32PositionComp2Value)926 static inline void EQDC_SetPositionCompare2Value(EQDC_Type *base, uint32_t u32PositionComp2Value)
927 {
928     base->UCOMP2 = (uint16_t)(u32PositionComp2Value >> 16U);
929     base->LCOMP2 = (uint16_t)(u32PositionComp2Value);
930 }
931 
932 /*!
933  * @brief Set position counter compare 3 value.
934  *
935  * Set the position counter compare 3 value (UCOMP3, LCOMP3).
936  * After writing values to the UCOMP3 and LCOMP3 registers, the values are "buffered" into outer-set
937  * registers temporarily. Values will be loaded into inner-set registers and take effect using
938  * the following two methods:
939  * 1. If CTRL2[LDMODE] is 1, "buffered" values are loaded into inner-set and take effect
940  * at the next roll-over or roll-under if CTRL[LDOK] is set.
941  * 2. If CTRL2[LDMODE] is 0, "buffered" values are loaded into inner-set and take effect
942  * immediately when CTRL[LDOK] is set.
943  *
944  * @param base EQDC peripheral base address
945  * @param u32PositionComp3Value Position modulus value
946  */
EQDC_SetPositionCompare3Value(EQDC_Type * base,uint32_t u32PositionComp3Value)947 static inline void EQDC_SetPositionCompare3Value(EQDC_Type *base, uint32_t u32PositionComp3Value)
948 {
949     base->UCOMP3 = (uint16_t)(u32PositionComp3Value >> 16U);
950     base->LCOMP3 = (uint16_t)(u32PositionComp3Value);
951 }
952 
953 /*!
954  * @brief  Get the current position counter's value.
955  *
956  * @param  base EQDC peripheral base address.
957  *
958  * @return Current position counter's value.
959  */
EQDC_GetPosition(EQDC_Type * base)960 static inline uint32_t EQDC_GetPosition(EQDC_Type *base)
961 {
962     uint32_t u32Pos;
963 
964     u32Pos = base->UPOS; /* Get upper 16 bits and make a snapshot. */
965     u32Pos <<= 16U;
966     u32Pos |= base->LPOSH; /* Get lower 16 bits from hold register. */
967 
968     return u32Pos;
969 }
970 
971 /*!
972  * @brief  Get the hold position counter's value.
973  *
974  * The position counter (POS or UPOS, LPOS) value is loaded to hold position (POSH or UPOSH, LPOSH)
975  * when:
976  *   1. Position register (POS or UPOS, LPOS), or position difference register (POSD),
977  *   or revolution register (REV) is read.
978  *   2. TRIGGER happens and TRIGGER is enabled to update the hold registers.
979  *
980  * @param  base EQDC peripheral base address.
981  * @return Hold position counter's value.
982  */
EQDC_GetHoldPosition(EQDC_Type * base)983 static inline uint32_t EQDC_GetHoldPosition(EQDC_Type *base)
984 {
985     uint32_t u32Pos;
986 
987     u32Pos = base->UPOSH; /* Get upper 16 bits from hold register. */
988     u32Pos <<= 16U;
989     u32Pos |= base->LPOSH; /* Get lower 16 bits from hold register. */
990 
991     return u32Pos;
992 }
993 
994 /*!
995  * @brief  Get the hold position counter1's value.
996  *
997  * The Upper Position Counter Hold Register 1(UPOSH1) shares the same address with UCOMP1.
998  * When read, this register means the value of UPOSH1, which is the upper 16 bits of POSH1.
999  * The Lower Position Counter Hold Register 1(LPOSH1) shares the same address with LCOMP1.
1000  * When read, this register means the value of LPOSH1, which is the lower 16 bits of POSH1.
1001  * Position counter is captured into POSH1 on the rising edge of ICAP[1].
1002  *
1003  * @param  base EQDC peripheral base address.
1004  * @return  Hold position counter1's value.
1005  */
EQDC_GetHoldPosition1(EQDC_Type * base)1006 static inline uint32_t EQDC_GetHoldPosition1(EQDC_Type *base)
1007 {
1008     uint32_t u32Pos;
1009 
1010     u32Pos = base->UPOSH1; /* Get upper 16 bits from hold register. */
1011     u32Pos <<= 16U;
1012     u32Pos |= base->LPOSH1; /* Get lower 16 bits from hold register. */
1013 
1014     return u32Pos;
1015 }
1016 
1017 /*!
1018  * @brief  Get the hold position counter2's value.
1019  *
1020  * The Upper Position Counter Hold Register 2(UPOSH2) shares the same address with UCOMP2.
1021  * When read,this register means the value of UPOSH2, which is the upper 16 bits of POSH2.
1022  * The Lower Position Counter Hold Register 2(LPOSH2) shares the same address with LCOMP2.
1023  * When read, this register means the value of LPOSH2, which is the lower 16 bits of POSH2.
1024  * Position counter is captured into POSH2 on the rising edge of ICAP[2].
1025  *
1026  * @param  base EQDC peripheral base address.
1027  * @return  Hold position counter2's value.
1028  */
EQDC_GetHoldPosition2(EQDC_Type * base)1029 static inline uint32_t EQDC_GetHoldPosition2(EQDC_Type *base)
1030 {
1031     uint32_t u32Pos;
1032 
1033     u32Pos = base->UPOSH2; /* Get upper 16 bits from hold register. */
1034     u32Pos <<= 16U;
1035     u32Pos |= base->LPOSH2; /* Get lower 16 bits from hold register. */
1036 
1037     return u32Pos;
1038 }
1039 
1040 /*!
1041  * @brief  Get the hold position counter3's value.
1042  *
1043  * The Upper Position Counter Hold Register 3(UPOSH3) shares the same address with UCOMP3.
1044  * When read,this register means the value of UPOSH3, which is the upper 16 bits of POSH3.
1045  * The Lower Position Counter Hold Register 3(LPOSH3) shares the same address with LCOMP3.
1046  * When read, this register means the value of LPOSH3, which is the lower 16 bits of POSH3.
1047  * Position counter is captured into POSH3 on the rising edge of ICAP[3].
1048  *
1049  * @param  base EQDC peripheral base address.
1050  * @return  Hold position counter3's value.
1051  */
EQDC_GetHoldPosition3(EQDC_Type * base)1052 static inline uint32_t EQDC_GetHoldPosition3(EQDC_Type *base)
1053 {
1054     uint32_t u32Pos;
1055 
1056     u32Pos = base->UPOSH3; /* Get upper 16 bits from hold register. */
1057     u32Pos <<= 16U;
1058     u32Pos |= base->LPOSH3; /* Get lower 16 bits from hold register. */
1059 
1060     return u32Pos;
1061 }
1062 
1063 /*!
1064  * @brief  Get the position difference counter's value.
1065  *
1066  * @param  base EQDC peripheral base address.
1067  * @return The position difference counter's value.
1068  */
EQDC_GetPositionDifference(EQDC_Type * base)1069 static inline uint16_t EQDC_GetPositionDifference(EQDC_Type *base)
1070 {
1071     return base->POSD;
1072 }
1073 
1074 /*!
1075  * @brief  Get the hold position difference counter's value.
1076  *
1077  * The position difference (POSD) value is loaded to hold position difference (POSDH)
1078  * when:
1079  * 1. Position register (POS or UPOS, LPOS), or position difference register (POSD),
1080  * or revolution register (REV) is read. When Period Measurement is enabled (CTRL3[PMEN] = 1),
1081  * POSDH will only be udpated when reading POSD.
1082  * 2. TRIGGER happens and TRIGGER is enabled to update the hold registers.
1083  *
1084  * @param  base EQDC peripheral base address.
1085  * @return  Hold position difference counter's value.
1086  */
EQDC_GetHoldPositionDifference(EQDC_Type * base)1087 static inline uint16_t EQDC_GetHoldPositionDifference(EQDC_Type *base)
1088 {
1089     return base->POSDH;
1090 }
1091 
1092 /*!
1093  * @brief  Get the revolution counter's value.
1094  *
1095  * Get the revolution counter (REV) value.
1096  *
1097  * @param  base EQDC peripheral base address.
1098  * @return  The revolution counter's value.
1099  */
EQDC_GetRevolution(EQDC_Type * base)1100 static inline uint16_t EQDC_GetRevolution(EQDC_Type *base)
1101 {
1102     return base->REV;
1103 }
1104 
1105 /*!
1106  * @brief  Get the hold revolution counter's value.
1107  *
1108  * The revolution counter (REV) value is loaded to hold revolution (REVH)
1109  * when:
1110  * 1. Position register (POS or UPOS, LPOS), or position difference register (POSD),
1111  * or revolution register (REV) is read.
1112  * 2. TRIGGER happens and TRIGGER is enabled to update the hold registers.
1113  *
1114  * @param  base EQDC peripheral base address.
1115  * @return Hold position revolution counter's value.
1116  */
EQDC_GetHoldRevolution(EQDC_Type * base)1117 static inline uint16_t EQDC_GetHoldRevolution(EQDC_Type *base)
1118 {
1119     return base->REVH;
1120 }
1121 
1122 /*!
1123  * @brief  Get the last edge time.
1124  *
1125  * Last edge time (LASTEDGE) is the time since the last edge occurred on PHASEA or PHASEB.
1126  * The last edge time register counts up using the peripheral clock after prescaler.
1127  * Any edge on PHASEA or PHASEB will reset this register to 0 and start counting.
1128  * If the last edge timer count reaches 0xffff, the counting will stop in order to
1129  * prevent an overflow.Counting will continue when an edge occurs on
1130  * PHASEA or PHASEB.
1131  *
1132  * @param  base EQDC peripheral base address.
1133  *
1134  * @return The last edge time.
1135  */
EQDC_GetLastEdgeTime(EQDC_Type * base)1136 static inline uint16_t EQDC_GetLastEdgeTime(EQDC_Type *base)
1137 {
1138     return base->LASTEDGE;
1139 }
1140 
1141 /*!
1142  * @brief  Get the hold last edge time.
1143  *
1144  * The hold of last edge time(LASTEDGEH) is update to last edge time(LASTEDGE)
1145  * when the position difference register register (POSD) is read.
1146  *
1147  * @param  base EQDC peripheral base address.
1148  * @return Hold of last edge time.
1149  */
EQDC_GetHoldLastEdgeTime(EQDC_Type * base)1150 static inline uint16_t EQDC_GetHoldLastEdgeTime(EQDC_Type *base)
1151 {
1152     return base->LASTEDGEH;
1153 }
1154 
1155 /*!
1156  * @brief Get the Position Difference Period counter value
1157  *
1158  * The Position Difference Period counter (POSDPER) counts up using the
1159  * prescaled peripheral clock.  When reading the position difference register(POSD),
1160  * the last edge time (LASTEDGE) will be loaded to position difference period counter(POSDPER).
1161  * If the POSDPER count reaches 0xffff, the counting will stop in order to prevent an
1162  * overflow. Counting will continue when an edge occurs on PHASEA or PHASEB.
1163  *
1164  * @param  base EQDC peripheral base address.
1165  * @return The position difference period counter value.
1166  */
EQDC_GetPositionDifferencePeriod(EQDC_Type * base)1167 static inline uint16_t EQDC_GetPositionDifferencePeriod(EQDC_Type *base)
1168 {
1169     return base->POSDPER;
1170 }
1171 
1172 /*!
1173  * @brief Get buffered Position Difference Period counter value
1174  *
1175  * The Bufferd Position Difference Period (POSDPERBFR) value is updated with
1176  * the position difference period counter(POSDPER) when any edge occurs
1177  * on PHASEA or PHASEB.
1178  *
1179  * @param  base EQDC peripheral base address.
1180  * @return The buffered position difference period counter value.
1181  */
EQDC_GetBufferedPositionDifferencePeriod(EQDC_Type * base)1182 static inline uint16_t EQDC_GetBufferedPositionDifferencePeriod(EQDC_Type *base)
1183 {
1184     return base->POSDPERBFR;
1185 }
1186 
1187 /*!
1188  * @brief Get Hold Position Difference Period counter value
1189  *
1190  * The hold position difference period(POSDPERH) is updated with the value of
1191  * buffered position difference period(POSDPERBFR) when the
1192  * position difference(POSD) register is read.
1193  *
1194  * @param  base EQDC peripheral base address.
1195  * @return The hold position difference period counter value.
1196  */
EQDC_GetHoldPositionDifferencePeriod(EQDC_Type * base)1197 static inline uint16_t EQDC_GetHoldPositionDifferencePeriod(EQDC_Type *base)
1198 {
1199     return base->POSDPERH;
1200 }
1201 
1202 /*! @} */
1203 
1204 #if defined(__cplusplus)
1205 }
1206 #endif
1207 
1208 /*!
1209  * @}
1210  */
1211 #endif /* FSL_EQDC_H_ */
1212