/** ****************************************************************************** * @brief Initialize all SCKey relative parameters and variables. * @param None * @retval None ****************************************************************************** */ void TSL_SCKey_Init(void) { for (KeyIndex = 0; KeyIndex < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyIndex++) { TSL_SetStructPointer(); pKeyStruct->State.whole = DISABLED_STATE; pKeyStruct->DetectThreshold = SCKEY_DETECTTHRESHOLD_DEFAULT; pKeyStruct->EndDetectThreshold = SCKEY_ENDDETECTTHRESHOLD_DEFAULT; pKeyStruct->RecalibrationThreshold = SCKEY_RECALIBRATIONTHRESHOLD_DEFAULT; } }
/** ****************************************************************************** * @brief After Touch Sensing acquisition, this function launch the data interpretation. * @param None * @retval None ****************************************************************************** */ void TSL_SCKey_Process(void) { TSL_SetStructPointer(); TSL_DeltaCalculation(); switch (pKeyStruct->State.whole) { case IDLE_STATE: if (TSL_SCKey_CheckErrorCondition()) { TSL_SCKey_SetErrorState(); break; } TSL_SCKey_IdleTreatment(); TSL_SCKey_CheckDisabled(); break; case PRE_DETECTED_STATE: TSL_SCKey_PreDetectTreatment(); break; case DETECTED_STATE: if (TSL_SCKey_CheckErrorCondition()) { TSL_SCKey_SetErrorState(); break; } TSL_SCKey_DetectedTreatment(); TSL_SCKey_CheckDisabled(); break; case POST_DETECTED_STATE: TSL_SCKey_PostDetectTreatment(); break; case PRE_CALIBRATION_STATE: TSL_SCKey_PreRecalibrationTreatment(); break; case CALIBRATION_STATE: if (TSL_SCKey_CheckErrorCondition()) { TSL_SCKey_SetErrorState(); break; } TSL_SCKey_CalibrationTreatment(); TSL_SCKey_CheckDisabled(); break; case ERROR_STATE: TSL_SCKey_CheckDisabled(); break; case DISABLED_STATE: TSL_SCKey_CheckEnabled(); break; default: for (;;) { // Infinite loop. } } TSL_TempGlobalSetting.whole |= pKeyStruct->Setting.whole; TSL_TempGlobalState.whole |= pKeyStruct->State.whole; pKeyStruct->Setting.b.CHANGED = 0; }
/** ****************************************************************************** * @brief Considers all Key information to apply the Environmental Change System (ECS). * Uses an IIR Filter with order 1: * Y(n) = K x X(n) + (1-K) x Y(n-1) * Y is the reference and X is the acquisition value. * @par Parameters: * None * @retval void None * @par Required preconditions: * None ****************************************************************************** */ void TSL_ECS(void) { u8 K_Filter, K_Filter_Complement; s8 ECS_Fast_Direction, ECS_Fast_Enable; u32 IIR_Result; disableInterrupts(); Local_TickECS10ms = TSL_TickCount_ECS_10ms; TSL_TickCount_ECS_10ms = 0; enableInterrupts(); while ( Local_TickECS10ms-- ) { ECSTimeStepCounter--; ECSTempoPrescaler--; if ( !ECSTempoPrescaler ) { ECSTempoPrescaler = 10; if ( ECSTempoCounter ) ECSTempoCounter--; } K_Filter = ECS_K_Slow; // Default case ! ECS_Fast_Enable = 1; ECS_Fast_Direction = 0; for ( KeyIndex = 0; KeyIndex < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyIndex++ ) { TSL_SetStructPointer(); // If any key is in DETECT state, ECS is disabled ! if ( pKeyStruct->State.whole & DETECTED_STATE) { ECSTempoCounter = ECSTemporization; // Restart temporization counter ... break; // Out from the for loop } if ( pKeyStruct->State.whole == IDLE_STATE ) { TSL_DeltaCalculation(); if ( Delta == 0 ) // No Fast ECS ! ECS_Fast_Enable = 0; else { if ( Delta < 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; } } } } #if NUMBER_OF_MULTI_CHANNEL_KEYS > 0 for ( KeyIndex = 0; KeyIndex < NUMBER_OF_MULTI_CHANNEL_KEYS; KeyIndex++ ) { TSL_MCKey_SetStructPointer(); if ( pMCKeyStruct->State.whole & DETECTED_STATE ) { ECSTempoCounter = ECSTemporization; // Restart temporization counter ... break; // Out from the for loop } if ( pMCKeyStruct->State.whole == IDLE_STATE ) { for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ ) { TSL_MCKey_DeltaCalculation( ChannelIndex ); Delta1 += Delta; } if ( Delta1 == 0 ) { // No Fast ECS ! ECS_Fast_Enable = 0; } else { if ( Delta1 < 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; } } } } #endif if ( !ECSTimeStepCounter && !ECSTempoCounter ) { ECSTimeStepCounter = ECSTimeStep; if (ECS_Fast_Enable) { K_Filter = ECS_K_Fast; } K_Filter_Complement = (u8)((0xFF ^ K_Filter) + 1); if ( K_Filter ) { // Apply filter to generate new reference value. for ( KeyIndex = 0; KeyIndex < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyIndex++ ) { TSL_SetStructPointer(); if ( pKeyStruct->State.whole == IDLE_STATE ) { IIR_Result = ((u32)(pKeyStruct->Channel.Reference) << 8) + pKeyStruct->Channel.ECSRefRest; IIR_Result = K_Filter_Complement * IIR_Result; IIR_Result += K_Filter * ((u32)(pKeyStruct->Channel.LastMeas) << 8); pKeyStruct->Channel.Reference = (u16)(IIR_Result >> 16); pKeyStruct->Channel.ECSRefRest = (u8)(IIR_Result >> 8); } } #if NUMBER_OF_MULTI_CHANNEL_KEYS > 0 for ( KeyIndex = 0; KeyIndex < NUMBER_OF_MULTI_CHANNEL_KEYS; KeyIndex++ ) { TSL_MCKey_SetStructPointer(); if ( pMCKeyStruct->State.whole == IDLE_STATE ) { for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ ) { IIR_Result = ((u32)(pMCKeyStruct->Channel[ChannelIndex].Reference) << 8) + pMCKeyStruct->Channel[ChannelIndex].ECSRefRest; IIR_Result = K_Filter_Complement * IIR_Result; IIR_Result += K_Filter * ((u32)(pMCKeyStruct->Channel[ChannelIndex].LastMeas) << 8); pMCKeyStruct->Channel[ChannelIndex].Reference = (u16)(IIR_Result >> 16); pMCKeyStruct->Channel[ChannelIndex].ECSRefRest = (u8)(IIR_Result >> 8); } } } #endif } }