📄 stm8_tsl_rc_multichannelkey.c
字号:
u8 TSL_MCKey_Position(void)
{
u8 Index1, Index2;
#if CHANNEL_PER_MCKEY == 8
u8 Index3;
#endif
u16 Major, Minor, SectorComputation;
s16 NewPosition;
u8 uNewPosition;
u32 tmpdelta;
u8 PositionCorrection;
u8 retval = 0x00;
Delta1 = 0;
Delta2 = 0;
Delta3 = 0;
Index1 = 0;
Index2 = 0;
#if CHANNEL_PER_MCKEY == 8
Index3 = 0;
#endif
for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ )
{
TSL_MCKey_DeltaCalculation( ChannelIndex );
// Delta must be positive only otherwise it is noise
if ( Delta < 0 )
{
Delta = 0;
}
/* We normalize the Delta */
tmpdelta = (u32)(Delta * (u32)(pMCKeyStruct->Channel[0].Reference));
tmpdelta = tmpdelta / pMCKeyStruct->Channel[ChannelIndex].Reference;
Delta = (s16)tmpdelta;
/* Apply a fixed coefficient */
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
if (KeyIndex == 0) // MCKEY1
{
#endif
if (MCKEY1_DELTA_COEFF[ChannelIndex] != 0x0100)
{
tmpdelta = (u32)(Delta * MCKEY1_DELTA_COEFF[ChannelIndex]);
Delta = (s16)(tmpdelta >> (u8)8);
}
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
}
else // MCKEY2
{
if (MCKEY2_DELTA_COEFF[ChannelIndex] != 0x0100)
{
tmpdelta = (u32)(Delta * MCKEY2_DELTA_COEFF[ChannelIndex]);
Delta = (s16)(tmpdelta >> (u8)8);
}
}
#endif
/* Sort the biggest, middle and lowest signals measured
- Delta1 and Index1 = biggest
- Delta2 and Index2 = middle
- Delta3 and Index3 = lowest */
if ( Delta > Delta1 )
{
Delta3 = Delta2;
Delta2 = Delta1;
Delta1 = Delta;
#if CHANNEL_PER_MCKEY == 8
Index3 = Index2;
#endif
Index2 = Index1;
Index1 = ChannelIndex;
}
else
{
if ( Delta > Delta2 )
{
Delta3 = Delta2;
Delta2 = Delta;
#if CHANNEL_PER_MCKEY == 8
Index3 = Index2;
#endif
Index2 = ChannelIndex;
}
else
{
if ( Delta > Delta3 )
{
#if CHANNEL_PER_MCKEY == 8
Index3 = ChannelIndex;
#endif
Delta3 = Delta;
}
}
}
} /* for all channels */
/* Noise filter: we need at least two significant Delta measurements */
if (Delta2 < ((u8)(pMCKeyStruct->EndDetectThreshold >> 1)) - 1)
{
return retval;
}
//----------------------------------------------------------------------------
// Position calculation...
//----------------------------------------------------------------------------
/*----------------------------------------------------------------------------
B = Biggest signal measured (Delta1/Index1)
M = Middle signal measured (Delta2/Index2)
S = Smallest signal measured (Delta3/Index3)
- The equation to find the position is:
Position = Offset +/- [ Sector_Size x ( Major / (Major + Minor) ) ]
- The Offset is the position of the middle of the Middle signal segment.
All the Offset values are stored in the ROM table Table_POSITION_OFFSET.
- Major = Biggest - Smallest signals
Minor = Middle - Smallest signals
- The Sector_Size depends of the number of channels used
----------------------------------------------------------------------------*/
/* Calculates the Major and Minor parameters */
Minor = Delta2 - Delta3; // Middle - Smallest signals
Major = Delta1 - Delta3; // Biggest - Smallest signals
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
if (KeyIndex == 0) // MCKEY1
{
#endif
NewPosition = MCKEY1_TABLE_POSITION_OFFSET[Index1][Index2];
SectorComputation = MCKEY1_SECTOR_COMPUTATION;
PositionCorrection = MCKEY1_POSITION_CORRECTION;
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
}
else // MCKEY2
{
NewPosition = MCKEY2_TABLE_POSITION_OFFSET[Index1][Index2];
SectorComputation = MCKEY2_SECTOR_COMPUTATION;
PositionCorrection = MCKEY2_POSITION_CORRECTION;
}
#endif
/* Calculates: [ Sector_Size x ( Major / (Major + Minor) ) ] */
SectorComputation = Major * SectorComputation;
SectorComputation = SectorComputation / ( Major + Minor );
// Use the sign bit from table to define the interpretation direction.
// The NewPosition is multiplied by 2 because the Offset stored in the ROM
// table is divided by 2...
if ( NewPosition > 0 ) // means Offset is > 0 in the ROM table
{
NewPosition = (s16)(NewPosition << 1); /*lint !e701 suppress info on this line only */
NewPosition += SectorComputation;
}
else // means Offset is <= 0 in the ROM table
{
NewPosition = (s16)((-NewPosition) << 1); /*lint !e701 suppress info on this line only */
NewPosition -= SectorComputation;
}
if (pMCKeyStruct->Setting.b.MCKEY_TYPE) // It's a Slider...
{
/* First adjustment used to shift all the values to obtain the "zero" */
if (NewPosition > 0)
{
NewPosition -= PositionCorrection;
}
else
{
NewPosition = NewPosition + 256 - PositionCorrection;
}
/* Second adjustment used to clamp the values at extremities of slider */
if (NewPosition < 0)
{
NewPosition = 0;
}
if (NewPosition > 255)
{
NewPosition = 255;
}
}
else // It's a Wheel: we keep only the low byte
{
NewPosition = (u8)NewPosition;
}
//----------------------------------------------------------------------------
// Direction Change Process
//----------------------------------------------------------------------------
#if MCKEY_DIRECTION_CHANGE_ENABLED > 0
if (pMCKeyStruct->Setting.b.DIRECTION) // Anticlockwise direction ...
{
// Check Direction changed and Position overflow from 0x00 to 0xFF not realized !
if ( ((u8)NewPosition > pMCKeyStruct->UnScaledPosition) && (((u8)NewPosition - pMCKeyStruct->UnScaledPosition) < MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) )
{
if ( NewPosition < (u16)(pMCKeyStruct->UnScaledPosition + pMCKeyStruct->DirectionChangeThreshold) )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
return retval;
}
else
{
pMCKeyStruct->Channel[1].IntegratorCounter--;
if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
pMCKeyStruct->Setting.b.DIRECTION = 0; // New direction accepted: clockwise.
}
else
{
return retval;
}
}
}
// Check position overflow from 0xFF to 0x00 to be filtered !
if ( (NewPosition + MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) < pMCKeyStruct->UnScaledPosition )
{
if ( (NewPosition + MCKEY_DIRECTION_CHANGE_TOTAL_STEPS) < (u16)(pMCKeyStruct->UnScaledPosition + pMCKeyStruct->DirectionChangeThreshold) )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
return retval;
}
else
{
pMCKeyStruct->Channel[1].IntegratorCounter--;
if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
pMCKeyStruct->Setting.b.DIRECTION = 0; // New direction accepted: clockwise.
}
else
{
return retval;
}
}
}
}
else // Clockwise direction... DEFAULT SETTING !
{
// Check Direction changed and Position overflow from 0xFF to 0x00 not realized !
if ( ((u8)NewPosition < pMCKeyStruct->UnScaledPosition) && ((pMCKeyStruct->UnScaledPosition - (u8)NewPosition) < MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) )
{
if ( (NewPosition + pMCKeyStruct->DirectionChangeThreshold) > pMCKeyStruct->UnScaledPosition )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
return retval;
}
else
{
pMCKeyStruct->Channel[1].IntegratorCounter--;
if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
pMCKeyStruct->Setting.b.DIRECTION = 1; // New direction accepted: anticlockwise.
}
else
{
return retval;
}
}
}
// Check position overflow from 0x00 to 0xFF to be filtered !
if ( NewPosition > (u16)(pMCKeyStruct->UnScaledPosition + MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) )
{
if ( (NewPosition + pMCKeyStruct->DirectionChangeThreshold) > (u16)(pMCKeyStruct->UnScaledPosition + MCKEY_DIRECTION_CHANGE_TOTAL_STEPS) )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
return retval;
}
else
{
pMCKeyStruct->Channel[1].IntegratorCounter--;
if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
{
pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
pMCKeyStruct->Setting.b.DIRECTION = 1; // New direction accepted: anticlockwise.
}
else
{
return retval;
}
}
}
}
#endif // MCKEY_DIRECTION_CHANGE_ENABLED
//----------------------------------------------------------------------------
// Final result...
//----------------------------------------------------------------------------
// The UnScaledPosition parameter is always updated
// The Position parameter is updated only if different from the previous one
pMCKeyStruct->UnScaledPosition = (u8)NewPosition;
uNewPosition = (u8)((u8)NewPosition >> (MCKEY_RESOLUTION_CALCULATION - pMCKeyStruct->Resolution));
if ( pMCKeyStruct->Position != uNewPosition )
{
pMCKeyStruct->Position = uNewPosition;
pMCKeyStruct->Setting.b.POSCHANGED = 1; /* Warning: Application layer must reset this flag */
retval = 0xFF;
}
return retval;
}
/**
******************************************************************************
* @brief Check for customer code setting and adapt key state.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_MCKey_CheckDisabled(void)
{
if ( !pMCKeyStruct->Setting.b.ENABLED )
{
TSL_MCKey_SetDisabledState( );
}
}
/**
******************************************************************************
* @brief Check for customer code setting and adapt key state.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_MCKey_CheckEnabled(void)
{
if ( pMCKeyStruct->Setting.b.ENABLED && pMCKeyStruct->Setting.b.IMPLEMENTED )
{
TSL_MCKey_SetCalibrationState( );
}
}
/**
******************************************************************************
* @brief Verify the last burst sequence gave a result within the authorized range.
* @par Parameters:
* None
* @retval u8 Return 0 if OK, 0xFF if Error.
* @par Required preconditions:
* None
******************************************************************************
*/
u8 TSL_MCKey_CheckErrorCondition(void)
{
for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ )
{
if ( (pMCKeyStruct->Channel[ChannelIndex].LastMeas < MCKEY_MIN_ACQUISITION)
|| (pMCKeyStruct->Channel[ChannelIndex].LastMeas > MCKEY_MAX_ACQUISITION) )
{
return 0xFF; // Error case !
}
}
return 0;
}
//============================================================================
//----- CONDITIONAL COMPILING FOR MCKEYS !!! -----------
#endif
//============================================================================
/*********************** (c) 2009 STMicroelectronics **************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -