1 /*
2 * Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #include "fsl_tsi_v4.h"
9
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.tsi_v4"
13 #endif
14
15 /*!
16 * brief Initializes hardware.
17 *
18 * details Initializes the peripheral to the targeted state specified by parameter configuration,
19 * such as sets prescalers, number of scans, clocks, delta voltage
20 * series resistor, filter bits, reference, and electrode charge current and threshold.
21 * param base TSI peripheral base address.
22 * param config Pointer to TSI module configuration structure.
23 * return none
24 */
TSI_Init(TSI_Type * base,const tsi_config_t * config)25 void TSI_Init(TSI_Type *base, const tsi_config_t *config)
26 {
27 assert(config != NULL);
28
29 bool is_module_enabled = false;
30 bool is_int_enabled = false;
31
32 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
33 CLOCK_EnableClock(kCLOCK_Tsi0);
34 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
35 if ((bool)(base->GENCS & TSI_GENCS_TSIEN_MASK))
36 {
37 is_module_enabled = true;
38 TSI_EnableModule(base, false);
39 }
40 if ((bool)(base->GENCS & TSI_GENCS_TSIIEN_MASK))
41 {
42 is_int_enabled = true;
43 TSI_DisableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
44 }
45
46 if (config->mode == kTSI_AnalogModeSel_Capacitive)
47 {
48 TSI_SetHighThreshold(base, config->thresh);
49 TSI_SetLowThreshold(base, config->thresl);
50 TSI_SetElectrodeOSCPrescaler(base, config->prescaler);
51 TSI_SetReferenceChargeCurrent(base, config->refchrg);
52 TSI_SetElectrodeChargeCurrent(base, config->extchrg);
53 TSI_SetNumberOfScans(base, config->nscn);
54 TSI_SetAnalogMode(base, config->mode);
55 TSI_SetOscVoltageRails(base, config->dvolt);
56 }
57 else /* For noise modes */
58 {
59 TSI_SetHighThreshold(base, config->thresh);
60 TSI_SetLowThreshold(base, config->thresl);
61 TSI_SetElectrodeOSCPrescaler(base, config->prescaler);
62 TSI_SetReferenceChargeCurrent(base, config->refchrg);
63 TSI_SetNumberOfScans(base, config->nscn);
64 TSI_SetAnalogMode(base, config->mode);
65 TSI_SetOscVoltageRails(base, config->dvolt);
66 TSI_SetElectrodeSeriesResistor(base, config->resistor);
67 TSI_SetFilterBits(base, config->filter);
68 }
69
70 if (is_module_enabled)
71 {
72 TSI_EnableModule(base, true);
73 }
74 if (is_int_enabled)
75 {
76 TSI_EnableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
77 }
78 }
79
80 /*!
81 * brief De-initializes hardware.
82 *
83 * details De-initializes the peripheral to default state.
84 *
85 * param base TSI peripheral base address.
86 * return none
87 */
TSI_Deinit(TSI_Type * base)88 void TSI_Deinit(TSI_Type *base)
89 {
90 base->GENCS = 0U;
91 base->DATA = 0U;
92 base->TSHD = 0U;
93 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
94 CLOCK_DisableClock(kCLOCK_Tsi0);
95 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
96 }
97
98 /*!
99 * brief Gets the TSI normal mode user configuration structure.
100 * This interface sets userConfig structure to a default value. The configuration structure only
101 * includes the settings for the whole TSI.
102 * The user configure is set to these values:
103 * code
104 userConfig->prescaler = kTSI_ElecOscPrescaler_2div;
105 userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA;
106 userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA;
107 userConfig->nscn = kTSI_ConsecutiveScansNumber_10time;
108 userConfig->mode = kTSI_AnalogModeSel_Capacitive;
109 userConfig->dvolt = kTSI_OscVolRailsOption_0;
110 userConfig->thresh = 0U;
111 userConfig->thresl = 0U;
112 endcode
113 *
114 * param userConfig Pointer to the TSI user configuration structure.
115 */
TSI_GetNormalModeDefaultConfig(tsi_config_t * userConfig)116 void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig)
117 {
118 /* Initializes the configure structure to zero. */
119 (void)memset(userConfig, 0, sizeof(*userConfig));
120
121 userConfig->thresh = 0U;
122 userConfig->thresl = 0U;
123 userConfig->prescaler = kTSI_ElecOscPrescaler_2div;
124 userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA;
125 userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA;
126 userConfig->nscn = kTSI_ConsecutiveScansNumber_5time;
127 userConfig->mode = kTSI_AnalogModeSel_Capacitive;
128 userConfig->dvolt = kTSI_OscVolRailsOption_0;
129 }
130
131 /*!
132 * brief Gets the TSI low power mode default user configuration structure.
133 * This interface sets userConfig structure to a default value. The configuration structure only
134 * includes the settings for the whole TSI.
135 * The user configure is set to these values:
136 * code
137 userConfig->prescaler = kTSI_ElecOscPrescaler_2div;
138 userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA;
139 userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA;
140 userConfig->nscn = kTSI_ConsecutiveScansNumber_10time;
141 userConfig->mode = kTSI_AnalogModeSel_Capacitive;
142 userConfig->dvolt = kTSI_OscVolRailsOption_0;
143 userConfig->thresh = 400U;
144 userConfig->thresl = 0U;
145 endcode
146 *
147 * param userConfig Pointer to the TSI user configuration structure.
148 */
TSI_GetLowPowerModeDefaultConfig(tsi_config_t * userConfig)149 void TSI_GetLowPowerModeDefaultConfig(tsi_config_t *userConfig)
150 {
151 /* Initializes the configure structure to zero. */
152 (void)memset(userConfig, 0, sizeof(*userConfig));
153
154 userConfig->thresh = 400U;
155 userConfig->thresl = 0U;
156 userConfig->prescaler = kTSI_ElecOscPrescaler_2div;
157 userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA;
158 userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA;
159 userConfig->nscn = kTSI_ConsecutiveScansNumber_5time;
160 userConfig->mode = kTSI_AnalogModeSel_Capacitive;
161 userConfig->dvolt = kTSI_OscVolRailsOption_0;
162 }
163
164 /*!
165 * brief Hardware calibration.
166 *
167 * details Calibrates the peripheral to fetch the initial counter value of
168 * the enabled electrodes.
169 * This API is mostly used at initial application setup. Call
170 * this function after the \ref TSI_Init API and use the calibrated
171 * counter values to set up applications (such as to determine
172 * under which counter value we can confirm a touch event occurs).
173 *
174 * param base TSI peripheral base address.
175 * param calBuff Data buffer that store the calibrated counter value.
176 * return none
177 *
178 */
TSI_Calibrate(TSI_Type * base,tsi_calibration_data_t * calBuff)179 void TSI_Calibrate(TSI_Type *base, tsi_calibration_data_t *calBuff)
180 {
181 assert(calBuff != NULL);
182
183 uint8_t i = 0U;
184 bool is_int_enabled = false;
185
186 if ((bool)(base->GENCS & TSI_GENCS_TSIIEN_MASK))
187 {
188 is_int_enabled = true;
189 TSI_DisableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
190 }
191 for (i = 0U; i < (uint8_t)FSL_FEATURE_TSI_CHANNEL_COUNT; i++)
192 {
193 TSI_SetMeasuredChannelNumber(base, i);
194 TSI_StartSoftwareTrigger(base);
195 while (0UL == (TSI_GetStatusFlags(base) & (uint32_t)kTSI_EndOfScanFlag))
196 {
197 }
198 calBuff->calibratedData[i] = TSI_GetCounter(base);
199 TSI_ClearStatusFlags(base, (uint32_t)kTSI_EndOfScanFlag);
200 }
201 if (is_int_enabled)
202 {
203 TSI_EnableInterrupts(base, (uint32_t)kTSI_GlobalInterruptEnable);
204 }
205 }
206
207 /*!
208 * brief Enables the TSI interrupt requests.
209 * param base TSI peripheral base address.
210 * param mask interrupt source
211 * The parameter can be combination of the following source if defined:
212 * arg kTSI_GlobalInterruptEnable
213 * arg kTSI_EndOfScanInterruptEnable
214 * arg kTSI_OutOfRangeInterruptEnable
215 */
TSI_EnableInterrupts(TSI_Type * base,uint32_t mask)216 void TSI_EnableInterrupts(TSI_Type *base, uint32_t mask)
217 {
218 uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
219
220 if (0UL != (mask & (uint32_t)kTSI_GlobalInterruptEnable))
221 {
222 regValue |= TSI_GENCS_TSIIEN_MASK;
223 }
224 if (0UL != (mask & (uint32_t)kTSI_OutOfRangeInterruptEnable))
225 {
226 regValue &= (~TSI_GENCS_ESOR_MASK);
227 }
228 if (0UL != (mask & (uint32_t)kTSI_EndOfScanInterruptEnable))
229 {
230 regValue |= TSI_GENCS_ESOR_MASK;
231 }
232
233 base->GENCS = regValue; /* write value to register */
234 }
235
236 /*!
237 * brief Disables the TSI interrupt requests.
238 * param base TSI peripheral base address.
239 * param mask interrupt source
240 * The parameter can be combination of the following source if defined:
241 * arg kTSI_GlobalInterruptEnable
242 * arg kTSI_EndOfScanInterruptEnable
243 * arg kTSI_OutOfRangeInterruptEnable
244 */
TSI_DisableInterrupts(TSI_Type * base,uint32_t mask)245 void TSI_DisableInterrupts(TSI_Type *base, uint32_t mask)
246 {
247 uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
248
249 if (0UL != (mask & (uint32_t)kTSI_GlobalInterruptEnable))
250 {
251 regValue &= (~TSI_GENCS_TSIIEN_MASK);
252 }
253 if (0UL != (mask & (uint32_t)kTSI_OutOfRangeInterruptEnable))
254 {
255 regValue |= TSI_GENCS_ESOR_MASK;
256 }
257 if (0UL != (mask & (uint32_t)kTSI_EndOfScanInterruptEnable))
258 {
259 regValue &= (~TSI_GENCS_ESOR_MASK);
260 }
261
262 base->GENCS = regValue; /* write value to register */
263 }
264
265 /*!
266 * brief Clears the interrupt flag.
267 *
268 * This function clears the TSI interrupt flag,
269 * automatically cleared flags can't be cleared by this function.
270 *
271 * param base TSI peripheral base address.
272 * param mask The status flags to clear.
273 */
TSI_ClearStatusFlags(TSI_Type * base,uint32_t mask)274 void TSI_ClearStatusFlags(TSI_Type *base, uint32_t mask)
275 {
276 uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
277
278 if (0UL != (mask & (uint32_t)kTSI_EndOfScanFlag))
279 {
280 regValue |= TSI_GENCS_EOSF_MASK;
281 }
282 if (0UL != (mask & (uint32_t)kTSI_OutOfRangeFlag))
283 {
284 regValue |= TSI_GENCS_OUTRGF_MASK;
285 }
286
287 base->GENCS = regValue; /* write value to register */
288 }
289