/** * @brief Calculate the K coefficient * @param[in] objgrp Pointer to the objects group to process * @param[in] k_slow K coefficient when objects have different delta variation * @param[in] k_fast K coefficient when objects have the same delta variation * @retval K coefficient (slow or fast) */ TSL_tKCoeff_T TSL_ecs_CalcK(TSL_ObjectGroup_T *objgrp, TSL_tKCoeff_T k_slow, TSL_tKCoeff_T k_fast) { TSL_tIndex_T idx_obj; // Index of current object TSL_tIndex_T idx_ch; // Index of current channel TSL_tDelta_T ldelta = 0; // Temporary delta TSL_tDelta_T ECS_Fast_Enable = 1; TSL_tDelta_T ECS_Fast_Direction = 0; CONST TSL_Object_T *pobj; TSL_tKCoeff_T retval = k_slow; TSL_tNb_T nb_channels = 0; // Number of channels inside current object TSL_ChannelData_T *p_Ch = 0; // Check parameters (if USE_FULL_ASSERT is defined) assert_param(IS_K_COEFF_OK(k_slow)); assert_param(IS_K_COEFF_OK(k_fast)); pobj = objgrp->p_Obj; // First object in the group // Process all objects for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++) { // Assign global object TSL_obj_SetGlobalObj(pobj); #if TSLPRM_TOTAL_TKEYS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB)) { // Ignore object if not in Release state (OFF or Error in this case) if (THIS_TKEY_STATEID != TSL_STATEID_RELEASE) { pobj++; // Next object continue; // Stop processing of current object } nb_channels = 1; p_Ch = TSL_Globals.This_TKey->p_ChD; } #endif #if TSLPRM_TOTAL_LNRTS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB)) { // Ignore object if not in Release state (OFF or Error in this case) if (THIS_LINROT_STATEID != TSL_STATEID_RELEASE) { pobj++; // Next object continue; // Stop processing of current object } nb_channels = THIS_LINROT_NB_CHANNELS; p_Ch = TSL_Globals.This_LinRot->p_ChD; } #endif // Check channel pointer variable (if USE_FULL_ASSERT is defined) assert_param(IS_POINTER_INITIALIZED(p_Ch)); // Check all channels of current object for (idx_ch = 0; idx_ch < nb_channels; idx_ch++) { ldelta = p_Ch->Delta; // Check delta if (ldelta == 0) // No Fast ECS ! { ECS_Fast_Enable = 0; } else { if (ldelta < 0) { if (ECS_Fast_Direction > 0) // No Fast ECS ! { ECS_Fast_Enable = 0; } else { ECS_Fast_Direction = -1; } } else { if (ECS_Fast_Direction < 0) // No Fast ECS ! { ECS_Fast_Enable = 0; } else { ECS_Fast_Direction = 1; } } } p_Ch++; // Next channel } // for all channels of current object pobj++; // Next object } // for all objects // Assign K fast following Delta variations if (ECS_Fast_Enable) { retval = k_fast; } return retval; }
/** * @brief Detection Exclusion System on the first object in detect state * @param[in] objgrp Pointer to the objects group to process * @retval None */ void TSL_dxs_FirstObj(CONST TSL_ObjectGroup_T *objgrp) { #if TSLPRM_USE_DXS > 0 TSL_tIndex_T idx_obj; CONST TSL_Object_T *pobj; CONST TSL_Object_T *pobj_candidate = 0; // Candidate object for being in Detect state + DxSLock flag TSL_tIndex_T obj_locked = 0; // Object with Lock flag // Exit if no object are in DETECT state. if ((objgrp->StateMask & TSL_STATE_DETECT_BIT_MASK) == 0) { return; } pobj = objgrp->p_Obj; // First object in the group // Process all objects for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++) { // Assign global object TSL_obj_SetGlobalObj(pobj); //-------------------------------------------------------------------------- #if TSLPRM_TOTAL_TKEYS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB)) { if (THIS_TKEY_STATEID == TSL_STATEID_DETECT) { if (THIS_TKEY_DXSLOCK == TSL_TRUE) { if (!obj_locked) { obj_locked = 1; pobj_candidate = 0; } else { THIS_TKEY_STATEID = TSL_STATEID_TOUCH; THIS_TKEY_CHANGE = TSL_STATE_CHANGED; } } else { THIS_TKEY_STATEID = TSL_STATEID_TOUCH; THIS_TKEY_CHANGE = TSL_STATE_CHANGED; if ((!pobj_candidate) && (!obj_locked)) { pobj_candidate = pobj; } } } } #endif // TSLPRM_TOTAL_TKEYS > 0 //-------------------------------------------------------------------------- #if TSLPRM_TOTAL_LNRTS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB)) { if (THIS_LINROT_STATEID == TSL_STATEID_DETECT) { if (THIS_LINROT_DXSLOCK == TSL_TRUE) { if (!obj_locked) { obj_locked = 1; pobj_candidate = 0; } else { THIS_LINROT_STATEID = TSL_STATEID_TOUCH; THIS_LINROT_CHANGE = TSL_STATE_CHANGED; } } else { THIS_LINROT_STATEID = TSL_STATEID_TOUCH; THIS_LINROT_CHANGE = TSL_STATE_CHANGED; if ((!pobj_candidate) && (!obj_locked)) { pobj_candidate = pobj; } } } } #endif // TSLPRM_TOTAL_LNRTS > 0 pobj++; // Next object } // // for all objects // Change state from TOUCH to DETECT + DxSLock flag on the candidate object only if (pobj_candidate) { // Assign global object TSL_obj_SetGlobalObj(pobj_candidate); #if TSLPRM_TOTAL_TKEYS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB)) { THIS_TKEY_STATEID = TSL_STATEID_DETECT; THIS_TKEY_CHANGE = TSL_STATE_CHANGED; THIS_TKEY_DXSLOCK = TSL_TRUE; } #endif // TSLPRM_TOTAL_TKEYS > 0 #if TSLPRM_TOTAL_LNRTS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB)) { THIS_LINROT_STATEID = TSL_STATEID_DETECT; THIS_LINROT_CHANGE = TSL_STATE_CHANGED; THIS_LINROT_DXSLOCK = TSL_TRUE; } #endif // TSLPRM_TOTAL_LNRTS > 0 } #endif // TSLPRM_USE_DXS > 0 }
/** * @brief Calculate the new Reference on a group of objects * @param[in] objgrp Pointer to the objects group to process * @param[in] Kcoeff K coefficient to apply * @retval None */ void TSL_ecs_ProcessK(TSL_ObjectGroup_T *objgrp, TSL_tKCoeff_T Kcoeff) { TSL_tIndex_T idx_obj; // Index of current object TSL_tIndex_T idx_ch; // Index of current channel CONST TSL_Object_T *pobj; TSL_tKCoeff_T Kcoeff_comp; uint32_t ECS_meas; uint32_t ECS_ref; TSL_tNb_T nb_channels = 0; // Number of channels inside current object TSL_ChannelData_T *p_Ch = 0; void(*pFunc_SetStateCalibration)(TSL_tCounter_T delay) = 0; // Check parameters (if USE_FULL_ASSERT is defined) assert_param(IS_K_COEFF_OK(Kcoeff)); pobj = objgrp->p_Obj; // First object in the group // Calculate the K coefficient complement Kcoeff_comp = (0xFF ^ Kcoeff) + 1; // Process all objects for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++) { // Assign global object TSL_obj_SetGlobalObj(pobj); #if TSLPRM_TOTAL_TKEYS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB)) { // Ignore object if not in Release state (OFF or Error in this case) if (THIS_TKEY_STATEID != TSL_STATEID_RELEASE) { pobj++; // Next object continue; // Stop processing of current object } nb_channels = 1; p_Ch = TSL_Globals.This_TKey->p_ChD; pFunc_SetStateCalibration = &TSL_tkey_SetStateCalibration; } #endif #if TSLPRM_TOTAL_LNRTS > 0 if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB)) { // Ignore object if not in Release state (OFF or Error in this case) if (THIS_LINROT_STATEID != TSL_STATEID_RELEASE) { pobj++; // Next object continue; // Stop processing of current object } nb_channels = THIS_LINROT_NB_CHANNELS; p_Ch = TSL_Globals.This_LinRot->p_ChD; pFunc_SetStateCalibration = &TSL_linrot_SetStateCalibration; } #endif // Check channel pointer variable (if USE_FULL_ASSERT is defined) assert_param(IS_POINTER_INITIALIZED(p_Ch)); // Calculate the new reference + rest for all channels for (idx_ch = 0; idx_ch < nb_channels; idx_ch++) { ECS_meas = TSL_acq_ComputeMeas(p_Ch->Ref, p_Ch->Delta); ECS_meas <<= 8; ECS_ref = (uint32_t)(p_Ch->Ref); ECS_ref <<= 8; ECS_ref += p_Ch->RefRest; ECS_ref *= Kcoeff_comp; ECS_ref += (Kcoeff * ECS_meas); p_Ch->RefRest = (TSL_tRefRest_T)((ECS_ref >> 8) & 0xFF); p_Ch->Ref = (TSL_tRef_T)(ECS_ref >> 16); // Go in Calibration state in the Reference is out of Range if (TSL_acq_TestReferenceOutOfRange(p_Ch) == TSL_TRUE) { pFunc_SetStateCalibration(0); } p_Ch++; // Next channel } pobj++; // Next object } // for all objects }
/** * @brief Initialize a group of Objects * @param[in] objgrp Pointer to the group of objects * @retval None */ void TSL_obj_GroupInit(TSL_ObjectGroup_T *objgrp) { TSL_tIndex_T idx_obj; CONST TSL_Object_T *pobj; TSL_tNb_T objgrp_state_mask = 0; pobj = objgrp->p_Obj; // First object in the group objgrp->Change = TSL_STATE_NOT_CHANGED; // Process all objects for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++) { // Assign global object TSL_obj_SetGlobalObj(pobj); switch (pobj->Type) { //------------------------------------------------------------------------ #if TSLPRM_TOTAL_TOUCHKEYS > 0 case TSL_OBJ_TOUCHKEY: // Call the specific method TSL_Globals.This_TKey->p_Methods->Init(); // Check if the object has changed of state if (TSL_Globals.This_TKey->p_Data->Change) { objgrp->Change = TSL_STATE_CHANGED; } // Update object group state mask objgrp_state_mask |= TSL_Globals.This_TKey->p_SM[TSL_Globals.This_TKey->p_Data->StateId].StateMask; break; #endif //------------------------------------------------------------------------ #if TSLPRM_TOTAL_TOUCHKEYS_B > 0 case TSL_OBJ_TOUCHKEYB: // Call the default method TSL_Params.p_TKeyMT->Init(); // Check if the object has changed of state if (TSL_Globals.This_TKey->p_Data->Change) { objgrp->Change = TSL_STATE_CHANGED; } // Get object state mask from state machine in TSL_Params objgrp_state_mask |= TSL_Params.p_TKeySM[TSL_Globals.This_TKey->p_Data->StateId].StateMask; break; #endif //------------------------------------------------------------------------ #if TSLPRM_TOTAL_LINROTS > 0 case TSL_OBJ_LINEAR: case TSL_OBJ_ROTARY: // Call the specific method TSL_Globals.This_LinRot->p_Methods->Init(); // Check if the object has changed of state if (TSL_Globals.This_LinRot->p_Data->Change) { objgrp->Change = TSL_STATE_CHANGED; } // Update object group state mask objgrp_state_mask |= TSL_Globals.This_LinRot->p_SM[TSL_Globals.This_LinRot->p_Data->StateId].StateMask; break; #endif //------------------------------------------------------------------------ #if TSLPRM_TOTAL_LINROTS_B > 0 case TSL_OBJ_LINEARB: case TSL_OBJ_ROTARYB: // Call the default method TSL_Params.p_LinRotMT->Init(); // Check if the object has changed of state if (TSL_Globals.This_LinRot->p_Data->Change) { objgrp->Change = TSL_STATE_CHANGED; } // Get object state mask from state machine in TSL_Params objgrp_state_mask |= TSL_Params.p_LinRotSM[TSL_Globals.This_LinRot->p_Data->StateId].StateMask; break; #endif default: break; } pobj++; // Next object } // Update the object group state mask objgrp->StateMask = objgrp_state_mask; }