📄 fsl_mma_iic.c
字号:
/*********************************************************************
(c) copyright Freescale Semiconductor Ltd. 2008
ALL RIGHTS RESERVED
********************************************************************
Ver 0 Initial release
********************************************************************/
#ifdef G_SENSOR_SUPPORT
#include "kal_release.h"
#include "custom_config.h"
#include "gpio_sw.h" //Hardware IO interface
#include "kal_trace.h"
#include "stack_common.h"
#include "stack_msgs.h"
#include "app_ltlcom.h" /* Task message communiction */
#include "syscomp_config.h"
#include "task_config.h" /* Task creation */
#include "app_buff_alloc.h" /* Declaration of buffer management API */
#include "stacklib.h" /* Basic type for dll, evshed, stacktimer */
#include "event_shed.h" /* Event scheduler */
#include "stack_timer.h" /* Stack timer */
#include "FSL_data.h"
#include "MMA7455L.h"
#define VT_DEUBG 0
#define ACC_DEBUG 1
#define VT_ACC_SENSOR_SCK 39
#define VT_ACC_SENSOR_SDA 38
#define SET_I2C_CLK_OUTPUT GPIO_InitIO(1, VT_ACC_SENSOR_SCK)//Need to be change
#define SET_I2C_DATA_OUTPUT GPIO_InitIO(1, VT_ACC_SENSOR_SDA) //Need to be change
#define SET_I2C_DATA_INPUT GPIO_InitIO(0, VT_ACC_SENSOR_SDA) //Need to be change
#define SET_I2C_CLK_HIGH GPIO_WriteIO(1, VT_ACC_SENSOR_SCK)//Need to be change
#define SET_I2C_CLK_LOW GPIO_WriteIO(0, VT_ACC_SENSOR_SCK) //Need to be change
#define SET_I2C_DATA_HIGH GPIO_WriteIO(1, VT_ACC_SENSOR_SDA) //Need to be change
#define SET_I2C_DATA_LOW GPIO_WriteIO(0, VT_ACC_SENSOR_SDA) //Need to be change
#define GET_I2C_DATA_BIT GPIO_ReadIO(VT_ACC_SENSOR_SDA)
#define MMA745xL_AddW 0x3A//0x38
#define MMA745xL_AddR 0x3B//0x39
//FOLLOWING DATA IS TOO BIG FOR UINT8
#define Delay20us 4400//95
#define Delay10us 2200//45
#define Delay5us 1100//21
#define Delay2p5us 550//10
/*
if you change the parameter to be UINT16, it will crash while doing TURN-OVER or FLIP
So still keep it in UINT8 even though it will make warning while compiling.
*/
void mma_delay(UINT8 time)
{
UINT8 i;
for (i=0; i<time; i++) ;
}
void mma745x_init()
{
GPIO_ModeSetup(VT_ACC_SENSOR_SCK, 0x00);
SET_I2C_CLK_OUTPUT;
SET_I2C_CLK_HIGH;
GPIO_ModeSetup(VT_ACC_SENSOR_SDA, 0x00);
SET_I2C_DATA_OUTPUT;
SET_I2C_DATA_HIGH;
}
void IIC_Start(void)
{
GPIO_ModeSetup(VT_ACC_SENSOR_SCK, 0);
SET_I2C_CLK_OUTPUT;
GPIO_ModeSetup(VT_ACC_SENSOR_SDA, 0);
SET_I2C_DATA_OUTPUT;
SET_I2C_DATA_HIGH;
mma_delay(Delay10us);
SET_I2C_CLK_HIGH;
mma_delay(Delay20us);
SET_I2C_DATA_LOW;
mma_delay(Delay10us);
SET_I2C_CLK_LOW;
mma_delay(Delay10us);
}
void IIC_Stop (void)
{
mma_delay(Delay10us);
SET_I2C_CLK_HIGH;
mma_delay(Delay10us);
SET_I2C_DATA_HIGH;
}
void IIC_RepeatedStart(void)
{
mma_delay(Delay20us);
mma_delay(Delay20us);
SET_I2C_DATA_HIGH;
mma_delay(Delay10us);
SET_I2C_CLK_HIGH;
mma_delay(Delay20us);
mma_delay(Delay20us);
SET_I2C_DATA_LOW;
mma_delay(Delay10us);
SET_I2C_CLK_LOW;
mma_delay(Delay10us);
}
void IIC_OneClk(void)
{
mma_delay(Delay5us);
SET_I2C_CLK_HIGH;
mma_delay(Delay10us);
SET_I2C_CLK_LOW;
mma_delay(Delay5us);
}
void IIC_SendByte(UINT8 sData)
{
UINT8 i;
#if 0
for (i=8; i>0; i--)
{
if ((sData>>i)&0x01)
{
SET_I2C_DATA_HIGH;
}
else
{
SET_I2C_DATA_LOW;
}
IIC_OneClk();
}
#else
for (i=0; i<8; i++)
{
if (sData&0x80)
{
SET_I2C_DATA_HIGH;
}
else
{
SET_I2C_DATA_LOW;
}
sData <<= 1;
IIC_OneClk();
}
#endif
}
UINT8 IIC_ChkAck(void)
{
SET_I2C_DATA_INPUT;
mma_delay(Delay5us);
SET_I2C_CLK_HIGH;
mma_delay(Delay5us);
if (GET_I2C_DATA_BIT)
{
mma_delay(Delay5us);
SET_I2C_CLK_LOW;
mma_delay(Delay5us);
SET_I2C_DATA_OUTPUT;
SET_I2C_DATA_LOW;
return 1;
}
else
{
mma_delay(Delay5us);
SET_I2C_CLK_LOW;
mma_delay(Delay5us);
SET_I2C_DATA_OUTPUT;
SET_I2C_DATA_LOW;
return 0;
}
}
UINT8 IIC_ReadByteACK(void)
{
UINT8 i;
UINT8 data;
SET_I2C_DATA_INPUT;
data = 0;
for (i=0; i<8; i++)
{
data=data<<1;
if (GET_I2C_DATA_BIT)
data |= 0x01;
IIC_OneClk();
}
SET_I2C_DATA_OUTPUT;
SET_I2C_DATA_LOW;
IIC_OneClk();
return data;
}
UINT8 IIC_ReadByteNCK(void)
{
UINT8 i;
UINT8 data;
SET_I2C_DATA_INPUT;
data = 0;
for (i=0; i<8; i++)
{
data=data<<1;
if (GET_I2C_DATA_BIT)
data |= 0x01;
IIC_OneClk();
}
SET_I2C_DATA_OUTPUT;
SET_I2C_DATA_HIGH;
IIC_OneClk();
SET_I2C_DATA_LOW;
return data;
}
// Master Write
void mma745x_IICWrite(UINT8 RegAdd, UINT8 Data)
{
//Start
IIC_Start();
// Device hardware address
IIC_SendByte(MMA745xL_AddW);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Write Address Error #\r\n");
#endif
IIC_Stop();
return;
}
// Register address to read
IIC_SendByte(RegAdd);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Reg Address NACK #\r\n");
#endif
IIC_Stop();
return;
}
// Data to send
IIC_SendByte(Data);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Data NACK #\r\n");
#endif
IIC_Stop();
return;
}
// Stop
IIC_Stop();
}
// Master Read
INT8 mma745x_IICRead(UINT8 RegAdd)
{
INT8 Data;
//Start
IIC_Start();
// Device hardware address
IIC_SendByte(MMA745xL_AddW);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Write Address Error #\r\n");
#endif
IIC_Stop();
return 1;
}
// Register address to read
IIC_SendByte(RegAdd);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Reg Address NACK #\r\n");
#endif
IIC_Stop();
return 2;
}
// Repeated Start
IIC_RepeatedStart();
// Device hardware address
IIC_SendByte(MMA745xL_AddR);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Read Address Error #\r\n");
#endif
IIC_Stop();
return 3;
}
Data = IIC_ReadByteNCK();
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read Data = %d #\r\n", Data);
#endif
// Stop
IIC_Stop();
return Data;
}
// Read XYZ 8bit Registers
UINT8 mma745x_ReadXYZ8(INT8 *X, INT8 *Y, INT8 *Z)
{
//Start
IIC_Start();
// Device hardware address
IIC_SendByte(MMA745xL_AddW);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Write Address Error #\r\n");
#endif
IIC_Stop();
return 0;
}
// Register address to read
IIC_SendByte(0x06);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Reg Address NACK #\r\n");
#endif
IIC_Stop();
return 1;
}
// Repeated Start
IIC_RepeatedStart();
// Device hardware address
IIC_SendByte(MMA745xL_AddR);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Read Address Error #\r\n");
#endif
IIC_Stop();
return 2;
}
*X = IIC_ReadByteACK();
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read X Data = %d #\r\n", *X);
#endif
*Y = IIC_ReadByteACK();
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read Y Data = %d #\r\n", *Y);
#endif
*Z = IIC_ReadByteNCK();
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read Z Data = %d #\r\n", *Z);
#endif
// Stop
IIC_Stop();
return 3;
}
// Read XYZ 10bit Registers
UINT8 mma745x_ReadXYZ10(INT16 *X, INT16 *Y, INT16 *Z)
{
INT16 temp;
//Start
IIC_Start();
// Device hardware address
IIC_SendByte(MMA745xL_AddW);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Write Address Error #\r\n");
#endif
IIC_Stop();
return 0;
}
// Register address to read
IIC_SendByte(0x00);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Reg Address NACK #\r\n");
#endif
IIC_Stop();
return 1;
}
// Repeated Start
IIC_RepeatedStart();
// Device hardware address
IIC_SendByte(MMA745xL_AddR);
if (IIC_ChkAck())
{
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Device Read Address Error #\r\n");
#endif
IIC_Stop();
return 2;
}
*X = (INT16)IIC_ReadByteACK();
temp = (INT16)IIC_ReadByteACK();
*X += (temp<<8);
if (*X&0x0200) *X |= 0xfc00;
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read X Data = %d #\r\n", *X);
#endif
*Y = (INT16)IIC_ReadByteACK();
temp = (INT16)IIC_ReadByteACK();
*Y += (temp<<8);
if (*Y&0x0200) *Y |= 0xfc00;
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read Y Data = %d #\r\n", *Y);
#endif
*Z = (INT16)IIC_ReadByteACK();
temp = (INT16)IIC_ReadByteNCK();
*Z += (temp<<8);
if (*Z&0x0200) *Z |= 0xfc00;
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "# MMA7455L Read Z Data = %d #\r\n", *Z);
#endif
// Stop
IIC_Stop();
return 3;
}
void MMA745x_Testing_SCL_Waveform(void)
{
GPIO_ModeSetup(VT_ACC_SENSOR_SCK, 0x00);
SET_I2C_CLK_OUTPUT;
while (1)
{
SET_I2C_CLK_HIGH;
mma_delay(Delay20us);
SET_I2C_CLK_LOW;
mma_delay(Delay20us);
SET_I2C_CLK_HIGH;
mma_delay(Delay10us);
SET_I2C_CLK_LOW;
mma_delay(Delay10us);
SET_I2C_CLK_HIGH;
mma_delay(Delay5us);
SET_I2C_CLK_LOW;
mma_delay(Delay5us);
}
}
void MMA745x_Testing_SDA_Waveform(void)
{
GPIO_ModeSetup(VT_ACC_SENSOR_SCK, 0x00);
SET_I2C_DATA_OUTPUT;
while (1)
{
SET_I2C_DATA_HIGH;
mma_delay(Delay20us);
SET_I2C_DATA_LOW;
mma_delay(Delay20us);
SET_I2C_DATA_HIGH;
mma_delay(Delay10us);
SET_I2C_DATA_LOW;
mma_delay(Delay10us);
SET_I2C_DATA_HIGH;
mma_delay(Delay5us);
SET_I2C_DATA_LOW;
mma_delay(Delay5us);
}
}
VUINT8 MMA745x_Read_RawData(VINT16 *pX, VINT16 *pY, VINT16 *pZ)
{
if(!Data_Is_Ready()) return 0; // Check whether data is ready
mma745x_ReadXYZ10(pX, pY, pZ); // Read 10-bit g-values and change to 16-bit signed data
return 1;
}
VUINT8 MMA745x_Test_IIC_Read_and_Write(void)
{
UINT8 old_value = 0;
UINT8 read_value = 0;
UINT8 write_value = 0x45;
old_value = mma745x_IICRead(MCTL);
//Test case
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "[read] old value = %d", old_value);
#endif
mma745x_IICWrite(MCTL, 0x45);
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "[write] old value = %d", write_value);
#endif
read_value = mma745x_IICRead(MCTL);
#ifdef ACC_DEBUG
kal_prompt_trace(MOD_SOC, "[read] new value = %d", read_value);
#endif
mma745x_IICWrite(MCTL, old_value);
if (read_value == write_value)
{
return 1;
}
else
{
return 0;
}
}
#if VT_DEUBG
void VT_TEST_IIC_READ_AND_WIRTE(void)
{
/* used to test IIC read and write */
int i,count = 10;
UINT8 value = 0;
UINT8 write_value = 0x45;
for(i = 0; i < 10; i++)
{
mma745x_IICWrite(0x16, write_value); // Enable measurment mode
kal_prompt_trace(MOD_SOC, "[%d] [WRITE] value = %d", i+1,write_value);
value = mma745x_IICRead(0x16);
kal_prompt_trace(MOD_SOC, "[%d] [READ] value = %d", i+1,value);
write_value++;
}
}
void VT_TEST_MMA7455L(void)
{
INT8 DX8, DY8, DZ8;
mma745x_init();
mma745x_IICWrite(0x16, 0x45); // Enable measurment mode
DX8 = mma745x_IICRead(0x06); // Read X
DY8 = mma745x_IICRead(0x07); // Read Y
DZ8 = mma745x_IICRead(0x08); // Read Z
//kal_prompt_trace();
mma745x_ReadXYZ8(&DX8, &DY8, &DZ8);
}
void VT_INIT_MMA7455L(void)
{
mma745x_init();
mma745x_IICWrite(0x16, 0x45); // Enable measurment mode
}
#endif
#endif /* G_SENSOR_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -