1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_ENC_H_
10 #define _FSL_ENC_H_
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup enc
16  * @{
17  */
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 #define FSL_ENC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
22 
23 /*!
24  * @brief Interrupt enable/disable mask.
25  */
26 enum _enc_interrupt_enable
27 {
28     kENC_HOMETransitionInterruptEnable  = (1U << 0U), /*!< HOME interrupt enable. */
29     kENC_INDEXPulseInterruptEnable      = (1U << 1U), /*!< INDEX pulse interrupt enable. */
30     kENC_WatchdogTimeoutInterruptEnable = (1U << 2U), /*!< Watchdog timeout interrupt enable. */
31     kENC_PositionCompareInerruptEnable  = (1U << 3U), /*!< Position compare interrupt enable. */
32     kENC_SimultBothPhaseChangeInterruptEnable =
33         (1U << 4U),                                     /*!< Simultaneous PHASEA and PHASEB change interrupt enable. */
34     kENC_PositionRollOverInterruptEnable  = (1U << 5U), /*!< Roll-over interrupt enable. */
35     kENC_PositionRollUnderInterruptEnable = (1U << 6U), /*!< Roll-under interrupt enable. */
36 };
37 
38 /*!
39  * @brief Status flag mask.
40  *
41  * These flags indicate the counter's events.
42  */
43 enum _enc_status_flags
44 {
45     kENC_HOMETransitionFlag        = (1U << 0U), /*!< HOME signal transition interrupt request. */
46     kENC_INDEXPulseFlag            = (1U << 1U), /*!< INDEX Pulse Interrupt Request. */
47     kENC_WatchdogTimeoutFlag       = (1U << 2U), /*!< Watchdog timeout interrupt request. */
48     kENC_PositionCompareFlag       = (1U << 3U), /*!< Position compare interrupt request. */
49     kENC_SimultBothPhaseChangeFlag = (1U << 4U), /*!< Simultaneous PHASEA and PHASEB change interrupt request. */
50     kENC_PositionRollOverFlag      = (1U << 5U), /*!< Roll-over interrupt request. */
51     kENC_PositionRollUnderFlag     = (1U << 6U), /*!< Roll-under interrupt request. */
52     kENC_LastCountDirectionFlag    = (1U << 7U), /*!< Last count was in the up direction, or the down direction. */
53 };
54 
55 /*!
56  * @brief Signal status flag mask.
57  *
58  * These flags indicate the counter's signal.
59  */
60 enum _enc_signal_status_flags
61 {
62     kENC_RawHOMEStatusFlag       = ENC_IMR_HOME_MASK,  /*!< Raw HOME input. */
63     kENC_RawINDEXStatusFlag      = ENC_IMR_INDEX_MASK, /*!< Raw INDEX input. */
64     kENC_RawPHBStatusFlag        = ENC_IMR_PHB_MASK,   /*!< Raw PHASEB input. */
65     kENC_RawPHAEXStatusFlag      = ENC_IMR_PHA_MASK,   /*!< Raw PHASEA input. */
66     kENC_FilteredHOMEStatusFlag  = ENC_IMR_FHOM_MASK,  /*!< The filtered version of HOME input. */
67     kENC_FilteredINDEXStatusFlag = ENC_IMR_FIND_MASK,  /*!< The filtered version of INDEX input. */
68     kENC_FilteredPHBStatusFlag   = ENC_IMR_FPHB_MASK,  /*!< The filtered version of PHASEB input. */
69     kENC_FilteredPHAStatusFlag   = ENC_IMR_FPHA_MASK,  /*!< The filtered version of PHASEA input. */
70 };
71 
72 /*!
73  * @brief Define HOME signal's trigger mode.
74  *
75  * The ENC would count the trigger from HOME signal line.
76  */
77 typedef enum _enc_home_trigger_mode
78 {
79     kENC_HOMETriggerDisabled = 0U, /*!< HOME signal's trigger is disabled. */
80     kENC_HOMETriggerOnRisingEdge,  /*!< Use positive going edge-to-trigger initialization of position counters. */
81     kENC_HOMETriggerOnFallingEdge, /*!< Use negative going edge-to-trigger initialization of position counters. */
82 } enc_home_trigger_mode_t;
83 
84 /*!
85  * @brief Define INDEX signal's trigger mode.
86  *
87  * The ENC would count the trigger from INDEX signal line.
88  */
89 typedef enum _enc_index_trigger_mode
90 {
91     kENC_INDEXTriggerDisabled = 0U, /*!< INDEX signal's trigger is disabled. */
92     kENC_INDEXTriggerOnRisingEdge,  /*!< Use positive going edge-to-trigger initialization of position counters. */
93     kENC_INDEXTriggerOnFallingEdge, /*!< Use negative going edge-to-trigger initialization of position counters. */
94 } enc_index_trigger_mode_t;
95 
96 /*!
97  * @brief Define type for decoder work mode.
98  *
99  * The normal work mode uses the standard quadrature decoder with PHASEA and PHASEB. When in signal phase count mode,
100  * a positive transition of the PHASEA input generates a count signal while the PHASEB input and the reverse direction
101  * control the counter direction. If the reverse direction is not enabled, PHASEB = 0 means counting up and PHASEB = 1
102  * means counting down. Otherwise, the direction is reversed.
103  */
104 typedef enum _enc_decoder_work_mode
105 {
106     kENC_DecoderWorkAsNormalMode = 0U,      /*!< Use standard quadrature decoder with PHASEA and PHASEB. */
107     kENC_DecoderWorkAsSignalPhaseCountMode, /*!< PHASEA input generates a count signal while PHASEB input control the
108                                                direction. */
109 } enc_decoder_work_mode_t;
110 
111 /*!
112  * @brief Define type for the condition of POSMATCH pulses.
113  */
114 typedef enum _enc_position_match_mode
115 {
116     kENC_POSMATCHOnPositionCounterEqualToComapreValue = 0U, /*!< POSMATCH pulses when a match occurs between the
117                                                                position counters (POS) and the compare value (COMP). */
118     kENC_POSMATCHOnReadingAnyPositionCounter, /*!< POSMATCH pulses when any position counter register is read. */
119 } enc_position_match_mode_t;
120 
121 /*!
122  * @brief Define type for determining how the revolution counter (REV) is incremented/decremented.
123  */
124 typedef enum _enc_revolution_count_condition
125 {
126     kENC_RevolutionCountOnINDEXPulse = 0U, /*!< Use INDEX pulse to increment/decrement revolution counter. */
127     kENC_RevolutionCountOnRollOverModulus, /*!< Use modulus counting roll-over/under to increment/decrement revolution
128                                               counter. */
129 } enc_revolution_count_condition_t;
130 
131 /*!
132  * @brief Define type for direction of self test generated signal.
133  */
134 typedef enum _enc_self_test_direction
135 {
136     kENC_SelfTestDirectionPositive = 0U, /*!< Self test generates the signal in positive direction. */
137     kENC_SelfTestDirectionNegative,      /*!< Self test generates the signal in negative direction. */
138 } enc_self_test_direction_t;
139 
140 /*!
141  * @brief Define user configuration structure for ENC module.
142  */
143 typedef struct _enc_config
144 {
145     /* Basic counter. */
146     bool enableReverseDirection;             /*!< Enable reverse direction counting. */
147     enc_decoder_work_mode_t decoderWorkMode; /*!< Enable signal phase count mode. */
148 
149     /* Signal detection. */
150     enc_home_trigger_mode_t HOMETriggerMode;   /*!< Enable HOME to initialize position counters. */
151     enc_index_trigger_mode_t INDEXTriggerMode; /*!< Enable INDEX to initialize position counters. */
152     bool enableTRIGGERClearPositionCounter;    /*!< Clear POSD, REV, UPOS and LPOS on rising edge of TRIGGER, or not. */
153     bool enableTRIGGERClearHoldPositionCounter; /*!< Enable update of hold registers on rising edge of TRIGGER, or not.
154                                                  */
155 
156     /* Watchdog. */
157     bool enableWatchdog;           /*!< Enable the watchdog to detect if the target is moving or not. */
158     uint16_t watchdogTimeoutValue; /*!< Watchdog timeout count value. It stores the timeout count for the quadrature
159                                         decoder module watchdog timer. This field is only available when
160                                         "enableWatchdog" = true. The available value is a 16-bit unsigned number.*/
161 
162     /* Filter for PHASEA, PHASEB, INDEX and HOME. */
163     uint16_t filterCount; /*!< Input Filter Sample Count. This value should be chosen to reduce the probability of
164                                noisy samples causing an incorrect transition to be recognized. The value represent the
165                                number of consecutive samples that must agree prior to the input filter accepting an
166                                input transition. A value of 0x0 represents 3 samples. A value of 0x7 represents 10
167                                samples. The Available range is 0 - 7.*/
168     uint16_t filterSamplePeriod; /*!< Input Filter Sample Period. This value should be set such that the sampling period
169                                       is larger than the period of the expected noise. This value represents the
170                                       sampling period (in IPBus clock cycles) of the decoder input signals.
171                                       The available range is 0 - 255. */
172 
173     /* Position compare. */
174     enc_position_match_mode_t positionMatchMode; /*!< The condition of POSMATCH pulses. */
175     uint32_t positionCompareValue;               /*!< Position compare value. The available value is a 32-bit number.*/
176 
177     /* Modulus counting. */
178     enc_revolution_count_condition_t revolutionCountCondition; /*!< Revolution Counter Modulus Enable. */
179     bool enableModuloCountMode;                                /*!< Enable Modulo Counting. */
180     uint32_t positionModulusValue; /*!< Position modulus value. This value would be available only when
181                                         "enableModuloCountMode" = true. The available value is a 32-bit number. */
182     uint32_t positionInitialValue; /*!< Position initial value. The available value is a 32-bit number. */
183 } enc_config_t;
184 
185 /*!
186  * @brief Define configuration structure for self test module.
187  *
188  * The self test module provides a quadrature test signal to the inputs of the quadrature decoder module.
189  * This is a factory test feature. It is also useful to customers' software development and testing.
190  */
191 typedef struct _enc_self_test_config
192 {
193     enc_self_test_direction_t signalDirection; /*!< Direction of self test generated signal. */
194     uint16_t signalCount;  /*!< Hold the number of quadrature advances to generate. The available range is 0 - 255.*/
195     uint16_t signalPeriod; /*!< Hold the period of quadrature phase in IPBus clock cycles.
196                                 The available range is 0 - 31. */
197 } enc_self_test_config_t;
198 
199 #if defined(__cplusplus)
200 extern "C" {
201 #endif
202 
203 /*******************************************************************************
204  * API
205  ******************************************************************************/
206 
207 /*!
208  * @name Initialization and De-initialization
209  * @{
210  */
211 
212 /*!
213  * @brief Initialization for the ENC module.
214  *
215  * This function is to make the initialization for the ENC module. It should be called firstly before any operation to
216  * the ENC with the operations like:
217  *  - Enable the clock for ENC module.
218  *  - Configure the ENC's working attributes.
219  *
220  * @param base   ENC peripheral base address.
221  * @param config Pointer to configuration structure. See to "enc_config_t".
222  */
223 void ENC_Init(ENC_Type *base, const enc_config_t *config);
224 
225 /*!
226  * @brief De-initialization for the ENC module.
227  *
228  * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with
229  * the operations like:
230  *  - Disable the clock for ENC module.
231  *
232  * @param base ENC peripheral base address.
233  */
234 void ENC_Deinit(ENC_Type *base);
235 
236 /*!
237  * @brief Get an available pre-defined settings for ENC's configuration.
238  *
239  * This function initializes the ENC configuration structure with an available settings, the default value are:
240  * @code
241  *   config->enableReverseDirection                = false;
242  *   config->decoderWorkMode                       = kENC_DecoderWorkAsNormalMode;
243  *   config->HOMETriggerMode                       = kENC_HOMETriggerDisabled;
244  *   config->INDEXTriggerMode                      = kENC_INDEXTriggerDisabled;
245  *   config->enableTRIGGERClearPositionCounter     = false;
246  *   config->enableTRIGGERClearHoldPositionCounter = false;
247  *   config->enableWatchdog                        = false;
248  *   config->watchdogTimeoutValue                  = 0U;
249  *   config->filterCount                           = 0U;
250  *   config->filterSamplePeriod                    = 0U;
251  *   config->positionMatchMode                     = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
252  *   config->positionCompareValue                  = 0xFFFFFFFFU;
253  *   config->revolutionCountCondition              = kENC_RevolutionCountOnINDEXPulse;
254  *   config->enableModuloCountMode                 = false;
255  *   config->positionModulusValue                  = 0U;
256  *   config->positionInitialValue                  = 0U;
257  * @endcode
258  * @param config Pointer to a variable of configuration structure. See to "enc_config_t".
259  */
260 void ENC_GetDefaultConfig(enc_config_t *config);
261 
262 /*!
263  * @brief Load the initial position value to position counter.
264  *
265  * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and
266  * LPOS), so that to provide the consistent operation the position counter registers.
267  *
268  * @param base ENC peripheral base address.
269  */
270 void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base);
271 
272 /*!
273  * @brief Enable and configure the self test function.
274  *
275  * This function is to enable and configuration the self test function. It controls and sets the frequency of a
276  * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module.
277  * It is a factory test feature; however, it may be useful to customers' software development and testing.
278  *
279  * @param base   ENC peripheral base address.
280  * @param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable.
281  */
282 void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config);
283 
284 /*!
285  * @brief Enable watchdog for ENC module.
286  *
287  * @param base ENC peripheral base address
288  * @param enable Enables or disables the watchdog
289  */
290 void ENC_EnableWatchdog(ENC_Type *base, bool enable);
291 
292 /*!
293  * @brief Set initial position value for ENC module.
294  *
295  * @param base ENC peripheral base address
296  * @param value Positive initial value
297  */
298 void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value);
299 
300 /* @} */
301 
302 /*!
303  * @name Status
304  * @{
305  */
306 /*!
307  * @brief  Get the status flags.
308  *
309  * @param  base ENC peripheral base address.
310  *
311  * @return      Mask value of status flags. For available mask, see to "_enc_status_flags".
312  */
313 uint32_t ENC_GetStatusFlags(ENC_Type *base);
314 
315 /*!
316  * @brief Clear the status flags.
317  *
318  * @param base ENC peripheral base address.
319  * @param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags".
320  */
321 void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask);
322 
323 /*!
324  * @brief  Get the signals' real-time status.
325  *
326  * @param  base ENC peripheral base address.
327  *
328  * @return      Mask value of signals' real-time status. For available mask, see to "_enc_signal_status_flags"
329  */
ENC_GetSignalStatusFlags(ENC_Type * base)330 static inline uint16_t ENC_GetSignalStatusFlags(ENC_Type *base)
331 {
332     return base->IMR;
333 }
334 /* @} */
335 
336 /*!
337  * @name Interrupts
338  * @{
339  */
340 
341 /*!
342  * @brief Enable the interrupts.
343  *
344  * @param base ENC peripheral base address.
345  * @param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable".
346  */
347 void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask);
348 
349 /*!
350  * @brief Disable the interrupts.
351  *
352  * @param base ENC peripheral base address.
353  * @param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable".
354  */
355 void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask);
356 
357 /*!
358  * @brief  Get the enabled interrupts' flags.
359  *
360  * @param  base ENC peripheral base address.
361  *
362  * @return      Mask value of enabled interrupts.
363  */
364 uint32_t ENC_GetEnabledInterrupts(ENC_Type *base);
365 
366 /* @} */
367 
368 /*!
369  * @name Value Operation
370  * @{
371  */
372 
373 /*!
374  * @brief  Get the current position counter's value.
375  *
376  * @param  base ENC peripheral base address.
377  *
378  * @return     Current position counter's value.
379  */
380 uint32_t ENC_GetPositionValue(ENC_Type *base);
381 
382 /*!
383  * @brief  Get the hold position counter's value.
384  *
385  * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
386  * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
387  * be attained.
388  *
389  * @param  base ENC peripheral base address.
390  *
391  * @return      Hold position counter's value.
392  */
393 uint32_t ENC_GetHoldPositionValue(ENC_Type *base);
394 
395 /*!
396  * @brief  Get the position difference counter's value.
397  *
398  * @param  base ENC peripheral base address.
399  *
400  * @return     The position difference counter's value.
401  */
ENC_GetPositionDifferenceValue(ENC_Type * base)402 static inline uint16_t ENC_GetPositionDifferenceValue(ENC_Type *base)
403 {
404     return base->POSD;
405 }
406 
407 /*!
408  * @brief  Get the hold position difference counter's value.
409  *
410  * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
411  * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
412  * be attained.
413  *
414  * @param  base ENC peripheral base address.
415  *
416  * @return      Hold position difference counter's value.
417  */
ENC_GetHoldPositionDifferenceValue(ENC_Type * base)418 static inline uint16_t ENC_GetHoldPositionDifferenceValue(ENC_Type *base)
419 {
420     return base->POSDH;
421 }
422 
423 /*!
424  * @brief  Get the position revolution counter's value.
425  *
426  * @param  base ENC peripheral base address.
427  *
428  * @return     The position revolution counter's value.
429  */
ENC_GetRevolutionValue(ENC_Type * base)430 static inline uint16_t ENC_GetRevolutionValue(ENC_Type *base)
431 {
432     return base->REV;
433 }
434 /*!
435  * @brief  Get the hold position revolution counter's value.
436  *
437  * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
438  * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
439  * be attained.
440  *
441  * @param  base ENC peripheral base address.
442  *
443  * @return      Hold position revolution counter's value.
444  */
ENC_GetHoldRevolutionValue(ENC_Type * base)445 static inline uint16_t ENC_GetHoldRevolutionValue(ENC_Type *base)
446 {
447     return base->REVH;
448 }
449 
450 /* @} */
451 
452 #if defined(__cplusplus)
453 }
454 #endif
455 
456 /* @} */
457 
458 #endif /* _FSL_ENC_H_ */
459