⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mems.c

📁 FreeRTOS - V5.1.1 Last Update: Nov 20 2008 http://sourceforge.net/projects/freertos/
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************* (C) COPYRIGHT 2007 RAISONANCE S.A.S. *******************/
/**
*
* @file     mems.c
* @brief    Mems Initialization and management
* @author   FL
* @date     07/2007
* @version  1.1
* @date     10/2007
* @version  1.5 various corrections reported by Ron Miller 
*
**/
/******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "circle.h"

/// @cond Internal

/* Private define ------------------------------------------------------------*/
#define RDOUTXL               0xE8  /*!< Multiple Read from OUTXL             */
#define WRCTRL_REG1           0x20  /*!< Single Write CTRL_REG                */
#define RDCTRL_REG1           0xA0  /*!< Single Read CTRL_REG                 */
#define RDID                  0x8F  /*!< Single Read WHO_AM_I                 */
#define LOW                   0x00  /*!< ChipSelect line low                  */
#define HIGH                  0x01  /*!< ChipSelect line high                 */
#define DUMMY_BYTE            0xA5
#define MEMS_DIVIDER          1
#define MEMS_TESTING_DIVIDER  101
#define MARGIN                500
#define DELAY_REACT           20
#define MIN_REACT             15
#define DIV_REACT             10
#define GRAD_SHOCK            200000

/* Private variables ---------------------------------------------------------*/
tMEMS_Info                          MEMS_Info                        = {0};   // structure definition in circle.h
int                                 TestingActive                    = 0;
int                                 StartingFromResetOrShockCounter  = 1000;
int                                 TimeCounterForDoubleClick        = 0;
int                                 TimeLastShock                    = 0;
static int                          divider                          = 0;
static Rotate_H12_V_Match_TypeDef   previous_Screen_Orientation;
u32                                 Gradient2;

//Filtering
unsigned                            N_filtering                      = 0;

//Gradient
s16                                 GradX                            = 0;
s16                                 GradY                            = 0;
s16                                 GradZ                            = 0;

// Pointer move:
// each coordinate (X, Y and Z) is described by 3 variables where suffix means:
//  f = flag to indicate that a move has been done. Cleared by the Ptr Manager when acknowledged.
//  i = amplitude of the move (Grad / 10)
//  t = delay to accept the counter reaction
int fMovePtrX; 
int iMovePtrX;
int tMovePtrX;
int fMovePtrY;
int iMovePtrY;
int tMovePtrY;
int fMovePtrZ;
int iMovePtrZ;
int tMovePtrZ;

s16 XInit      = 0;
s16 YInit      = 0;
s16 ZInit      = 0;

/* Private function prototypes -----------------------------------------------*/
static void MEMS_ChipSelect( u8 State );
static u8 MEMS_SendByte( u8 byte );
static void MEMS_WriteEnable( void );
static u32 MEMS_ReadOutXY( void );
static void MEMS_WakeUp( void );

/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
*
*                                MEMS_WakeUp
*
*******************************************************************************/
/**
*  Wake Up Mems.
*
**/
/******************************************************************************/
static void MEMS_WakeUp( void )
   {
   u8 reg_val;

   /* read RDCTRL_REG1 */

   /* Chip Select low */
   MEMS_ChipSelect( LOW );

   /* Send "RDCTRL_REG1" instruction */
   MEMS_SendByte( RDCTRL_REG1 );

   reg_val = MEMS_SendByte( DUMMY_BYTE );

   /* Chip Select high */
   MEMS_ChipSelect( HIGH );

   /* SET P0:P1 to '11' */
   /* 0xC0 to wake up and 0x30 for full speed frequency (640 Hz). */
   reg_val = reg_val | 0xC0 | 0x30;

   /* Chip Select low */
   MEMS_ChipSelect( LOW );

   /* Send "WRCTRL_REG1" instruction */
   MEMS_SendByte( WRCTRL_REG1 );
   MEMS_SendByte( reg_val );

   /* Chip Select high */
   MEMS_ChipSelect( HIGH );
   }

/*******************************************************************************
*
*                                MEMS_ReadOutXY
*
*******************************************************************************/
/**
*  Reads X and Y Out.
*
*  @return An unsigned 32 bit word with the highest 16 bits containing the Y
*          and the lowest 16 bits the X.
*
**/
/******************************************************************************/
static u32 MEMS_ReadOutXY( void )
   {
   u8 OutXL;
   u8 OutXH;
   u8 OutYL;
   u8 OutYH;
   u8 OutZL;
   u8 OutZH;

   /* Chip Select low */
   MEMS_ChipSelect( LOW );

   /* Send "RDOUTXL" instruction */
   MEMS_SendByte( RDOUTXL );

   /* Read a byte */
   OutXL = MEMS_SendByte( DUMMY_BYTE );

   /* Read a byte */
   OutXH = MEMS_SendByte( DUMMY_BYTE );

   /* Read a byte */
   OutYL = MEMS_SendByte( DUMMY_BYTE );

   /* Read a byte */
   OutYH = MEMS_SendByte( DUMMY_BYTE );

   /* Read a byte */
   OutZL = MEMS_SendByte( DUMMY_BYTE );

   /* Read a byte */
   OutZH = MEMS_SendByte( DUMMY_BYTE );

   MEMS_Info.OutX =  OutXL + ( OutXH << 8 );
   MEMS_Info.OutY =  OutYL + ( OutYH << 8 );
   MEMS_Info.OutZ =  OutZL + ( OutZH << 8 );

   /* Chip Select high */
   MEMS_ChipSelect( HIGH );

   MEMS_Info.OutX_F4 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F4 >> 2 ) ); // Filter on 4 values.
   MEMS_Info.OutY_F4 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F4 >> 2 ) ); // Filter on 4 values.
   MEMS_Info.OutZ_F4 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F4 >> 2 ) ); // Filter on 4 values.

   MEMS_Info.OutX_F16 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F16 >> 4 ) ); // Filter on 16 values.
   MEMS_Info.OutY_F16 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F16 >> 4 ) ); // Filter on 16 values.
   MEMS_Info.OutZ_F16 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F16 >> 4 ) ); // Filter on 16 values.

   MEMS_Info.OutX_F64 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F64 >> 6 ) ); // Filter on 64 values.
   MEMS_Info.OutY_F64 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F64 >> 6 ) ); // Filter on 64 values.
   MEMS_Info.OutZ_F64 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F64 >> 6 ) ); // Filter on 64 values.

   MEMS_Info.OutX_F256 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F256 >> 8) ); // Filter on 256 values.
   MEMS_Info.OutY_F256 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F256 >> 8) ); // Filter on 256 values.
   MEMS_Info.OutZ_F256 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F256 >> 8) ); // Filter on 256 values.

   if( N_filtering < 256 )
      {
      // Just to validate the calculated average values.
      N_filtering++; 
      }

   return ( MEMS_Info.OutX + ( MEMS_Info.OutY << 16 ) );
   }

/*******************************************************************************
*
*                                MEMS_ChipSelect
*
*******************************************************************************/
/**
*  Selects or deselects the MEMS device.
*
*  @param[in]  State Level to be applied on ChipSelect pin.
*
**/
/******************************************************************************/
static void MEMS_ChipSelect( u8 State )
   {
   /* Set High or low the chip select line on PA.4 pin */
   GPIO_WriteBit( GPIOD, GPIO_Pin_2, (BitAction)State );
   }

/*******************************************************************************
*
*                                MEMS_SendByte
*
*******************************************************************************/
/**
*  Sends a byte through the SPI interface and return the byte received from 
*  the SPI bus.
*
*  @param[in]  byte The byte to send to the SPI interface.                  
*
*  @return The byte returned by the SPI bus.
*
**/
/******************************************************************************/
static u8 MEMS_SendByte( u8 byte )
   {
   /* Loop while DR register in not emplty */
   while( SPI_GetFlagStatus( SPI2, SPI_FLAG_TXE ) == RESET );

   /* Send byte through the SPI2 peripheral */
   SPI_SendData( SPI2, byte );

   /* Wait to receive a byte */
   while( SPI_GetFlagStatus( SPI2, SPI_FLAG_RXNE ) == RESET );

   /* Return the byte read from the SPI bus */
   return SPI_ReceiveData( SPI2 );
   }

/* Public functions for CircleOS ---------------------------------------------*/

/*******************************************************************************
*
*                                MEMS_Init
*
*******************************************************************************/
/**
*
*  Initializes the peripherals used by the SPI MEMS driver.
*
*  @attention  This function must <b>NOT</b> be called by the user.
*
**/
/******************************************************************************/
void MEMS_Init(void)
{
   SPI_InitTypeDef  SPI_InitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;

   /* Configure PC6 and PC7 as Output push-pull For MEMS*/
   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;

   GPIO_Init( GPIOC, &GPIO_InitStructure );

   /* Enable SPI2 and GPIOA clocks */
   RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2,  ENABLE );
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE );

   /* Configure SPI2 pins: SCK, MISO and MOSI */
   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;

   GPIO_Init( GPIOB, &GPIO_InitStructure );

   /* Configure PD2 as Output push-pull, used as MEMS Chip select */
   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;

   GPIO_Init( GPIOD, &GPIO_InitStructure );

   /* SPI2 configuration */
   SPI_InitStructure.SPI_Direction           = SPI_Direction_2Lines_FullDuplex;
   SPI_InitStructure.SPI_Mode                = SPI_Mode_Master;
   SPI_InitStructure.SPI_DataSize            = SPI_DataSize_8b;
   SPI_InitStructure.SPI_CPOL                = SPI_CPOL_High;
   SPI_InitStructure.SPI_CPHA                = SPI_CPHA_2Edge;
   SPI_InitStructure.SPI_NSS                 = SPI_NSS_Soft;
   SPI_InitStructure.SPI_BaudRatePrescaler   = SPI_BaudRatePrescaler_256;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -