📄 mems.c
字号:
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init( SPI2, &SPI_InitStructure );
/* Enable SPI2 */
SPI_Cmd( SPI2, ENABLE );
if( MEMS_ReadID() != 0x3A )
{
int i;
// Try to resynchronize
for( i = 0 ; i < 17 ; i++ )
{
/* Configure SPI2 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( GPIOB, &GPIO_InitStructure );
GPIO_WriteBit( GPIOB, GPIO_Pin_15, HIGH );
MEMS_ChipSelect( LOW );
GPIO_WriteBit( GPIOB, GPIO_Pin_13, LOW );
GPIO_WriteBit( GPIOB, GPIO_Pin_13, HIGH );
MEMS_ChipSelect( HIGH );
/* Configure again PB. SCK as SPI2 pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( GPIOB, &GPIO_InitStructure );
if ( MEMS_ReadID() == 0x3A )
{
break;
}
}
if( i == 17 )
{
DRAW_DisplayString( 1, 50, "Test MEM ID Failed", 17 );
}
}
/* Read for the first time */
N_filtering = 0;
MEMS_ReadOutXY();
MEMS_Info.OutX_F4 = MEMS_Info.OutX_F16 = MEMS_Info.OutX_F64 = MEMS_Info.OutX_F256 = MEMS_Info.OutX;
MEMS_Info.OutY_F4 = MEMS_Info.OutY_F16 = MEMS_Info.OutY_F64 = MEMS_Info.OutY_F256 = MEMS_Info.OutY;
MEMS_Info.OutZ_F4 = MEMS_Info.OutZ_F16 = MEMS_Info.OutZ_F64 = MEMS_Info.OutZ_F256 = MEMS_Info.OutZ;
/* Init X and Y*/
MEMS_GetPosition( &XInit, &YInit );
/* Wake Up Mems*/
MEMS_WakeUp();
}
/*******************************************************************************
*
* MEMS_Handler
*
*******************************************************************************/
/**
*
* Called by the CircleOS scheduler to manage the MEMS. The Circle beeps if the
* MEMS is shocked.
*
* @attention This function must <b>NOT</b> be called by the user.
*
**/
/******************************************************************************/
void MEMS_Handler( void )
{
char buffer [20];
int i;
int ofs_disp = 0;
if( StartingFromResetOrShockCounter )
{
StartingFromResetOrShockCounter--;
}
TimeCounterForDoubleClick++;
MEMS_ReadOutXY();
// Evaluate gradients
GradX = ( MEMS_Info.OutX_F4 >> 2 ) - MEMS_Info.OutX;
GradY = ( MEMS_Info.OutY_F4 >> 2 ) - MEMS_Info.OutY;
GradZ = ( MEMS_Info.OutZ_F4 >> 2 ) - MEMS_Info.OutZ;
// Decide whether a direction is selected
if( tMovePtrX == 0 )
{
if( ( GradX > MIN_REACT ) || ( GradX < -MIN_REACT ) )
{
iMovePtrX = GradX / DIV_REACT;
tMovePtrX = DELAY_REACT;
fMovePtrX = 1;
}
}
else
{
tMovePtrX--;
}
if( tMovePtrY == 0 )
{
if( ( GradY > MIN_REACT ) || ( GradY < -MIN_REACT ) )
{
iMovePtrY = GradY / DIV_REACT; //FL071012 rrm fix
tMovePtrY = DELAY_REACT;
fMovePtrY = 1;
}
}
else
{
tMovePtrY--;
}
if( tMovePtrZ==0 )
{
if( ( GradZ > MIN_REACT ) || ( GradY < -MIN_REACT ) )
{
iMovePtrZ = GradZ / DIV_REACT;
tMovePtrZ = DELAY_REACT;
fMovePtrZ = 1;
}
}
else
{
tMovePtrZ--;
}
Gradient2 = (s32)GradX * (s32)GradX + (s32)GradY * (s32)GradY + (s32)GradZ * (s32)GradZ;
// MEMS is shocked, let's beep!
if( ( Gradient2 > GRAD_SHOCK ) && ( BUZZER_GetMode() == BUZZER_OFF ) && ( StartingFromResetOrShockCounter == 0 ) )
{
MEMS_Info.Shocked++;
/*FL071007 = 1;
Suggested by Bob Seabrook: a further posiblity is to increment Shocked rather than just setting it
So it can still be tested for non zero as before but one can get more
info from the int without extra cost. */
#define DELAY_BETWEEN_TWO_SHOCK 20
#define MAX_DELAY_FOR_DOUBLECLICK 150
StartingFromResetOrShockCounter = DELAY_BETWEEN_TWO_SHOCK; //< filter: short delay before detecting the next shock
if ( (TimeCounterForDoubleClick - TimeLastShock) < MAX_DELAY_FOR_DOUBLECLICK )
{
MEMS_Info.DoubleClick++;
TimeLastShock = 0;
}
else
{
TimeLastShock = TimeCounterForDoubleClick;
}
BUZZER_SetMode( BUZZER_SHORTBEEP );
}
}
/*******************************************************************************
*
* MEMS_ReadID
*
*******************************************************************************/
/**
* Reads SPI chip identification.
*
* @return The SPI chip identification.
*
**/
/******************************************************************************/
u8 MEMS_ReadID( void )
{
u8 Temp = 0;
/* Chip Select low */
MEMS_ChipSelect( LOW );
/* Send "RDID" instruction */
MEMS_SendByte( RDID );
/* Read a byte from the MEMS */
Temp = MEMS_SendByte( DUMMY_BYTE );
/* Chip Select low */
MEMS_ChipSelect( HIGH );
return Temp;
}
/// @endcond
/* Public functions ----------------------------------------------------------*/
/*******************************************************************************
*
* MEMS_GetPosition
*
*******************************************************************************/
/**
*
* Returns the current (relative) position of the Primer.
* Only X-Y axis are considered here.
*
* @param[out] pX Current horizontal coordinate.
* @param[out] pY Current vertical coordinate.
*
* @warning The (0x0) point in on the low left corner.
* @note For absolute position information use MEMS_GetInfo()
*
**/
/******************************************************************************/
void MEMS_GetPosition( s16* pX, s16* pY )
{
*pX = MEMS_Info.OutX - XInit;
*pY = MEMS_Info.OutY - YInit;
}
/*******************************************************************************
*
* MEMS_GetRotation
*
*******************************************************************************/
/**
*
* Returns current screen orientation.
*
* @param[out] pH12 Current screen orientation.
*
**/
/******************************************************************************/
void MEMS_GetRotation( Rotate_H12_V_Match_TypeDef* pH12 )
{
s16 sX = MEMS_Info.OutX;
s16 sY = MEMS_Info.OutY;
if( ( ( sX <= -MARGIN ) && ( sY <= 0 ) && (sX<=sY ) ) ||
( ( sX <=- MARGIN ) && ( sY > 0) && (sX <= (-sY ) ) ) )
{
// 1st case: x<0, |x|>y => H12 = V9
*pH12 = V9;
}
else if( ( ( sY <= -MARGIN ) && ( sX <= 0 ) && ( sY <= sX ) ) ||
( ( sY <= -MARGIN ) && ( sX > 0 ) && ( sY <= (-sX ) ) ) )
{
// 2nd case: y<0, |y|>x => H12 = V12
*pH12 = V12;
}
else if( ( ( sX >= MARGIN ) && ( sY <= 0 ) && ( sX >= (-sY) ) ) ||
( ( sX >= MARGIN ) && ( sY > 0 ) && ( sX >= sY ) ) )
{
// 3rd case: x>0, |x|>y => H12=V3
*pH12 = V3;
}
else if( ( ( sY >= MARGIN ) && ( sX <= 0 ) && ( sY >= (-sX ) ) ) ||
( ( sY >= MARGIN ) && ( sX > 0 ) && ( sY >= sX ) ) )
{
// 4th case: y>0, |y|>x => H12=V6
*pH12 = V6;
}
}
/*******************************************************************************
*
* MEMS_SetNeutral
*
*******************************************************************************/
/**
*
* Set current position as "neutral position".
*
**/
/******************************************************************************/
void MEMS_SetNeutral( void )
{
// Set Neutral position.
MEMS_GetPosition( &XInit, &YInit );
}
/*******************************************************************************
*
* MEMS_GetInfo
*
*******************************************************************************/
/**
*
* Return the current MEMS information (state, absolute position...).
*
* @return a pointer to tMEMS_Info
*
**/
/******************************************************************************/
tMEMS_Info* MEMS_GetInfo( void )
{
return &MEMS_Info;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -