blob: c299c90f63320a434aafc790a0ae0dd5c7b1ac4f [file] [log] [blame]
/*
* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_tsi_v4.h"
void TSI_Init(TSI_Type *base, const tsi_config_t *config)
{
assert(config != NULL);
bool is_module_enabled = false;
bool is_int_enabled = false;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Tsi0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
if (base->GENCS & TSI_GENCS_TSIEN_MASK)
{
is_module_enabled = true;
TSI_EnableModule(base, false);
}
if (base->GENCS & TSI_GENCS_TSIIEN_MASK)
{
is_int_enabled = true;
TSI_DisableInterrupts(base, kTSI_GlobalInterruptEnable);
}
if(config->mode == kTSI_AnalogModeSel_Capacitive)
{
TSI_SetHighThreshold(base, config->thresh);
TSI_SetLowThreshold(base, config->thresl);
TSI_SetElectrodeOSCPrescaler(base, config->prescaler);
TSI_SetReferenceChargeCurrent(base, config->refchrg);
TSI_SetElectrodeChargeCurrent(base, config->extchrg);
TSI_SetNumberOfScans(base, config->nscn);
TSI_SetAnalogMode(base, config->mode);
TSI_SetOscVoltageRails(base, config->dvolt);
}
else /* For noise modes */
{
TSI_SetHighThreshold(base, config->thresh);
TSI_SetLowThreshold(base, config->thresl);
TSI_SetElectrodeOSCPrescaler(base, config->prescaler);
TSI_SetReferenceChargeCurrent(base, config->refchrg);
TSI_SetNumberOfScans(base, config->nscn);
TSI_SetAnalogMode(base, config->mode);
TSI_SetOscVoltageRails(base, config->dvolt);
TSI_SetElectrodeSeriesResistor(base, config->resistor);
TSI_SetFilterBits(base, config->filter);
}
if (is_module_enabled)
{
TSI_EnableModule(base, true);
}
if (is_int_enabled)
{
TSI_EnableInterrupts(base, kTSI_GlobalInterruptEnable);
}
}
void TSI_Deinit(TSI_Type *base)
{
base->GENCS = 0U;
base->DATA = 0U;
base->TSHD = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(kCLOCK_Tsi0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig)
{
userConfig->thresh = 0U;
userConfig->thresl = 0U;
userConfig->prescaler = kTSI_ElecOscPrescaler_2div;
userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA;
userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA;
userConfig->nscn = kTSI_ConsecutiveScansNumber_5time;
userConfig->mode = kTSI_AnalogModeSel_Capacitive;
userConfig->dvolt = kTSI_OscVolRailsOption_0;
}
void TSI_GetLowPowerModeDefaultConfig(tsi_config_t *userConfig)
{
userConfig->thresh = 400U;
userConfig->thresl = 0U;
userConfig->prescaler = kTSI_ElecOscPrescaler_2div;
userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA;
userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA;
userConfig->nscn = kTSI_ConsecutiveScansNumber_5time;
userConfig->mode = kTSI_AnalogModeSel_Capacitive;
userConfig->dvolt = kTSI_OscVolRailsOption_0;
}
void TSI_Calibrate(TSI_Type *base, tsi_calibration_data_t *calBuff)
{
assert(calBuff != NULL);
uint8_t i = 0U;
bool is_int_enabled = false;
if (base->GENCS & TSI_GENCS_TSIIEN_MASK)
{
is_int_enabled = true;
TSI_DisableInterrupts(base, kTSI_GlobalInterruptEnable);
}
for (i = 0U; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++)
{
TSI_SetMeasuredChannelNumber(base, i);
TSI_StartSoftwareTrigger(base);
while (!(TSI_GetStatusFlags(base) & kTSI_EndOfScanFlag))
{
}
calBuff->calibratedData[i] = TSI_GetCounter(base);
TSI_ClearStatusFlags(base, kTSI_EndOfScanFlag);
}
if (is_int_enabled)
{
TSI_EnableInterrupts(base, kTSI_GlobalInterruptEnable);
}
}
void TSI_EnableInterrupts(TSI_Type *base, uint32_t mask)
{
uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
if (mask & kTSI_GlobalInterruptEnable)
{
regValue |= TSI_GENCS_TSIIEN_MASK;
}
if (mask & kTSI_OutOfRangeInterruptEnable)
{
regValue &= (~TSI_GENCS_ESOR_MASK);
}
if (mask & kTSI_EndOfScanInterruptEnable)
{
regValue |= TSI_GENCS_ESOR_MASK;
}
base->GENCS = regValue; /* write value to register */
}
void TSI_DisableInterrupts(TSI_Type *base, uint32_t mask)
{
uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
if (mask & kTSI_GlobalInterruptEnable)
{
regValue &= (~TSI_GENCS_TSIIEN_MASK);
}
if (mask & kTSI_OutOfRangeInterruptEnable)
{
regValue |= TSI_GENCS_ESOR_MASK;
}
if (mask & kTSI_EndOfScanInterruptEnable)
{
regValue &= (~TSI_GENCS_ESOR_MASK);
}
base->GENCS = regValue; /* write value to register */
}
void TSI_ClearStatusFlags(TSI_Type *base, uint32_t mask)
{
uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK);
if (mask & kTSI_EndOfScanFlag)
{
regValue |= TSI_GENCS_EOSF_MASK;
}
if (mask & kTSI_OutOfRangeFlag)
{
regValue |= TSI_GENCS_OUTRGF_MASK;
}
base->GENCS = regValue; /* write value to register */
}