📄 stm8_tsl_rc_services.c
字号:
/**
******************************************************************************
* @file STM8_TSL_RC_Services.c
* @brief RC Touch Sensing Library for STM8 CPU family.
* Set of library internal functions.
* @author STMicroelectronics - MCD Application Team
* @version V1.1.0
* @date 21-FEB-2009
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2>
* @image html logo.bmp
******************************************************************************
*/
#include "STM8_TSL_RC_API.h"
#include "STM8_TSL_RC_Services.h"
//-------- SECTION DEFINITION FOR THIS FILE --------------
#if defined(__CSMC__) && defined(USE_PRAGMA_SECTION)
#pragma section [TSL_RAM]
#pragma section @tiny [TSL_RAM0]
#pragma section (TSL_CODE)
#pragma section const {TSL_CONST}
#endif
//============================================================================
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//----- SINGLE CHANNEL KEY OR COMMON KEY SERVICES -----
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//============================================================================
/**
******************************************************************************
* @brief Update pointer to current Key Structure.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SetStructPointer(void)
{
pKeyStruct = &sSCKeyInfo[KeyIndex];
}
/**
******************************************************************************
* @brief Delta calculation for the current Key structure.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_DeltaCalculation(void)
{
Delta = (s16)(pKeyStruct->Channel.LastMeas - pKeyStruct->Channel.Reference);
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the IDLE state.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetIdleState(void)
{
pKeyStruct->Setting.b.CHANGED = 1;
TSL_SCKey_BackToIdleState();
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to return to the IDLE state and reset appropriate flags.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_BackToIdleState(void)
{
pKeyStruct->State.whole = IDLE_STATE;
pKeyStruct->Setting.b.DETECTED = 0;
pKeyStruct->Setting.b.LOCKED = 0;
pKeyStruct->Setting.b.ERROR = 0;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the PRE_DETECTED state and init integrator counter.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetPreDetectState(void)
{
pKeyStruct->State.whole = PRE_DETECTED_STATE;
pKeyStruct->Channel.IntegratorCounter = DetectionIntegrator;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the DETECTED state and init detection timeout + flags.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetDetectedState(void)
{
pKeyStruct->State.whole = DETECTED_STATE;
pKeyStruct->Setting.b.DETECTED = 1;
pKeyStruct->Setting.b.CHANGED = 1;
pKeyStruct->Counter = DetectionTimeout;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the POST_DETECTED state and init end integrator counter.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetPostDetectState(void)
{
pKeyStruct->State.whole = POST_DETECTED_STATE;
pKeyStruct->Channel.IntegratorCounter = EndDetectionIntegrator;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go back to the DETECTED state
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_BackToDetectedState(void)
{
pKeyStruct->State.whole = DETECTED_STATE;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the PRE_CALIBRATION state and init integrator counter.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetPreRecalibrationState(void)
{
pKeyStruct->State.whole = PRE_CALIBRATION_STATE;
pKeyStruct->Channel.IntegratorCounter = RecalibrationIntegrator;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the CALIBRATION state and init appropriate flags.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetCalibrationState(void)
{
pKeyStruct->State.whole = CALIBRATION_STATE;
pKeyStruct->Setting.b.DETECTED = 0;
pKeyStruct->Setting.b.CHANGED = 1;
pKeyStruct->Setting.b.LOCKED = 0;
pKeyStruct->Setting.b.ERROR = 0;
pKeyStruct->Counter = SCKEY_CALIBRATION_COUNT_DEFAULT;
pKeyStruct->Channel.Reference = 0;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the ERROR state and init appropriate flags.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetErrorState(void)
{
pKeyStruct->State.whole = ERROR_STATE;
pKeyStruct->Setting.b.DETECTED = 0;
pKeyStruct->Setting.b.CHANGED = 1;
pKeyStruct->Setting.b.LOCKED = 0;
pKeyStruct->Setting.b.ERROR = 1;
}
/**
******************************************************************************
* @brief Short local routine to setup SCKey internal state machine.
* Used to go to the DISABLE state and init appropriate flags.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_SetDisabledState(void)
{
pKeyStruct->State.whole = DISABLED_STATE;
pKeyStruct->Setting.b.DETECTED = 0;
pKeyStruct->Setting.b.CHANGED = 1;
pKeyStruct->Setting.b.LOCKED = 0;
pKeyStruct->Setting.b.ERROR = 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 & (PRE_DETECTED_STATE | DETECTED_STATE | POST_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 & (PRE_DETECTED_STATE | DETECTED_STATE | POST_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
}
}
}
}
/**
******************************************************************************
* @brief Apply Detection Exclusion System algorithm (DES).
* This function modify the LOCKED bit of current Key structure only.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_SCKey_DES(void)
{
u8 DESGroupMask, KeyToCheck;
if ( pKeyStruct->Setting.b.LOCKED )
return;
DESGroupMask = pKeyStruct->DESGroup;
for ( KeyToCheck = 0; KeyToCheck < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyToCheck++ )
{
if ( KeyToCheck != KeyIndex )
{
// KeyToCheck and current key are in same group ?
if ( sSCKeyInfo[KeyToCheck].DESGroup & DESGroupMask )
{
if ( sSCKeyInfo[KeyToCheck].Setting.b.LOCKED )
{
goto ExitToIdle;
}
}
}
}
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 0
for ( KeyToCheck = 0; KeyToCheck < NUMBER_OF_MULTI_CHANNEL_KEYS; KeyToCheck++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -