| /* |
| * 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 */ |
| } |