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