/** ****************************************************************************** * @file tsl_touchkey.c * @author MCD Application Team * @version V1.4.4 * @date 31-March-2014 * @brief This file contains all functions to manage TouchKey sensors. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "tsl_touchkey.h" #include "tsl_globals.h" #if TSLPRM_TOTAL_TKEYS > 0 /* Private typedefs ----------------------------------------------------------*/ /* Private defines -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ #define THIS_MEAS TSL_Globals.This_TKey->p_ChD->Meas #define THIS_DELTA TSL_Globals.This_TKey->p_ChD->Delta #define THIS_REF TSL_Globals.This_TKey->p_ChD->Ref #define THIS_REFREST TSL_Globals.This_TKey->p_ChD->RefRest #define THIS_CHANNEL_DATA TSL_Globals.This_TKey->p_ChD #define THIS_ACQ_STATUS TSL_Globals.This_TKey->p_ChD->Flags.AcqStatus #define THIS_OBJ_STATUS TSL_Globals.This_TKey->p_ChD->Flags.ObjStatus #define THIS_DATA_READY TSL_Globals.This_TKey->p_ChD->Flags.DataReady #define THIS_STATEID TSL_Globals.This_TKey->p_Data->StateId #define THIS_CHANGE TSL_Globals.This_TKey->p_Data->Change #define THIS_COUNTER_DEB TSL_Globals.This_TKey->p_Data->CounterDebounce #define THIS_COUNTER_DTO TSL_Globals.This_TKey->p_Data->CounterDTO #define THIS_DXSLOCK TSL_Globals.This_TKey->p_Data->DxSLock #define THIS_PROXIN_TH TSL_Globals.This_TKey->p_Param->ProxInTh #define THIS_PROXOUT_TH TSL_Globals.This_TKey->p_Param->ProxOutTh #define THIS_DETECTIN_TH TSL_Globals.This_TKey->p_Param->DetectInTh #define THIS_DETECTOUT_TH TSL_Globals.This_TKey->p_Param->DetectOutTh #define THIS_CALIB_TH TSL_Globals.This_TKey->p_Param->CalibTh #define THIS_COUNTER_DEB_CALIB TSL_Globals.This_TKey->p_Param->CounterDebCalib #define THIS_COUNTER_DEB_PROX TSL_Globals.This_TKey->p_Param->CounterDebProx #define THIS_COUNTER_DEB_DETECT TSL_Globals.This_TKey->p_Param->CounterDebDetect #define THIS_COUNTER_DEB_RELEASE TSL_Globals.This_TKey->p_Param->CounterDebRelease #define THIS_COUNTER_DEB_ERROR TSL_Globals.This_TKey->p_Param->CounterDebError #if TSLPRM_DTO > 0 #define DTO_GET_TIME {TSL_tkey_DTOGetTime();} #else #define DTO_GET_TIME #endif #if TSLPRM_COEFF_TH > 0 #define TEST_DELTA(OPER,TH) (THIS_DELTA OPER (uint16_t)((uint16_t)TH << TSLPRM_COEFF_TH)) #define TEST_DELTA_N(OPER,TH) (THIS_DELTA OPER -((uint16_t)((uint16_t)TH << TSLPRM_COEFF_TH))) #define TEST_DELTA_NEGATIVE {if (THIS_DELTA < 0) {return;}} #else #define TEST_DELTA(OPER,TH) (THIS_DELTA OPER TH) #define TEST_DELTA_N(OPER,TH) (THIS_DELTA OPER -(TH)) #define TEST_DELTA_NEGATIVE #endif /* Private variables ---------------------------------------------------------*/ static TSL_tNb_T CalibDiv; /* Private functions prototype -----------------------------------------------*/ void TSL_tkey_DTOGetTime(void); //============================================================================== // "Object methods" functions //============================================================================== /** * @brief Init parameters with default values from configuration file * @param None * @retval None */ void TSL_tkey_Init(void) { // Thresholds #if TSLPRM_USE_PROX > 0 THIS_PROXIN_TH = TSLPRM_TKEY_PROX_IN_TH; THIS_PROXOUT_TH = TSLPRM_TKEY_PROX_OUT_TH; #endif THIS_DETECTIN_TH = TSLPRM_TKEY_DETECT_IN_TH; THIS_DETECTOUT_TH = TSLPRM_TKEY_DETECT_OUT_TH; THIS_CALIB_TH = TSLPRM_TKEY_CALIB_TH; // Debounce counters THIS_COUNTER_DEB_CALIB = TSLPRM_DEBOUNCE_CALIB; #if TSLPRM_USE_PROX > 0 THIS_COUNTER_DEB_PROX = TSLPRM_DEBOUNCE_PROX; #endif THIS_COUNTER_DEB_DETECT = TSLPRM_DEBOUNCE_DETECT; THIS_COUNTER_DEB_RELEASE = TSLPRM_DEBOUNCE_RELEASE; THIS_COUNTER_DEB_ERROR = TSLPRM_DEBOUNCE_ERROR; // Initial state TSL_tkey_SetStateCalibration(TSLPRM_CALIB_DELAY); } /** * @brief Process the State Machine * @param None * @retval None */ void TSL_tkey_Process(void) { TSL_StateId_enum_T prev_state_id; if ((THIS_DATA_READY != 0) || (THIS_STATEID == TSL_STATEID_OFF)) { THIS_DATA_READY = TSL_DATA_NOT_READY; // The new data is processed prev_state_id = THIS_STATEID; #if TSLPRM_TOTAL_TOUCHKEYS > 0 if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEY) { // Launch the TKey state function TSL_Globals.This_TKey->p_SM[THIS_STATEID].StateFunc(); } #endif #if TSLPRM_TOTAL_TOUCHKEYS_B > 0 if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEYB) { // Launch the TSL_Params state function TSL_Params.p_TKeySM[THIS_STATEID].StateFunc(); } #endif // Check if the new state has changed if (THIS_STATEID == prev_state_id) { THIS_CHANGE = TSL_STATE_NOT_CHANGED; } else { THIS_CHANGE = TSL_STATE_CHANGED; } #if TSLPRM_USE_DXS > 0 if (THIS_STATEID != TSL_STATEID_DETECT) { THIS_DXSLOCK = TSL_FALSE; } if (THIS_STATEID == TSL_STATEID_TOUCH) { THIS_STATEID = TSL_STATEID_DETECT; } #endif } } //============================================================================== // Utility functions //============================================================================== /** * @brief Go in Calibration state * @param[in] delay Delay before calibration starts (stabilization of noise filter) * @retval None */ void TSL_tkey_SetStateCalibration(TSL_tCounter_T delay) { THIS_STATEID = TSL_STATEID_CALIB; THIS_CHANGE = TSL_STATE_CHANGED; THIS_OBJ_STATUS = TSL_OBJ_STATUS_ON; switch (TSL_Params.NbCalibSamples) { case 4: CalibDiv = 2; break; case 16: CalibDiv = 4; break; default: TSL_Params.NbCalibSamples = 8; CalibDiv = 3; break; } // If a noise filter is used, the counter must be initialized to a value // different from 0 in order to stabilize the filter. THIS_COUNTER_DEB = (TSL_tCounter_T)(delay + (TSL_tCounter_T)TSL_Params.NbCalibSamples); THIS_REF = 0; } /** * @brief Go in Off state with sensor "off" * @param None * @retval None */ void TSL_tkey_SetStateOff(void) { THIS_STATEID = TSL_STATEID_OFF; THIS_CHANGE = TSL_STATE_CHANGED; THIS_OBJ_STATUS = TSL_OBJ_STATUS_OFF; } #if !defined(TSLPRM_STM8TL5X) && !defined(STM8TL5X) /** * @brief Go in Off state with sensor in "Burst mode only" * @param None * @retval None */ void TSL_tkey_SetStateBurstOnly(void) { THIS_STATEID = TSL_STATEID_OFF; THIS_CHANGE = TSL_STATE_CHANGED; THIS_OBJ_STATUS = TSL_OBJ_STATUS_BURST_ONLY; } #endif /** * @brief Return the current state identifier * @param None * @retval State id */ TSL_StateId_enum_T TSL_tkey_GetStateId(void) { return(THIS_STATEID); } /** * @brief Return the current state mask * @param None * @retval State mask */ TSL_StateMask_enum_T TSL_tkey_GetStateMask(void) { TSL_StateMask_enum_T state_mask = TSL_STATEMASK_UNKNOWN; #if TSLPRM_TOTAL_TOUCHKEYS > 0 if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEY) { state_mask = TSL_Globals.This_TKey->p_SM[THIS_STATEID].StateMask; } #endif #if TSLPRM_TOTAL_TOUCHKEYS_B > 0 if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEYB) { state_mask = TSL_Params.p_TKeySM[THIS_STATEID].StateMask; } #endif return state_mask; } /** * @brief Return the Change flag * @param None * @retval Change flag status */ TSL_tNb_T TSL_tkey_IsChanged(void) { return(THIS_CHANGE); } //============================================================================== // State machine functions //============================================================================== #if TSLPRM_USE_PROX > 0 /** * @brief Debounce Release processing (previous state = Proximity) * @param None * @retval None */ void TSL_tkey_DebReleaseProxStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_PROX; // Go back to the previous state } else // Acquisition is OK or has NOISE { if (THIS_DELTA > THIS_PROXOUT_TH) { THIS_STATEID = TSL_STATEID_PROX; // Go back to the previous state } else { if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } // else stay in Debounce Release } } } #endif // if TSLPRM_USE_PROX > 0 /** * @brief Debounce Release processing (previous state = Detect) * @param None * @retval None */ void TSL_tkey_DebReleaseDetectStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_DETECT; // Go back to the previous state } else // Acquisition is OK or has NOISE { if TEST_DELTA(>, THIS_DETECTOUT_TH) { TEST_DELTA_NEGATIVE; THIS_STATEID = TSL_STATEID_DETECT; } else { #if TSLPRM_USE_PROX > 0 if (THIS_DELTA > THIS_PROXOUT_TH) { THIS_STATEID = TSL_STATEID_PROX; return; } #endif if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } // else stay in Debounce Release } } } /** * @brief Debounce Release processing (previous state = Touch) * Same as Debounce Release Detect processing * @param None * @retval None */ void TSL_tkey_DebReleaseTouchStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_TOUCH; // Go back to the previous state } else // Acquisition is OK or has NOISE { if TEST_DELTA(>, THIS_DETECTOUT_TH) { TEST_DELTA_NEGATIVE; THIS_STATEID = TSL_STATEID_TOUCH; } else { #if TSLPRM_USE_PROX > 0 if (THIS_DELTA > THIS_PROXOUT_TH) { THIS_STATEID = TSL_STATEID_PROX; return; } #endif if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } // else stay in Debounce Release } } } /** * @brief Release state processing * @param None * @retval None */ void TSL_tkey_ReleaseStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_ERROR; } else { THIS_STATEID = TSL_STATEID_DEB_ERROR_RELEASE; } } else // Acquisition is OK or has NOISE { if TEST_DELTA(>=, THIS_DETECTIN_TH) { TEST_DELTA_NEGATIVE; THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_DETECT; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_DETECT; } return; } #if TSLPRM_USE_PROX > 0 if (THIS_DELTA >= THIS_PROXIN_TH) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_PROX; } return; } #endif // Check delta for re-calibration // Warning: the threshold value is inverted in the macro if TEST_DELTA_N(<=, THIS_CALIB_TH) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_CALIB; if (THIS_COUNTER_DEB == 0) { TSL_tkey_SetStateCalibration(0); } else { THIS_STATEID = TSL_STATEID_DEB_CALIB; } } } } /** * @brief Debounce Calibration processing (previous state = Release) * @param None * @retval None */ void TSL_tkey_DebCalibrationStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_RELEASE; // Go back to the previous state } else // Acquisition is OK or has NOISE { // Still below recalibration threshold // Warning: the threshold value is inverted in the macro if TEST_DELTA_N(<=, THIS_CALIB_TH) { if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { TSL_tkey_SetStateCalibration(0); } // else stay in Debounce Calibration } else // Go back to previous state { THIS_STATEID = TSL_STATEID_RELEASE; } } } /** * @brief Calibration state processing * @param None * @retval None */ void TSL_tkey_CalibrationStateProcess(void) { TSL_tMeas_T new_meas; #if TSLPRM_CALIB_DELAY > 0 // Noise filter stabilization time if (THIS_COUNTER_DEB > (TSL_tCounter_T)TSL_Params.NbCalibSamples) { THIS_COUNTER_DEB--; return; // Skip the sample } #endif if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_ERROR; } else { THIS_STATEID = TSL_STATEID_DEB_ERROR_CALIB; } } else // Acquisition is OK or has NOISE { // Get the new measure or Calculate it #if TSLPRM_USE_MEAS > 0 new_meas = THIS_MEAS; #else // Calculate it new_meas = TSL_acq_ComputeMeas(THIS_REF, THIS_DELTA); #endif // Verify the first Reference value if (THIS_COUNTER_DEB == (TSL_tCounter_T)TSL_Params.NbCalibSamples) { if (TSL_acq_TestFirstReferenceIsValid(THIS_CHANNEL_DATA, new_meas)) { THIS_REF = new_meas; } else { THIS_REF = 0; return; } } else { // Add the measure in temporary Reference THIS_REF += new_meas; // Check reference overflow if (THIS_REF < new_meas) { THIS_REF = 0; // Suppress the bad reference THIS_STATEID = TSL_STATEID_ERROR; return; } } // Check that we have all the needed measurements if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { // Divide temporary Reference by the number of samples THIS_REF >>= CalibDiv; THIS_REFREST = 0; THIS_DELTA = 0; THIS_STATEID = TSL_STATEID_RELEASE; } } } #if TSLPRM_USE_PROX > 0 /** * @brief Debounce Proximity processing (previous state = Release) * @param None * @retval None */ void TSL_tkey_DebProxStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_RELEASE; } else // Acquisition is OK or has NOISE { if TEST_DELTA(>=, THIS_DETECTIN_TH) { TEST_DELTA_NEGATIVE; THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_DETECT; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_DETECT; } return; } if (THIS_DELTA >= THIS_PROXIN_TH) { if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } // else stay in Debounce Proximity } else { THIS_STATEID = TSL_STATEID_RELEASE; } } } #endif #if TSLPRM_USE_PROX > 0 /** * @brief Debounce Proximity processing (previous state = Detect) * @param None * @retval None */ void TSL_tkey_DebProxDetectStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_DETECT; } else // Acquisition is OK or has NOISE { if TEST_DELTA(>, THIS_DETECTOUT_TH) { TEST_DELTA_NEGATIVE; THIS_STATEID = TSL_STATEID_DETECT; return; } if (THIS_DELTA > THIS_PROXOUT_TH) { if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } // else stay in Debounce Proximity } else { THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } else { THIS_STATEID = TSL_STATEID_DEB_RELEASE_DETECT; } } } } #endif #if TSLPRM_USE_PROX > 0 /** * @brief Debounce Proximity processing (previous state = Touch) * @param None * @retval None */ void TSL_tkey_DebProxTouchStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_TOUCH; } else // Acquisition is OK or has NOISE { if TEST_DELTA(>, THIS_DETECTOUT_TH) { TEST_DELTA_NEGATIVE; THIS_STATEID = TSL_STATEID_TOUCH; return; } if (THIS_DELTA > THIS_PROXOUT_TH) { if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } // else stay in Debounce Proximity } else { THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } else { THIS_STATEID = TSL_STATEID_DEB_RELEASE_TOUCH; } } } } #endif #if TSLPRM_USE_PROX > 0 /** * @brief Proximity state processing * @param None * @retval None */ void TSL_tkey_ProxStateProcess(void) { #if TSLPRM_DTO > 0 TSL_tTick_sec_T tick_detected; #endif if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_ERROR; } else { THIS_STATEID = TSL_STATEID_DEB_ERROR_PROX; } } else // Acquisition is OK or has NOISE { if TEST_DELTA(>=, THIS_DETECTIN_TH) { TEST_DELTA_NEGATIVE; THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_DETECT; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_DETECT; } return; } if (THIS_DELTA <= THIS_PROXOUT_TH) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } else { THIS_STATEID = TSL_STATEID_DEB_RELEASE_PROX; } return; } // Stay in Proximity state #if TSLPRM_DTO > 0 //------------------------------------ // Detection Time Out (DTO) processing //------------------------------------ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64)) { tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved // Enter in calibration state if the DTO duration has elapsed if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK) { TSL_tkey_SetStateCalibration(0); } } #endif } } #endif /** * @brief Debounce Detect processing (previous state = Release or Proximity) * @param None * @retval None */ void TSL_tkey_DebDetectStateProcess(void) { if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_STATEID = TSL_STATEID_RELEASE; } else // Acquisition is OK or has NOISE { if TEST_DELTA(>=, THIS_DETECTIN_TH) { TEST_DELTA_NEGATIVE; if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_DETECT; DTO_GET_TIME; // Take current time for DTO processing } // else stay in Debounce Detect } else { #if TSLPRM_USE_PROX > 0 if (THIS_DELTA >= THIS_PROXIN_TH) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_PROX; } } else { THIS_STATEID = TSL_STATEID_RELEASE; } #else THIS_STATEID = TSL_STATEID_RELEASE; #endif } } } /** * @brief Detect state processing * @param None * @retval None */ void TSL_tkey_DetectStateProcess(void) { #if TSLPRM_DTO > 0 TSL_tTick_sec_T tick_detected; #endif if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_ERROR; } else { THIS_STATEID = TSL_STATEID_DEB_ERROR_DETECT; } } else // Acquisition is OK or has NOISE { if TEST_DELTA(>, THIS_DETECTOUT_TH) { TEST_DELTA_NEGATIVE; #if TSLPRM_DTO > 0 //------------------------------------ // Detection Time Out (DTO) processing //------------------------------------ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64)) { tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved // Enter in calibration state if the DTO duration has elapsed if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK) { TSL_tkey_SetStateCalibration(0); } } #endif return; // Normal operation, stay in Detect state } #if TSLPRM_USE_PROX > 0 if (THIS_DELTA > THIS_PROXOUT_TH) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_PROX_DETECT; } return; } #endif THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } else { THIS_STATEID = TSL_STATEID_DEB_RELEASE_DETECT; } } } /** * @brief Touch state processing * Same as Detect state * @param None * @retval None */ void TSL_tkey_TouchStateProcess(void) { #if TSLPRM_DTO > 0 TSL_tTick_sec_T tick_detected; #endif if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_ERROR; } else { THIS_STATEID = TSL_STATEID_DEB_ERROR_TOUCH; } } else // Acquisition is OK or has NOISE { if TEST_DELTA(>, THIS_DETECTOUT_TH) { TEST_DELTA_NEGATIVE; #if TSLPRM_DTO > 0 //------------------------------------ // Detection Time Out (DTO) processing //------------------------------------ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64)) { tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved // Enter in calibration state if the DTO duration has elapsed if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK) { TSL_tkey_SetStateCalibration(0); } } #endif return; // Normal operation, stay in Touch state } #if TSLPRM_USE_PROX > 0 if (THIS_DELTA > THIS_PROXOUT_TH) { THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_PROX; DTO_GET_TIME; // Take current time for DTO processing } else { THIS_STATEID = TSL_STATEID_DEB_PROX_TOUCH; } return; } #endif THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE; if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_RELEASE; } else { THIS_STATEID = TSL_STATEID_DEB_RELEASE_TOUCH; } } } /** * @brief Debounce error state processing * @param None * @retval None */ void TSL_tkey_DebErrorStateProcess(void) { volatile TSL_StateMask_enum_T mask; if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max) { if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;} if (THIS_COUNTER_DEB == 0) { THIS_STATEID = TSL_STATEID_ERROR; } } else // Acquisition is OK or has NOISE { // Get state mask mask = TSL_tkey_GetStateMask(); // Mask Error and Debounce bits #ifdef _RAISONANCE_ mask &= ~(TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK); #else mask &= (TSL_StateMask_enum_T)(~(TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK)); #endif // Go back to the previous state switch (mask) { case TSL_STATEMASK_RELEASE : THIS_STATEID = TSL_STATEID_RELEASE; break; case TSL_STATEMASK_PROX : THIS_STATEID = TSL_STATEID_PROX; break; case TSL_STATEMASK_DETECT : THIS_STATEID = TSL_STATEID_DETECT; break; case TSL_STATEMASK_TOUCH : THIS_STATEID = TSL_STATEID_TOUCH; break; default: TSL_tkey_SetStateCalibration(0); break; } } } //============================================================================== // Private functions //============================================================================== /** * @brief Get the current time in second and affect it to the DTO counter (Private) * @param None * @retval None */ void TSL_tkey_DTOGetTime(void) { disableInterrupts(); THIS_COUNTER_DTO = (TSL_tCounter_T)TSL_Globals.Tick_sec; enableInterrupts(); } #endif // #if TSLPRM_TOTAL_TKEYS > 0 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/