📄 i2c.c
字号:
/********************************************/
/* I2C.c: implementation of the I2C API. */
/* Author : qzsu */
/* Time : 2006-08-21 */
/********************************************/
#include <string.h>
#include <platform.h>
#include "i2c.h"
#ifdef I2C_WINCE
#include <windows.h>
#include <ceddk.h>
#include <Pkfuncs.h>
#endif
#define PHY_I2C_BASE 0x20036000
#define PIN_MASKBASE 0x20020000
U8 *g_i2c_base;
U32 *pinmark = NULL;
void I2C_delay(U32 us)
{
U32 count;
count = 22;//266/12(1us)
while(us--)
{
while(count--);
}
}
void I2C_MsDelay(U32 n)
{
volatile U32 i = 50000*n;
while(i--);
}
// Receive FIFO Completely Full
bool IsRFF(void);
// Receive FIFO Not Empty
bool IsRFNE(void);
// Transmit FIFO Completely Empty
bool IsTFE(void);
/* The following API are used to access the State Register*/
// Receive FIFO Completely Full
bool IsRFF(void)
{
if(I2C_STATUS & RFF)
{
return true;
}
else
{
return false;
}
}
// Receive FIFO Not Empty
bool IsRFNE(void)
{
if(I2C_STATUS & RFNE)
{
return true;
}
else
{
return false;
}
}
// Transmit FIFO Completely Empty
bool IsTFE(void)
{
if(I2C_STATUS & TFE)
{
return true;
}
else
{
return false;
}
}
//end the state Register API
void I2C_PinMask( U32 enable )
{
// volatile int* pinmark = NULL;
#ifdef I2C_WINCE
// pinmark = (volatile int*)hw_map_io( PIN_MASKBASE , 0x1000 , 0 );
// RETAILMSG(1,(_T("pinmark:%x\r\n"),pinmark));
I2C_MsDelay(1);
#else
pinmark = (U32*) PIN_MASKBASE;
#endif
if( pinmark )
{
if( enable )
pinmark[0x10c/4] |= 0x400;
else
pinmark[0x10c/4] &= ~0x400;
}
}
/* brief : Initialize the I2C module */
void InitI2C(void)
{
#ifdef I2C_WINCE
//g_i2c_base = (U8 *)(hw_map_io(PHY_I2C_BASE, 0x1000, 0));
//pinmark = (U32*)hw_map_io( PIN_MASKBASE , 0x1000 , 0 );
g_i2c_base = (U8 *)((U32)VA_IIC_BASE );
pinmark = (U32*)((U32)VA_SYSCTRL_BASE);
// RETAILMSG(1,(_T("g_i2c_base:%x\r\n"),g_i2c_base));
I2C_MsDelay(1);
#else
g_i2c_base = (U8*)PHY_I2C_BASE;
#endif
// Define the Initialize parameters
//Disable the I2C MASTER
I2C_DISABLE;
//Set the address if targeted as a slave
// I2C_SAR(0x0045);
//Set the control register for the transfer
I2C_CON(0x0003);
//-: Set the High period for the SCL
//(we have 10 MHz ic_clk) if we want 100kbps , SS_HCNT = 0x0028
//Set the Low period for the SCL
//(we have 10 MHz ic_clk) if we want 100kbps , SS_LCNG =0x002f
I2C_SS_HCNT(0x0028);
I2C_SS_LCNT(0x002f);
//Set the address for the target register(slave)
// I2C_TAR(0x0056);
//Enable interrupts
I2C_INTR_MASK(0);
//Set Rx FIFO Threshold
I2C_RX_TL(0);
//Set Tx FIFO Threshold
I2C_TX_TL(0);
//Enable the I2C MASTER
I2C_ENABLE;
}
void DeleteI2C(void)
{
#ifdef I2C_WINCE
if(g_i2c_base)
{
//hw_unmap_io(g_i2c_base , 0x1000);
}
if(pinmark)
{
//hw_unmap_io( (void*)pinmark , 0x1000);
}
#endif
}
/* brief: This API is used to transmit data
** para : threhold -- the threhole of the FIFO
** para : buffer -- the pointer of data
** para : target -- the address of the target
** ret : retvalue is 1 means , threhold value is not illegal;
*/
int TransmitData(const int threhold, const unsigned char buffer[], const unsigned short target)
{
int i;
if(!g_i2c_base)
{
#ifdef I2C_WINCE
RETAILMSG(1, (TEXT("+RTC_Init_Write Fail \r\n")));
#endif
return -1;
}
if(threhold < 0 || threhold >255)
{
return -1;
}
I2C_DISABLE;
I2C_TX_TL((threhold-1));
I2C_TAR(target);
I2C_ENABLE;
while(!IsTFE());
i=0;
while(i < threhold)
{
I2C_WRITE (buffer[i++]);
while(!IsTFE());
}
return 0;
}
int ReadData(const int threhold, const unsigned char buffer[], const unsigned short target)
{
volatile int retValue = 0 ,i;
if(!g_i2c_base)
{
#ifdef I2C_WINCE
RETAILMSG(1, (TEXT("+RTC_Init_Read Fail \r\n")));
#endif
return -1;
}
//dw
if(threhold < 0 || threhold >255){
retValue = -1;
return retValue;
}
I2C_DISABLE;
I2C_TX_TL((threhold-1));
I2C_TAR(target);
I2C_ENABLE;
while(!IsTFE());
//wa
i=0;
while(i < threhold)
{
I2C_WRITE (buffer[i++]);
while(!IsTFE());
}
//sr
I2C_CON(I2CR_CON | 0x20);//IC_RESTART_EN
//dr
while(!IsTFE());
I2C_WRITE(0x168); //read operation
while(!IsTFE());
//data
while(!IsRFNE());
while(IsRFF());
retValue = I2C_READ;
return retValue;
}
BOOL OALI2C_Read(UINT32 code, VOID *pInpBuffer, UINT32 inpSize,
void *pOutBuffer, UINT32 outSize, UINT32 *pOutSize)
{
BYTE *pIn = (BYTE *)pInpBuffer;
BYTE *pOut = (BYTE *)pOutBuffer;
if(!(inpSize >= 2 && outSize)) //In:SlaveAddr,Addr Out:Data
return FALSE;
I2C_PinMask( 1 ); // enable i2c pin mask
*pOut = ReadData(inpSize - 1, pIn, pIn[inpSize - 1] >> 1);
I2C_MsDelay(1);
I2C_PinMask( 0 ); // disable i2c pin mask
I2C_MsDelay(10);
if(pOutSize)
*pOutSize = 1;
return TRUE;
}
BOOL OALI2C_Write(UINT32 code, VOID *pInpBuffer, UINT32 inpSize,
VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize)
{
BYTE *pIn = (BYTE *)pInpBuffer;
if(inpSize < 3) //In:SlaveAddr,Addr,Data Out:No
return FALSE;
I2C_PinMask( 1 ); // enable i2c pin mask
I2C_MsDelay(1);
TransmitData(inpSize - 1, pIn, pIn[inpSize - 1] >> 1);
I2C_MsDelay(1);
I2C_PinMask( 0 ); // disable i2c pin mask
I2C_MsDelay(10);
if(pOutSize)
*pOutSize = 0;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -