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