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