1 /*
2  * Copyright 2017-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_capt.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.capt"
17 #endif
18 
19 /*******************************************************************************
20  * Prototypes
21  ******************************************************************************/
22 /*!
23  * @brief Get the CAPT instance from the peripheral base address.
24  *
25  * @param base CAPT peripheral base address.
26  * @return CAPT instance.
27  */
28 static uint32_t CAPT_GetInstance(CAPT_Type *base);
29 
30 /*******************************************************************************
31  * Variables
32  ******************************************************************************/
33 /* Array of CAPT peripheral base address. */
34 static CAPT_Type *const s_captBases[] = CAPT_BASE_PTRS;
35 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
36 /* Clock name of CAPT. */
37 static const clock_ip_name_t s_captClock[] = CAPT_CLOCKS;
38 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
39 
40 #if !(defined(FSL_FEATURE_CAPT_HAS_NO_RESET) && FSL_FEATURE_CAPT_HAS_NO_RESET)
41 /*! @brief Pointers to CAPT resets for each instance. */
42 static const reset_ip_name_t s_captResets[] = CAPT_RSTS_N;
43 #endif
44 
45 /*******************************************************************************
46  * Codes
47  ******************************************************************************/
CAPT_GetInstance(CAPT_Type * base)48 static uint32_t CAPT_GetInstance(CAPT_Type *base)
49 {
50     uint32_t instance;
51 
52     /* Find the instance index from base address mappings. */
53     for (instance = 0; instance < ARRAY_SIZE(s_captBases); instance++)
54     {
55         if (s_captBases[instance] == base)
56         {
57             break;
58         }
59     }
60 
61     assert(instance < ARRAY_SIZE(s_captBases));
62 
63     return instance;
64 }
65 /*!
66  * brief Initialize the CAPT module.
67  *
68  * param base CAPT peripheral base address.
69  * param config Pointer to "capt_config_t" structure.
70  */
CAPT_Init(CAPT_Type * base,const capt_config_t * config)71 void CAPT_Init(CAPT_Type *base, const capt_config_t *config)
72 {
73     assert(config != NULL);
74 
75     uint32_t tmp32;
76 
77 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
78     /* Open clock gate. */
79     CLOCK_EnableClock(s_captClock[CAPT_GetInstance(base)]);
80 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
81 
82 #if !(defined(FSL_FEATURE_CAPT_HAS_NO_RESET) && FSL_FEATURE_CAPT_HAS_NO_RESET)
83     /* Reset the CAPT module */
84     RESET_PeripheralReset(s_captResets[CAPT_GetInstance(base)]);
85 #endif
86 
87     /* Write CTRL register. */
88     tmp32 = base->CTRL & (CAPT_CTRL_POLLMODE_MASK | CAPT_CTRL_TYPE_MASK
89 #if defined(FSL_FEATURE_CAPT_HAS_CTRL_DMA) && FSL_FEATURE_CAPT_HAS_CTRL_DMA
90                           | CAPT_CTRL_DMA_MASK
91 #endif /* FSL_FEATURE_CAPT_HAS_CTRL_DMA */
92                          );
93     tmp32 |= CAPT_CTRL_TRIGGER(config->triggerMode) | CAPT_CTRL_FDIV(config->clockDivider) |
94              CAPT_CTRL_XPINUSE(config->XpinsMode) | CAPT_CTRL_XPINSEL(config->enableXpins);
95     if (config->enableWaitMode)
96     {
97         tmp32 |= CAPT_CTRL_WAIT_MASK;
98     }
99     /* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
100     while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
101     {
102     }
103     base->CTRL = tmp32;
104 
105     /* Write POLL_TCNT register. */
106     tmp32 = base->POLL_TCNT & CAPT_POLL_TCNT_TCNT_MASK;
107     tmp32 |= CAPT_POLL_TCNT_TOUT(config->timeOutCount) | CAPT_POLL_TCNT_POLL(config->pollCount) |
108              CAPT_POLL_TCNT_MDELAY(config->mDelay) | CAPT_POLL_TCNT_RDELAY(config->rDelay);
109     if (config->enableTouchLower)
110     {
111         tmp32 |= CAPT_POLL_TCNT_TCHLOW_ER_MASK;
112     }
113     base->POLL_TCNT = tmp32;
114 }
115 
116 /*!
117  * brief De-initialize the CAPT module.
118  *
119  * param base CAPT peripheral base address.
120  */
CAPT_Deinit(CAPT_Type * base)121 void CAPT_Deinit(CAPT_Type *base)
122 {
123     /* Make CAPT inactive. */
124     /* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
125     while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
126     {
127     }
128     base->CTRL &= ~CAPT_CTRL_POLLMODE_MASK;
129 
130 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
131     /* Disable clock gate. */
132     CLOCK_DisableClock(s_captClock[CAPT_GetInstance(base)]);
133 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
134 }
135 
136 /*!
137  * brief Gets an available pre-defined settings for the CAPT's configuration.
138  *
139  * This function initializes the converter configuration structure with available settings. The default values are:
140  * code
141  *   config->enableWaitMode = false;
142  *   config->enableTouchLower = true;
143  *   config->clockDivider = 15U;
144  *   config->timeOutCount = 12U;
145  *   config->pollCount = 0U;
146  *   config->enableXpins = 0U;
147  *   config->triggerMode = kCAPT_YHPortTriggerMode;
148  *   config->XpinsMode = kCAPT_InactiveXpinsDrivenLowMode;
149  *   config->mDelay = kCAPT_MeasureDelayNoWait;
150  *   config->rDelay = kCAPT_ResetDelayWait9FCLKs;
151  * endcode
152  * param base   CAPT peripheral base address.
153  * param config Pointer to the configuration structure.
154  */
CAPT_GetDefaultConfig(capt_config_t * config)155 void CAPT_GetDefaultConfig(capt_config_t *config)
156 {
157     assert(NULL != config);
158 
159     /* Initializes the configure structure to zero. */
160     (void)memset(config, 0, sizeof(*config));
161 
162     config->enableWaitMode   = false;
163     config->enableTouchLower = true;
164     config->clockDivider     = 15U;
165     config->timeOutCount     = 12U;
166     config->pollCount        = 0U;
167     config->enableXpins      = 0U;
168     config->triggerMode      = kCAPT_YHPortTriggerMode;
169     config->XpinsMode        = kCAPT_InactiveXpinsDrivenLowMode;
170     config->mDelay           = kCAPT_MeasureDelayNoWait;
171     config->rDelay           = kCAPT_ResetDelayWait9FCLKs;
172 }
173 
174 /*!
175  * brief Set the CAPT polling mode.
176  *
177  * param base CAPT peripheral base address.
178  * param mode The selection of polling mode.
179  */
CAPT_SetPollMode(CAPT_Type * base,capt_polling_mode_t mode)180 void CAPT_SetPollMode(CAPT_Type *base, capt_polling_mode_t mode)
181 {
182     /* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
183     while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
184     {
185     }
186 
187     base->CTRL &= ~CAPT_CTRL_POLLMODE_MASK;
188     base->CTRL |= CAPT_CTRL_POLLMODE(mode);
189 }
190 
191 #if defined(FSL_FEATURE_CAPT_HAS_CTRL_DMA) && FSL_FEATURE_CAPT_HAS_CTRL_DMA
192 /*!
193  * brief Enable DMA feature.
194  *
195  * param base CAPT peripheral base address.
196  * param mode Select how DMA triggers are generated.
197  */
CAPT_EnableDMA(CAPT_Type * base,capt_dma_mode_t mode)198 void CAPT_EnableDMA(CAPT_Type *base, capt_dma_mode_t mode)
199 {
200     /* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
201     while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
202     {
203     }
204     base->CTRL = (base->CTRL & ~CAPT_CTRL_DMA_MASK) | CAPT_CTRL_DMA(mode);
205 }
206 
207 /*!
208  * brief Disable DMA feature.
209  *
210  * param base CAPT peripheral base address.
211  */
CAPT_DisableDMA(CAPT_Type * base)212 void CAPT_DisableDMA(CAPT_Type *base)
213 {
214     /* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
215     while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
216     {
217     }
218     base->CTRL &= ~CAPT_CTRL_DMA_MASK;
219 }
220 #endif /*FSL_FEATURE_CAPT_HAS_CTRL_DMA*/
221 
222 /*!
223  * brief Get CAPT touch data.
224  *
225  * param base CAPT peripheral base address.
226  * param data The structure to store touch data.
227  *
228  * return If return 'true', which means get valid data.
229  *         if return 'false', which means get invalid data.
230  */
CAPT_GetTouchData(CAPT_Type * base,capt_touch_data_t * data)231 bool CAPT_GetTouchData(CAPT_Type *base, capt_touch_data_t *data)
232 {
233     assert(NULL != data);
234 
235     uint32_t tmp32;
236     bool ret;
237 
238     tmp32 = base->TOUCH;
239 
240     if (CAPT_TOUCH_CHANGE_MASK == (CAPT_TOUCH_CHANGE_MASK & tmp32))
241     {
242         ret = false;
243     }
244     else
245     {
246         if (CAPT_TOUCH_ISTOUCH_MASK == (CAPT_TOUCH_ISTOUCH_MASK & tmp32))
247         {
248             data->yesTouch = true;
249         }
250         else
251         {
252             data->yesTouch = false;
253         }
254         if (CAPT_TOUCH_ISTO_MASK == (CAPT_TOUCH_ISTO_MASK & tmp32))
255         {
256             data->yesTimeOut = true;
257         }
258         else
259         {
260             data->yesTimeOut = false;
261         }
262         data->XpinsIndex     = (uint8_t)((CAPT_TOUCH_XVAL_MASK & tmp32) >> CAPT_TOUCH_XVAL_SHIFT);
263         data->sequenceNumber = (uint8_t)((CAPT_TOUCH_SEQ_MASK & tmp32) >> CAPT_TOUCH_SEQ_SHIFT);
264         data->count          = (uint16_t)((CAPT_TOUCH_COUNT_MASK & tmp32) >> CAPT_TOUCH_COUNT_SHIFT);
265 
266         ret = true;
267     }
268 
269     return ret;
270 }
271 
272 /*
273  * brief Start touch data polling using poll-now method.
274  *
275  * This function starts new data polling using polling-now method, CAPT stops when
276  * the polling is finished, application could check the status or monitor interrupt
277  * to know when the progress is finished.
278  *
279  * Note that this is simultaneous poll of all X pins, all enabled X pins are
280  * activated concurrently, rather than walked one-at-a-time
281  *
282  * param base CAPT peripheral base address.
283  * param enableXpins The X pins enabled in this polling.
284  */
CAPT_PollNow(CAPT_Type * base,uint16_t enableXpins)285 void CAPT_PollNow(CAPT_Type *base, uint16_t enableXpins)
286 {
287     /* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
288     while (0U != (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
289     {
290     }
291 
292     /* If poll mode is not 0, change to 0. */
293     if (0U != (base->CTRL & CAPT_CTRL_POLLMODE_MASK))
294     {
295         base->CTRL &= ~CAPT_CTRL_POLLMODE_MASK;
296 
297         while (0U != (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
298         {
299         }
300     }
301 
302     base->CTRL = (base->CTRL & ~(CAPT_CTRL_XPINSEL_MASK)) | CAPT_CTRL_POLLMODE(kCAPT_PollNowMode) |
303                  CAPT_CTRL_XPINSEL(enableXpins);
304 }
305