1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2021 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #include "fsl_tsi_v5.h"
9
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.tsi_v5"
13 #endif
14
15 /*******************************************************************************
16 * Prototypes
17 ******************************************************************************/
18
19 /*******************************************************************************
20 * Variables
21 ******************************************************************************/
22 /* Array of TSI clock name. */
23 const clock_ip_name_t s_tsiClock[] = TSI_CLOCKS;
24 /* Array of TSI IRQ name. */
25 const IRQn_Type s_TsiIRQ[] = TSI_IRQS;
26 /* Array of TSI peripheral base address. */
27 TSI_Type *const s_tsiBases[] = TSI_BASE_PTRS;
28 /*******************************************************************************
29 * Code
30 ******************************************************************************/
31 /*!
32 * brief Get the TSI instance from peripheral base address.
33 *
34 * param base TSI peripheral base address.
35 * return TSI instance.
36 */
TSI_GetInstance(TSI_Type * base)37 uint32_t TSI_GetInstance(TSI_Type *base)
38 {
39 uint32_t instance;
40
41 /* Find the instance index from base address mappings. */
42 for (instance = 0U; instance < ARRAY_SIZE(s_tsiBases); instance++)
43 {
44 if (s_tsiBases[instance] == base)
45 {
46 break;
47 }
48 }
49
50 assert(instance < ARRAY_SIZE(s_tsiBases));
51
52 return instance;
53 }
54
55 /*!
56 * brief Initialize hardware to Self-cap mode.
57 *
58 * details Initialize the peripheral to the targeted state specified by parameter config,
59 * such as sets sensitivity adjustment, current settings.
60 * param base TSI peripheral base address.
61 * param config Pointer to TSI self-cap configuration structure.
62 * return none
63 */
TSI_InitSelfCapMode(TSI_Type * base,const tsi_selfCap_config_t * config)64 void TSI_InitSelfCapMode(TSI_Type *base, const tsi_selfCap_config_t *config)
65 {
66 uint32_t temp = 0U;
67 assert(config != NULL);
68
69 bool is_module_enabled = false;
70 bool is_int_enabled = false;
71
72 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
73 uint32_t instance = TSI_GetInstance(base);
74
75 /* Enable tsi clock */
76 (void)CLOCK_EnableClock(s_tsiClock[instance]);
77 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
78 if ((bool)(base->GENCS & TSI_GENCS_TSIEN_MASK))
79 {
80 is_module_enabled = true;
81 TSI_EnableModule(base, false);
82 }
83 if ((bool)(base->GENCS & TSI_GENCS_TSIIEN_MASK))
84 {
85 is_int_enabled = true;
86 TSI_DisableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
87 }
88
89 /* common settings */
90 temp = (base->MODE) & ~(TSI_MODE_SETCLK_MASK | TSI_MODE_MODE_MASK | TSI_MODE_S_SEN_MASK | TSI_MODE_S_W_SHIELD_MASK);
91 base->MODE = temp | (TSI_MODE_S_W_SHIELD(config->enableShield) | TSI_MODE_S_SEN(config->enableSensitivity) |
92 TSI_MODE_SETCLK(config->commonConfig.mainClock) | TSI_MODE_MODE(config->commonConfig.mode));
93
94 base->GENCS =
95 (base->GENCS & (~(ALL_FLAGS_MASK | TSI_GENCS_DVOLT_MASK))) | TSI_GENCS_DVOLT(config->commonConfig.dvolt);
96
97 temp = (base->SINC) & ~(TSI_SINC_CUTOFF_MASK | TSI_SINC_ORDER_MASK | TSI_SINC_DECIMATION_MASK);
98 base->SINC = temp | (TSI_SINC_CUTOFF(config->commonConfig.cutoff) | TSI_SINC_ORDER(config->commonConfig.order) |
99 TSI_SINC_DECIMATION(config->commonConfig.decimation));
100
101 temp = (base->SSC0) & ~(TSI_SSC0_CHARGE_NUM_MASK | TSI_SSC0_BASE_NOCHARGE_NUM_MASK | TSI_SSC0_PRBS_OUTSEL_MASK |
102 TSI_SSC0_SSC_PRESCALE_NUM_MASK | TSI_SSC0_SSC_MODE_MASK);
103 base->SSC0 =
104 temp | (TSI_SSC0_PRBS_OUTSEL(config->commonConfig.prbsOutsel) |
105 TSI_SSC0_SSC_MODE(config->commonConfig.ssc_mode) | TSI_SSC0_CHARGE_NUM(config->commonConfig.chargeNum) |
106 TSI_SSC0_BASE_NOCHARGE_NUM(config->commonConfig.noChargeNum) |
107 TSI_SSC0_SSC_PRESCALE_NUM(config->commonConfig.ssc_prescaler));
108
109 /* Self-cap mode specific settings */
110 temp = (base->MODE) & ~(TSI_MODE_S_XDN_MASK | TSI_MODE_S_CTRIM_MASK | TSI_MODE_S_XIN_MASK | TSI_MODE_S_XCH_MASK);
111 base->MODE = temp | (TSI_MODE_S_XDN(config->xdn) | TSI_MODE_S_CTRIM(config->ctrim) |
112 TSI_MODE_S_XIN(config->inputCurrent) | TSI_MODE_S_XCH(config->chargeCurrent));
113
114 if (is_module_enabled)
115 {
116 TSI_EnableModule(base, true);
117 }
118 if (is_int_enabled)
119 {
120 TSI_EnableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
121 }
122 }
123
124 /*!
125 * brief Initialize hardware to Mutual-cap mode.
126 *
127 * details Initialize the peripheral to the targeted state specified by parameter config,
128 * such as sets Vref generator setting, sensitivity boost settings, Pmos/Nmos settings.
129 * param base TSI peripheral base address.
130 * param config Pointer to TSI mutual-cap configuration structure.
131 * return none
132 */
TSI_InitMutualCapMode(TSI_Type * base,const tsi_mutualCap_config_t * config)133 void TSI_InitMutualCapMode(TSI_Type *base, const tsi_mutualCap_config_t *config)
134 {
135 uint32_t temp = 0U;
136 assert(config != NULL);
137
138 bool is_module_enabled = false;
139 bool is_int_enabled = false;
140
141 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
142 uint32_t instance = TSI_GetInstance(base);
143
144 /* Enable tsi clock */
145 (void)CLOCK_EnableClock(s_tsiClock[instance]);
146 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
147 if ((bool)(base->GENCS & TSI_GENCS_TSIEN_MASK))
148 {
149 is_module_enabled = true;
150 TSI_EnableModule(base, false);
151 }
152 if ((bool)(base->GENCS & (uint32_t)TSI_GENCS_TSIIEN_MASK))
153 {
154 is_int_enabled = true;
155 TSI_DisableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
156 }
157
158 /* Common settings */
159 temp = (base->MODE) & ~(TSI_MODE_SETCLK_MASK | TSI_MODE_MODE_MASK);
160 base->MODE = temp | (TSI_MODE_SETCLK(config->commonConfig.mainClock) | TSI_MODE_MODE(config->commonConfig.mode));
161
162 base->GENCS =
163 (base->GENCS & (~(ALL_FLAGS_MASK | TSI_GENCS_DVOLT_MASK))) | TSI_GENCS_DVOLT(config->commonConfig.dvolt);
164
165 temp = (base->SINC) & ~(TSI_SINC_CUTOFF_MASK | TSI_SINC_ORDER_MASK | TSI_SINC_DECIMATION_MASK);
166 base->SINC = temp | (TSI_SINC_CUTOFF(config->commonConfig.cutoff) | TSI_SINC_ORDER(config->commonConfig.order) |
167 TSI_SINC_DECIMATION(config->commonConfig.decimation));
168
169 temp = (base->SSC0) & ~(TSI_SSC0_CHARGE_NUM_MASK | TSI_SSC0_BASE_NOCHARGE_NUM_MASK | TSI_SSC0_PRBS_OUTSEL_MASK |
170 TSI_SSC0_SSC_PRESCALE_NUM_MASK | TSI_SSC0_SSC_MODE_MASK);
171 base->SSC0 =
172 temp | (TSI_SSC0_PRBS_OUTSEL(config->commonConfig.prbsOutsel) |
173 TSI_SSC0_SSC_MODE(config->commonConfig.ssc_mode) | TSI_SSC0_CHARGE_NUM(config->commonConfig.chargeNum) |
174 TSI_SSC0_BASE_NOCHARGE_NUM(config->commonConfig.noChargeNum) |
175 TSI_SSC0_SSC_PRESCALE_NUM(config->commonConfig.ssc_prescaler));
176
177 /* Mutual-cap mode specific configurations */
178 temp = (base->MUL0) & ~(TSI_MUL0_M_PRE_CURRENT_MASK | TSI_MUL0_M_PRE_RES_MASK | TSI_MUL0_M_SEN_RES_MASK);
179 base->MUL0 = temp | (TSI_MUL0_M_PRE_CURRENT(config->preCurrent) | TSI_MUL0_M_PRE_RES(config->preResistor) |
180 TSI_MUL0_M_SEN_RES(config->senseResistor));
181
182 temp = (base->MUL1) & ~(TSI_MUL1_M_SEN_BOOST_MASK | TSI_MUL1_M_MODE_MASK | TSI_MUL1_M_PMIRRORL_MASK |
183 TSI_MUL1_M_PMIRRORR_MASK | TSI_MUL1_M_NMIRROR_MASK);
184 base->MUL1 = temp | (TSI_MUL1_M_SEN_BOOST(config->boostCurrent) | TSI_MUL1_M_MODE(config->txDriveMode) |
185 TSI_MUL1_M_PMIRRORL(config->pmosLeftCurrent) | TSI_MUL1_M_PMIRRORR(config->pmosRightCurrent) |
186 TSI_MUL1_M_NMIRROR(config->nmosCurrent));
187
188 if (is_module_enabled)
189 {
190 TSI_EnableModule(base, true);
191 }
192 if (is_int_enabled)
193 {
194 TSI_EnableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
195 }
196 }
197
198 /*!
199 * brief De-initialize hardware.
200 *
201 * details De-initialize the peripheral to default state.
202 *
203 * param base TSI peripheral base address.
204 * return none
205 */
TSI_Deinit(TSI_Type * base)206 void TSI_Deinit(TSI_Type *base)
207 {
208 base->GENCS = 0U;
209 base->DATA = 0U;
210 base->TSHD = 0U;
211
212 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
213 uint32_t instance = TSI_GetInstance(base);
214
215 /* Disable tsi clock */
216 (void)CLOCK_DisableClock(s_tsiClock[instance]);
217 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
218 }
219
220 /*!
221 * brief Get TSI self-cap mode user configure structure.
222 * This interface sets userConfig structure to a default value. The configuration structure only
223 * includes the settings for the whole TSI.
224 * The user configure is set to a value:
225 * code
226 userConfig->commonConfig.mainClock = kTSI_MainClockSlection_0;
227 userConfig->commonConfig.mode = kTSI_SensingModeSlection_Self;
228 userConfig->commonConfig.dvolt = kTSI_DvoltOption_2;
229 userConfig->commonConfig.cutoff = kTSI_SincCutoffDiv_1;
230 userConfig->commonConfig.order = kTSI_SincFilterOrder_1;
231 userConfig->commonConfig.decimation = kTSI_SincDecimationValue_8;
232 userConfig->commonConfig.chargeNum = kTSI_SscChargeNumValue_3;
233 userConfig->commonConfig.prbsOutsel = kTSI_SscPrbsOutsel_2;
234 userConfig->commonConfig.noChargeNum = kTSI_SscNoChargeNumValue_2;
235 userConfig->commonConfig.ssc_mode = kTSI_ssc_prbs_method;
236 userConfig->commonConfig.ssc_prescaler = kTSI_ssc_div_by_1;
237 userConfig->enableSensitivity = true;
238 userConfig->enableShield = false;
239 userConfig->xdn = kTSI_SensitivityXdnOption_1;
240 userConfig->ctrim = kTSI_SensitivityCtrimOption_7;
241 userConfig->inputCurrent = kTSI_CurrentMultipleInputValue_0;
242 userConfig->chargeCurrent = kTSI_CurrentMultipleChargeValue_1;
243 endcode
244 *
245 * param userConfig Pointer to TSI user configure structure.
246 */
TSI_GetSelfCapModeDefaultConfig(tsi_selfCap_config_t * userConfig)247 void TSI_GetSelfCapModeDefaultConfig(tsi_selfCap_config_t *userConfig)
248 {
249 /* Initializes the configure structure to zero. */
250 (void)memset(userConfig, 0, sizeof(*userConfig));
251
252 userConfig->commonConfig.mainClock = kTSI_MainClockSlection_0;
253 userConfig->commonConfig.mode = kTSI_SensingModeSlection_Self;
254 userConfig->commonConfig.dvolt = kTSI_DvoltOption_2;
255 userConfig->commonConfig.cutoff = kTSI_SincCutoffDiv_1;
256 userConfig->commonConfig.order = kTSI_SincFilterOrder_1;
257 userConfig->commonConfig.decimation = kTSI_SincDecimationValue_8;
258 userConfig->commonConfig.chargeNum = kTSI_SscChargeNumValue_3;
259 userConfig->commonConfig.prbsOutsel = kTSI_SscPrbsOutsel_2;
260 userConfig->commonConfig.noChargeNum = kTSI_SscNoChargeNumValue_2;
261 userConfig->commonConfig.ssc_mode = kTSI_ssc_prbs_method;
262 userConfig->commonConfig.ssc_prescaler = kTSI_ssc_div_by_1;
263 userConfig->enableSensitivity = true;
264 userConfig->enableShield = kTSI_shieldAllOff;
265 userConfig->xdn = kTSI_SensitivityXdnOption_1;
266 userConfig->ctrim = kTSI_SensitivityCtrimOption_7;
267 userConfig->inputCurrent = kTSI_CurrentMultipleInputValue_0;
268 userConfig->chargeCurrent = kTSI_CurrentMultipleChargeValue_1;
269 }
270
271 /*!
272 * brief Get TSI mutual-cap mode default user configure structure.
273 * This interface sets userConfig structure to a default value. The configuration structure only
274 * includes the settings for the whole TSI.
275 * The user configure is set to a value:
276 * code
277 userConfig->commonConfig.mainClock = kTSI_MainClockSlection_1;
278 userConfig->commonConfig.mode = kTSI_SensingModeSlection_Mutual;
279 userConfig->commonConfig.dvolt = kTSI_DvoltOption_0;
280 userConfig->commonConfig.cutoff = kTSI_SincCutoffDiv_1;
281 userConfig->commonConfig.order = kTSI_SincFilterOrder_1;
282 userConfig->commonConfig.decimation = kTSI_SincDecimationValue_8;
283 userConfig->commonConfig.chargeNum = kTSI_SscChargeNumValue_4;
284 userConfig->commonConfig.prbsOutsel = kTSI_SscPrbsOutsel_2;
285 userConfig->commonConfig.noChargeNum = kTSI_SscNoChargeNumValue_5;
286 userConfig->commonConfig.ssc_mode = kTSI_ssc_prbs_method;
287 userConfig->commonConfig.ssc_prescaler = kTSI_ssc_div_by_1;
288 userConfig->preCurrent = kTSI_MutualPreCurrent_4uA;
289 userConfig->preResistor = kTSI_MutualPreResistor_4k;
290 userConfig->senseResistor = kTSI_MutualSenseResistor_10k;
291 userConfig->boostCurrent = kTSI_MutualSenseBoostCurrent_0uA;
292 userConfig->txDriveMode = kTSI_MutualTxDriveModeOption_0;
293 userConfig->pmosLeftCurrent = kTSI_MutualPmosCurrentMirrorLeft_32;
294 userConfig->pmosRightCurrent = kTSI_MutualPmosCurrentMirrorRight_1;
295 userConfig->enableNmosMirror = true;
296 userConfig->nmosCurrent = kTSI_MutualNmosCurrentMirror_1;
297 endcode
298 *
299 * param userConfig Pointer to TSI user configure structure.
300 */
TSI_GetMutualCapModeDefaultConfig(tsi_mutualCap_config_t * userConfig)301 void TSI_GetMutualCapModeDefaultConfig(tsi_mutualCap_config_t *userConfig)
302 {
303 /* Initializes the configure structure to zero. */
304 (void)memset(userConfig, 0, sizeof(*userConfig));
305
306 userConfig->commonConfig.mainClock = kTSI_MainClockSlection_1;
307 userConfig->commonConfig.mode = kTSI_SensingModeSlection_Mutual;
308 userConfig->commonConfig.dvolt = kTSI_DvoltOption_0;
309 userConfig->commonConfig.cutoff = kTSI_SincCutoffDiv_1;
310 userConfig->commonConfig.order = kTSI_SincFilterOrder_1;
311 userConfig->commonConfig.decimation = kTSI_SincDecimationValue_8;
312 userConfig->commonConfig.chargeNum = kTSI_SscChargeNumValue_4;
313 userConfig->commonConfig.prbsOutsel = kTSI_SscPrbsOutsel_2;
314 userConfig->commonConfig.noChargeNum = kTSI_SscNoChargeNumValue_5;
315 userConfig->commonConfig.ssc_mode = kTSI_ssc_prbs_method;
316 userConfig->commonConfig.ssc_prescaler = kTSI_ssc_div_by_1;
317 userConfig->preCurrent = kTSI_MutualPreCurrent_4uA;
318 userConfig->preResistor = kTSI_MutualPreResistor_4k;
319 userConfig->senseResistor = kTSI_MutualSenseResistor_10k;
320 userConfig->boostCurrent = kTSI_MutualSenseBoostCurrent_0uA;
321 userConfig->txDriveMode = kTSI_MutualTxDriveModeOption_0;
322 userConfig->pmosLeftCurrent = kTSI_MutualPmosCurrentMirrorLeft_32;
323 userConfig->pmosRightCurrent = kTSI_MutualPmosCurrentMirrorRight_1;
324 userConfig->enableNmosMirror = true;
325 userConfig->nmosCurrent = kTSI_MutualNmosCurrentMirror_1;
326 }
327
328 /*!
329 * brief Hardware base counter value for calibration.
330 *
331 * details Calibrate the peripheral to fetch the initial counter value of
332 * the enabled channels.
333 * This API is mostly used at initial application setup, it shall be called
334 * after the \ref TSI_Init API, then user can use the calibrated
335 * counter values to setup applications(such as to determine
336 * under which counter value we can confirm a touch event occurs).
337 *
338 * param base TSI peripheral base address.
339 * param calBuff Data buffer that store the calibrated counter value.
340 * return none
341 * note This API is mainly used for self-cap mode;
342 * note The calibration work in mutual-cap mode shall be done in applications due to different board layout.
343 *
344 */
TSI_SelfCapCalibrate(TSI_Type * base,tsi_calibration_data_t * calBuff)345 void TSI_SelfCapCalibrate(TSI_Type *base, tsi_calibration_data_t *calBuff)
346 {
347 assert(calBuff != NULL);
348
349 uint8_t i = 0U;
350 bool is_int_enabled = false;
351
352 if ((bool)(base->GENCS & TSI_GENCS_TSIIEN_MASK))
353 {
354 is_int_enabled = true;
355 TSI_DisableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
356 }
357 for (i = 0U; i < (uint8_t)FSL_FEATURE_TSI_CHANNEL_COUNT; i++)
358 {
359 TSI_SetSelfCapMeasuredChannel(base, i);
360 TSI_StartSoftwareTrigger(base);
361 while (!(bool)((TSI_GetStatusFlags(base) & (uint32_t)kTSI_EndOfScanFlag)))
362 {
363 }
364 calBuff->calibratedData[i] = TSI_GetCounter(base);
365 TSI_ClearStatusFlags(base, (uint32_t)kTSI_EndOfScanFlag);
366 }
367 if (is_int_enabled)
368 {
369 TSI_EnableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
370 }
371 }
372
373 /*!
374 * brief Enables TSI interrupt requests.
375 * param base TSI peripheral base address.
376 * param mask interrupt source
377 * The parameter can be combination of the following source if defined:
378 * arg kTSI_GlobalInterruptEnable
379 * arg kTSI_EndOfScanInterruptEnable
380 * arg kTSI_OutOfRangeInterruptEnable
381 */
TSI_EnableInterrupts(TSI_Type * base,uint32_t mask)382 void TSI_EnableInterrupts(TSI_Type *base, uint32_t mask)
383 {
384 uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
385
386 if ((bool)(mask & (uint32_t)kTSI_GlobalInterruptEnable))
387 {
388 regValue |= TSI_GENCS_TSIIEN_MASK;
389 }
390 if ((bool)(mask & (uint32_t)kTSI_OutOfRangeInterruptEnable))
391 {
392 regValue &= (~TSI_GENCS_ESOR_MASK);
393 }
394 if ((bool)(mask & (uint32_t)kTSI_EndOfScanInterruptEnable))
395 {
396 regValue |= TSI_GENCS_ESOR_MASK;
397 }
398
399 base->GENCS = regValue; /* write value to register */
400 }
401
402 /*!
403 * brief Disables TSI interrupt requests.
404 * param base TSI peripheral base address.
405 * param mask interrupt source
406 * The parameter can be combination of the following source if defined:
407 * arg kTSI_GlobalInterruptEnable
408 * arg kTSI_EndOfScanInterruptEnable
409 * arg kTSI_OutOfRangeInterruptEnable
410 */
TSI_DisableInterrupts(TSI_Type * base,uint32_t mask)411 void TSI_DisableInterrupts(TSI_Type *base, uint32_t mask)
412 {
413 uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
414
415 if ((bool)(mask & (uint32_t)kTSI_GlobalInterruptEnable))
416 {
417 regValue &= (~TSI_GENCS_TSIIEN_MASK);
418 }
419 if ((bool)(mask & (uint32_t)kTSI_OutOfRangeInterruptEnable))
420 {
421 regValue |= TSI_GENCS_ESOR_MASK;
422 }
423 if ((bool)(mask & (uint32_t)kTSI_EndOfScanInterruptEnable))
424 {
425 regValue &= (~TSI_GENCS_ESOR_MASK);
426 }
427
428 base->GENCS = regValue; /* write value to register */
429 }
430
431 /*!
432 * brief Clear interrupt flag.
433 *
434 * This function clear tsi interrupt flag,
435 * automatically cleared flags can not be cleared by this function.
436 *
437 * param base TSI peripheral base address.
438 * param mask The status flags to clear.
439 */
TSI_ClearStatusFlags(TSI_Type * base,uint32_t mask)440 void TSI_ClearStatusFlags(TSI_Type *base, uint32_t mask)
441 {
442 uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
443
444 if ((bool)(mask & (uint32_t)kTSI_EndOfScanFlag))
445 {
446 regValue |= TSI_GENCS_EOSF_MASK;
447 }
448 if ((bool)(mask & (uint32_t)kTSI_OutOfRangeFlag))
449 {
450 regValue |= TSI_GENCS_OUTRGF_MASK;
451 }
452
453 base->GENCS = regValue; /* write value to register */
454 }
455