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

📄 fsl_mma_iic.c

📁 mtk 3D动力传感器驱动源码
💻 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 + -