📄 hi_i2c.c
字号:
/****************************************************************************** Copyright (C), 2001-2011, Hisilicon Tech. Co., Ltd. ****************************************************************************** File Name : hi_i2c.c Version : Initial Draft Author : Hisilicon multimedia software group Created : 2003/09/25 Last Modified : Description : Provides to access and initialize the I2C interface Function List : I2C_Init I2C_SerialRead I2C_SerialWrite I2C_Read I2C_Write History : 1.Date : 2003/09/25 Author : yuanyabin Modification: Created file 2.Date : 2005/08/18 Author : zhouaidi(42136) Modification: 1、加入taskDelay for linux; 2、修改hi_i2c.h, hi_i2c_h中的HI_IN、HI_OUT、HI_IO为IN、OUT、IO; 3、在hi_i2c.c头部包含"hi.h"" 4、在I2C_SerialWrite中加入100ms的延时,解决Linux下IIC配置VAD不成功的问题。******************************************************************************/#include <config.h>#if defined(CONFIG_HI3510_LOGO)#include "hi_common/hi.h"#include "hi_inc.h"#include "hi_i2c.h"#ifdef OS_LINUX#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#endif#ifdef OS_LINUX #define taskDelay(x) usleep(x*10000)#endif #define taskDelay(x) udelay(x*100)/* Register read macro definition */#ifndef IIC_REG_READ#define IIC_REG_READ(reg,result) \ ((result) = *(volatile UINT32 *)(reg))#endif /* Register write macro definition */#ifndef IIC_REG_WRITE#define IIC_REG_WRITE(reg,data) \ (*((volatile UINT32 *)(reg)) = (data))#endifunsigned int I2C_BASE_MMAP; /* addr after mapped *//* IIC registers */#define IIC_CON (I2C_BASE_MMAP+0x00) /*IIC control reg*/#define IIC_TAR (I2C_BASE_MMAP+0x04) /*slave chip address reg*/#define IIC_HCNT (I2C_BASE_MMAP+0x14)#define IIC_LCNT (I2C_BASE_MMAP+0x18)#define IIC_HS_HCNT (I2C_BASE_MMAP+0x1C)#define IIC_HS_LCNT (I2C_BASE_MMAP+0x20)#define IIC_INTR_MASK (I2C_BASE_MMAP+0x30) /*interrupt mask reg*/#define IIC_INTR_STAT (I2C_BASE_MMAP+0x2C) /*interrupt status reg*/#define IIC_ENABLE (I2C_BASE_MMAP+0x6C) /*IP enable*/#define IIC_DATA_CMD (I2C_BASE_MMAP+0x10) /*IIC TX FIFO*/#define IIC_TXFIFO_FLAG (I2C_BASE_MMAP+0x74) /*indicate TXFIFO level*/#define IIC_RXFIFO_FLAG (I2C_BASE_MMAP+0x78) /*indicate RXFIFO level*/#define IIC_STATUS (I2C_BASE_MMAP+0x70) /*IP status flag reg*/#define IIC_RAW_INTSTATUS (I2C_BASE_MMAP+0x34)/*clear write interrupt reg */#define IIC_CLR_INTR (I2C_BASE_MMAP+0x40) /*clear combined and individual interrupt*/#define IIC_CLR_TX_ABRT (I2C_BASE_MMAP+0x54) /*clear RT abrt interrupt reg*/#define IIC_CLR_STOPDET (I2C_BASE_MMAP+0x60) /*clear stop_det interrupt reg*/#define IIC_CLR_TX_OVER (I2C_BASE_MMAP+0x4C) /*clear tx fifo over interrupt reg*/#define IIC_CLR_RX_ABRT (I2C_BASE_MMAP+0x80) /*clear RX abrt interrupt reg*/#define TIMECOUNT 0x10000#define CONTROL_VALUE 0x0023#ifdef OS_LINUX#define I2C_RD_REG 0x23#define I2C_SET_REG 0x24#define IIC_DEV "/dev/misc/i2c"int i2c_fd=-1;#endif/*! \brief Sends a character over I2C * * \param c Character to send * */static HI_RET i2cSendByte(IN UINT8 u8Value){ UINT16 usData = 0x00FF; UINT16 status; UINT32 i = 0; usData = u8Value & usData; /*set write CMD*/ IIC_REG_READ(IIC_TXFIFO_FLAG, status); /*check TX fifo status*/ while(status >= 8) /*TX FIFO full and wait for a while*/ { taskDelay(10); if(++i>TIMECOUNT) { return HI_ERROR; } IIC_REG_READ(IIC_TXFIFO_FLAG, status); } IIC_REG_WRITE(IIC_DATA_CMD,usData); /*write one byte to TX fifo*/ return HI_OK; }/*! \brief Receives a character over I2C * * \return Character received * */static UINT8 i2cReceiveByte(void){ UINT8 ucValue; UINT16 status; UINT32 i = 0; IIC_REG_WRITE(IIC_DATA_CMD,0x0100); /*read Rx FIFO*/ IIC_REG_READ(IIC_RXFIFO_FLAG, status); while(status == 0) /*RX FIFO is empty and wait for a while*/ { taskDelay(10); if(++i>TIMECOUNT) { return HI_ERROR; } IIC_REG_READ(IIC_RXFIFO_FLAG, status); } IIC_REG_READ(IIC_DATA_CMD,ucValue); return(ucValue);}HI_RET i2cCheckSendResult(void){ UINT16 status; UINT32 i = 0; IIC_REG_READ(IIC_TXFIFO_FLAG, status); while(status != 0) /*TX FIFO is not empty and wait for a while*/ { taskDelay(10); if(++i>TIMECOUNT) { return HI_ERROR; } IIC_REG_READ(IIC_TXFIFO_FLAG, status); } return HI_OK;}static void i2cSetAddress(IN UINT8 u8address){ IIC_REG_WRITE(IIC_ENABLE, 0); IIC_REG_WRITE(IIC_TAR, u8address>>1); IIC_REG_WRITE(IIC_ENABLE, 1);}/*! \brief Reads data from a client on the I2C bus * * \param client Device to read data from * \param address Address of data within device * * \return data received * */UINT8 I2C_Read(IN struct i2c_client *pstClient, IN UINT8 u8Address){ return I2C_SerialRead((UINT8)(pstClient->addr), (UINT8)u8Address );}/*for digital camera iic , added by wangaijun*/UINT8 SccbSerialRead(IN UINT8 u8DevAddress, IN UINT8 u8Address){ int rxdata = 0; return rxdata;}/*! \brief Writes data to a client on the I2C bus * * \param client Device to write data from * \param address Address of data within device * \param data Data to write to device * */HI_RET I2C_Write(IN struct i2c_client *client, IN UINT8 u8Address, IN UINT8 u8Data){ return I2C_SerialWrite(client->addr, u8Address, u8Data);}UINT8 I2C_SerialRead(IN UINT8 u8DevAddress, IN UINT8 u8Address){#ifndef OS_LINUX int rxdata; i2cSetAddress((unsigned char)(u8DevAddress)); i2cSendByte(u8Address); rxdata = i2cReceiveByte(); return rxdata;#else int rxdata=0; unsigned long val; val=0; val=(u8DevAddress<<8)|u8Address; if(i2c_fd>0){ rxdata=ioctl(i2c_fd,I2C_RD_REG,&val); if(rxdata<0) return HI_ERROR; rxdata=(val>>16)&0xff; } return rxdata;#endif}/*! \brief Writes data to a device on the I2C bus * * \param client Device to write data from * \param address Address of data within device * \param data Data to write to device * */HI_RET I2C_SerialWrite(IN int devAddress, IN int address, IN int data){#ifndef OS_LINUX HI_RET ret; i2cSetAddress((unsigned char)(devAddress)); i2cSendByte(address); i2cSendByte(data); ret = i2cCheckSendResult(); return ret;#else HI_RET ret; unsigned long val; val=0; val=((devAddress&0xff)<<8)|(address&0xff); val=val|((data&0xff)<<16); if(i2c_fd>0){ ret=ioctl(i2c_fd,I2C_SET_REG,&val); if(ret<0) return HI_ERROR; else return HI_OK; } else ret=HI_ERROR; return ret;#endif}/*! \brief Initializes I2C interface * */static int i2cInitialized = 0;void I2C_Init(void){ UINT32 cnt, hcnt, lcnt;#ifdef OS_LINUX i2c_fd=-1;#endif if(i2cInitialized == 0) {#ifdef OS_LINUX i2c_fd=open(IIC_DEV, O_NONBLOCK, O_RDWR); if(i2c_fd<0) { printf("open i2c device error\n"); return ; }#endif I2C_BASE_MMAP = (unsigned int)memmap(I2C_BASE, I2C_SIZE); if(I2C_BASE == 0) { printx(("IIC failed! \n")); return ; } IIC_REG_WRITE(IIC_ENABLE, 0); /* standard speed. */ //cnt = I2C_CLK/I2C_RATE; cnt = (27*1000000*4)/I2C_RATE; hcnt = (cnt/9)*4; lcnt = (cnt/9)*5; IIC_REG_WRITE(IIC_CON, CONTROL_VALUE); IIC_REG_WRITE(IIC_HCNT, hcnt); IIC_REG_WRITE(IIC_LCNT, lcnt); IIC_REG_WRITE(IIC_INTR_MASK, 0x0000); i2cInitialized = 1; return; } else { printx(("I2c has been initialized.\n")); return; }}/* end of file hi_i2c.c */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -