/*****************************************************************************
*
* (c) 2009 Freescale Inc.
* ALL RIGHTS RESERVED.
*
**************************************************************************//*!
*
* @file mma6900.c
* @version 1.0.1.0
* @date Jul-11-2011
* @author B20253
*
* @brief The device driver for accelerometer MMA6900
*
*****************************************************************************/
#include "mma6900.h"
#include "spi.h"
#include "main.h"
static Byte MMA6900_enabled = FALSE; //static 静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。
//且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
//其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束
MMA6900_MAIN_STR mmaValues;
MMA6900_READ_REG_STR MMA6900_read;
MMA6900_REG_STR regs_mma6900;
word cntResetDevres = 0;
static SPI_regs* actual_spi;
// internal functions
void MMA6900_SetUp(byte reg_DEVCTL);
word MMA6900_RegAccessWordPrtcl2(byte);
word MMA6900_RegReadWordPrtcl2(void); //word 16位字节
word MMA6900_RegWriteWordPrtcl2(byte);
void MMA6900_Reset_DEVRES(void); //前面的void是说明函数是void类型即无返回值类型!后面的void是修饰符即说明main无参数传递
void MMA6900_ReadAllReg(void);
/***************************************************************************//*!
* @brief
*
* @param 参数
*
* @return
****************************************************************************/
void CopyToStructure6900(void)
{
byte* ptr_tmp = (byte*)&MMA6900_read.Regtest;
byte ix;
for(ix=0; ix<REGISTERS; ix++) //MMAD900H registers=26
{
if(ix != 0)
{
regs_mma6900.all_regs[ix] =*ptr_tmp;
ptr_tmp += 2;
}
}
}
/***************************************************************************//*!
*
* @brief MMA6900 initialization 初始化
*
* @param input 参数输入
*
* @return (nothing)
*
* @remarks call in main.c in initialization section 调用c初始化部分
*
****************************************************************************/
void MMA6900_Init(MODULES mod)
{
(void)mod;
if(mod == MODULE_A)
{
SPI_Init((SPI_regs*)p_SPI1C1);
actual_spi = (SPI_regs*)p_SPI1C1;
}
else if(mod == MODULE_B)
{
SPI_Init((SPI_regs*)p_SPI2C1);
actual_spi = (SPI_regs*)p_SPI2C1;
}
MMA6900_Reset_DEVRES();//重置
MMA6900_ReadAllReg(); //读取寄存器
MMA6900_SetUp(0x90);
MMA6900_enabled = TRUE;//启用
}
void MMA6900_DeInit(void)
{
MMA6900_enabled = FALSE;
}
word MMA6900_DisplayRegister(word tmp) //使用寄存器
{
MMA6900_READ_REG temp;
temp.MergedBits.Status=tmp>>8;
temp.MergedBits.Data=tmp&0x00FF;
return (temp.word);
}
/***************************************************************************//*!
* @brief 重置
*
* @param
*
* @return
****************************************************************************/
void MMA6900_Reset_DEVRES(void)
{
byte temp5L;
word temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9;
temp1=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVSTAT);
temp2=MMA6900_RegReadWordPrtcl2(); //16
MMA6900_read.RegDEVSTAT.word = MMA6900_DisplayRegister(temp2);
if(MMA6900_read.RegDEVSTAT.Bits.DEVRES==1)
{
cntResetDevres++;
temp3=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
temp4=MMA6900_RegReadWordPrtcl2(); //16
MMA6900_read.RegDEVCTL.word = MMA6900_DisplayRegister(temp4);
temp5=(word)(temp4|0x0020); //Set CE
temp5L=(byte)(temp5&0x00FF);
temp6=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
temp7=MMA6900_RegWriteWordPrtcl2(temp5L);
temp8=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVSTAT);
temp9=MMA6900_RegReadWordPrtcl2();
MMA6900_read.RegDEVSTAT.word = MMA6900_DisplayRegister(temp9);
}
}
/***************************************************************************//*!
* @brief
*
* @param
*
* @return
****************************************************************************/
void MMA6900_ReadAllReg(void)
{
REG_STR read_reg;
word* ptr_reg = &read_reg.reg_SN0.reg_check;
MMA6900_READ_REG* ptr_read = (MMA6900_READ_REG*)&MMA6900_read.Regtest;
const byte reg_addres[REGISTERS] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27};
byte index;
for(index=0; index<=REGISTERS; index++)
{
ptr_reg[index] = MMA6900_RegAccessWordPrtcl2(reg_addres[index]);
ptr_reg[index+1] = MMA6900_RegReadWordPrtcl2();
ptr_read[index].word = MMA6900_DisplayRegister(ptr_reg[index+1]);
}
}
void MMA6900_WriteToRegister(byte tmp)
{
MMA6900_SetUp(tmp);
}
/***************************************************************************//*!
* @brief 读取原始数据
*
* @param
*
* @return
****************************************************************************/
Byte MMA6900_ReadRawData(TWR_MMA6900* mma6900)
{
static byte last_write;
Byte ix;
if(MMA6900_enabled == FALSE)
{
mma6900->x = 0;
mma6900->y = 0;
for(ix=0; ix<MMA6900_REGS; ix++)
mma6900->all_regs[ix] = 0;
return 0;
}
MMA6900_ReadAllReg();
CopyToStructure6900();
(void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_X11L);
MMA6900_read.RegACC_X11L.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
mmaValues.x.bytes.Dgt11RegL = MMA6900_read.RegACC_X11L.MergedBits.Data;
(void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_X11H);
MMA6900_read.RegACC_X11H.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
mmaValues.x.bytes.Dgt11RegH = (MMA6900_read.RegACC_X11H.MergedBits.Data)&0x07;
(void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_Y11L);
MMA6900_read.RegACC_Y11L.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
mmaValues.y.bytes.Dgt11RegL = MMA6900_read.RegACC_Y11L.MergedBits.Data;
(void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_Y11H);
MMA6900_read.RegACC_Y11H.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
mmaValues.y.bytes.Dgt11RegH = (MMA6900_read.RegACC_Y11H.MergedBits.Data)&0x07;
mma6900->x = mmaValues.x.words.Dgt11Reg;
mma6900->y = mmaValues.y.words.Dgt11Reg;
for(ix=0; ix<MMA6900_REGS; ix++)
mma6900->all_regs[ix] = regs_mma6900.all_regs[ix];
if(mma6900->w_regs != last_write)
MMA6900_WriteToRegister(mma6900->w_regs);
last_write = mma6900->w_regs;
}
/***************************************************************************//*!
* @brief 奇偶校验
*
* @param
*
* @return
****************************************************************************/
byte MMA6900_Parity(word data)
{
byte x = 0;
do
{
if (data & 0x01)
x++;
}while(data >>= 1);//它先执行循环体中的语句,然后再判断条件是否为真。
//如果为真则继续循环,如果为假,则终止循环。
//因此,do-while循环至少要执行一次循环语句。
return (x&0x01 == 1) ? 0 : 1;
}
/***************************************************************************//*!
* @brief 设置
*
* @param
*
* @return
****************************************************************************/
void MMA6900_SetUp(byte reg_DEVCTL)
{
(void)MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
(void)MMA6900_RegWriteWordPrtcl2(reg_DEVCTL);
(void)MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
MMA6900_read.RegDEVCTL.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
}
/***************************************************************************//*!
* @brief
*
* @param
*
* @return
****************************************************************************/
word MMA6900_RegAccessWordPrtcl2(byte RegAdd)
{
byte tx_byte1,tx_byte2;
byte rx_byte1,rx_byte2;
word temp,rx_word;
temp = 0x1000; //Word created to compute parity 用来计算奇偶校验的
temp|=RegAdd; //Example: TEMP 0x0F
if(MMA6900_Parity(temp)) temp|=0x0400; //Parity added if required 如果需要奇偶校验
tx_byte1= (byte)(temp>>8);
tx_byte2= (byte)(temp&0x00FF);
SPI_Reset_SS(actual_spi); //SS2 = 0;
SPI_SendByte(tx_byte1, actual_spi);
rx_byte1=SPI_ReadByte(actual_spi);
SPI_SendByte(tx_byte2, actual_spi);
rx_byte2=SPI_ReadByte(actual_spi);
SPI_Set_SS(actual_spi); // SS2 = 1;
rx_word=rx_byte1<<8;
rx_word|=rx_byte2;
return(rx_word);
}
/***************************************************************************//*!
* @brief
*
* @param
*
* @return
****************************************************************************/
word MMA6900_RegReadWordPrtcl2(void)
{
byte tx_byte1,tx_byte2;
byte rx_byte1,rx_byte2;
word temp,rx_word;
temp = 0x2000; //Din 0x2000 (checked on scope 在检查范围)
tx_byte1= (byte)(temp>>8);
tx_byte2= (byte)(temp&0x00FF);
SPI_Reset_SS(actual_spi); //SS1=0;
SPI_SendByte(tx_byte1, actual_spi);
rx_byte1=SPI_ReadByte(actual_spi);
SPI_SendByte(tx_byte2, actual_spi);
rx_byte2=SPI_ReadByte(actual_spi);
SPI_Set_SS(actual_spi);//SS1=1;
rx_word = rx_byte1<<8;
rx_word |= rx_byte2;
return(rx_word);
}
/***************************************************************************//*!
* @brief
*
* @param
*
* @return
****************************************************************************/
word MMA6900_RegWriteWordPrtcl2(byte val)
{
byte p;
byte tx_byte1,tx_byte2;
byte rx_byte1,rx_byte2;
word temp,rx_word;
temp = 0x3000; //Word created to compute parity
temp|=val;
p=MMA6900_Parity(temp);
if(p) temp|=0x0400; //Parity added if required
tx_byte1= (byte)(temp>>8);
tx_byte2= (byte)(temp&0x00FF);
SPI_Reset_SS(actual_spi); // SS1=0;
SPI_SendByte(tx_byte1, actual_spi);
rx_byte1=SPI_ReadByte(actual_spi);
SPI_SendByte(tx_byte2, actual_spi);
rx_byte2=SPI_ReadByte(actual_spi);
SPI_Set_SS(actual_spi);// SS1=1;
rx_word=rx_byte1<<8;
rx_word|=rx_byte2;
return(rx_word);
}
/***************************************************************************//*!
* @brief 读取加速度数据X,Y
*
* @param
*
* @return
****************************************************************************/
word MMA6900_Read_AccPrtcl2(byte axis)
{
byte rx_byte1,rx_byte2;
byte tx_byte1,tx_byte2;
word temp,rx_word;
if(axis==0x00) temp = 0x4000; //Din 0x4000 seen on scope OK
if(axis==0x01) temp = 0x8000; //Din 0x8000 seen on scope OK
tx_byte1= (byte)(temp>>8);
tx_byte2= (byte)(temp&0x00FF);
SPI_Reset_SS(actual_spi);// SS1=0;
SPI_SendByte(tx_byte1, actual_spi);
rx_byte1=SPI_ReadByte(actual_spi);
SPI_SendByte(tx_byte2, actual_spi);
rx_byte2=SPI_ReadByte(actual_spi);
SPI_Set_SS(actual_spi);// SS1=1;
rx_word=rx_byte1<<8;
rx_word|=rx_byte2;
return(rx_word);
}