📄 2402read-write.c
字号:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/arch/irqs.h>
#include <linux/delay.h>
#define DEV_NAME "/dev/i2c"
#define DEVICE "IIC DRV"
#define DATA_LEN 256
int major = 221;
int minor = 0;
typedef unsigned int U32;
typedef unsigned char U8;
#define CLK_BASE (0x4C000000)
#define IIC_BASE (0x54000000)
#define GPIO_BASE (0x56000000)
#define CLK_CON ( CLK_BASE + 0xC )
#define IIC_GPECON ( GPIO_BASE + 0x40 )
#define IIC_GPEUP ( GPIO_BASE + 0x48 )
#define IIC_CON ( IIC_BASE + 0x0 )
#define IIC_STAT ( IIC_BASE + 0x4 )
#define IIC_ADDR ( IIC_BASE + 0x8 )
#define IIC_DS ( IIC_BASE + 0xC )
unsigned int *R_GPECON, *R_GPEUP, *R_IICCON, *R_IICSTAT, *R_IICADD, *R_IICDS, *R_CLKCON;
enum {WRDATA=1, POLLACK, RDDATA, SETRDADDR};
#define IIC_INTPEND 0x10
#define IICBUFSIZE 0x20
int IIC_open(struct inode *, struct file *);
int IIC_release(struct inode *, struct file *);
ssize_t IIC_read(struct file *file, char* buf, size_t count, loff_t *f_pos);
ssize_t IIC_write(struct file *file, char* buf, size_t count, loff_t *f_pos);
void IicPoll(void);
void Run_IicPoll(void);
#define DELAYTIME 1000
#define IICPOLL_TIMEOUT (15625*10)
#define Delay(x) udelay(x)
ulong get_timer(ulong base);
char iic_data;
static U8 _iicData[IICBUFSIZE];
static volatile int _iicDataCount;
static volatile int _iicStatus;
static volatile int _iicMode;
static int _iicPt;
unsigned int uiOldGPECON;
unsigned int uiOldGPEUP;
//**************[ iic_wr ]*****************************************
void iic_wr(U32 slvAddr,U32 addr,U8 data)
{
//2402 byte Write mode
unsigned int tmp=0;
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicData[1] = data;
_iicDataCount = 2;
//while (rIICSTAT & 0x20);
//rIICDS = slvAddr; //0xa0
iowrite8( slvAddr, R_IICDS );
//Master Tx mode, Start(Write), IIC-bus data output enable
//Bus arbitration sucessful, Address as slave status flag Cleared,
//Address zero status flag cleared, Last received bit is 0
//rIICSTAT = 0xf0;
iowrite8(0xf0, R_IICSTAT);
//rIICCON = 0xaf;
//Clearing the pending bit isn't needed because the pending bit has been cleared.
//timeout = get_timer(0);
while(_iicDataCount!=-1)
{
Run_IicPoll();
// if (get_timer(0)-timeout > IICPOLL_TIMEOUT) break;
}
_iicMode = POLLACK;
while(1)
{
//rIICDS = slvAddr;
iowrite8( slvAddr, R_IICDS);
_iicStatus = 0x100; //To check if _iicStatus is changed
//rIICSTAT = 0xf0; //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
iowrite8( 0xf0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
while(_iicStatus==0x100)
{
Run_IicPoll();
}
if(!(_iicStatus & 0x1))
{
break; //When ACK is received
}
}
//rIICSTAT = 0xd0; //Master Tx condition, Stop(Write), Output Enable
iowrite8( 0xd0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
tmp = ioread32( R_IICCON );
//printk("tmp=R_IICCON : %X \n", tmp);
Delay(DELAYTIME); //Wait until stop condtion is in effect.
//Write is completed.
}
//**************[ _Wr2410Iic_E2PROM ]*****************************************
void iic_wr_page(U32 slvAddr,U32 addr,U8 *buffer,U32 length)
{
//2402 Page Write mode
int i = 0;
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
for(i = 1; i < 1 + length; i++)
{
_iicData[i] = buffer[i-1];
}
_iicDataCount = length+1;
iowrite8( 0xaf, R_IICCON );
iowrite8( 0x10, R_IICADD);
iowrite8( 0x10, R_IICSTAT );
//while (rIICSTAT & 0x20);
//rIICDS = slvAddr; //0xa0
iowrite8( slvAddr, R_IICDS );
//Master Tx mode, Start(Write), IIC-bus data output enable
//Bus arbitration sucessful, Address as slave status flag Cleared,
//Address zero status flag cleared, Last received bit is 0
//rIICSTAT = 0xf0;
iowrite8(0xf0, R_IICSTAT);
//rIICCON = 0xaf;
//Clearing the pending bit isn't needed because the pending bit has been cleared.
//timeout = get_timer(0);
while(_iicDataCount!=-1)
{
Run_IicPoll();
// if (get_timer(0)-timeout > IICPOLL_TIMEOUT) break;
}
_iicMode = POLLACK;
while(1)
{
//rIICDS = slvAddr;
iowrite8( slvAddr, R_IICDS);
_iicStatus = 0x100; //To check if _iicStatus is changed
//rIICSTAT = 0xf0; //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
iowrite8( 0xf0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
while(_iicStatus==0x100)
{
Run_IicPoll();
}
if(!(_iicStatus & 0x1))
{
break; //When ACK is received
}
}
//rIICSTAT = 0xd0; //Master Tx condition, Stop(Write), Output Enable
iowrite8( 0xd0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
Delay(DELAYTIME); //Wait until stop condtion is in effect.
//Write is completed.
}
//************************[ iic_rd ]********************************
void iic_rd(U32 slvAddr,U32 addr,U8 *data)
{
//2402 byte read mode
_iicMode = SETRDADDR;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicDataCount = 1;
//while (rIICSTAT & 0x20);
//rIICDS = slvAddr;
iowrite8( slvAddr, R_IICDS );
//rIICSTAT = 0xf0; //MasTx,Start
iowrite8(0xf0,R_IICSTAT);
//rIICCON = 0xaf;
//Clearing the pending bit isn't needed because the pending bit has been cleared.
//timeout = get_timer(0);
while(_iicDataCount!=-1) {
Run_IicPoll();
//if (get_timer(0)-timeout > IICPOLL_TIMEOUT) break;
}
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = 1;
//rIICDS = slvAddr;
iowrite8( slvAddr, R_IICDS );
//rIICSTAT = 0xb0; //Master Rx,Start
iowrite8( 0xb0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
//timeout = get_timer(0);
while(_iicDataCount!=-1) {
Run_IicPoll();
//if (get_timer(0)-timeout > IICPOLL_TIMEOUT) break;
}
*data = _iicData[1];
//rIICSTAT = 0xd0; //Master Tx condition, Stop(Write), Output Enable
iowrite8( 0xd0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
Delay(DELAYTIME);
}
//************************[ _Rd2410Iic ]********************************
void iic_rd_page(U32 slvAddr,U32 addr,U8 *buffer,U32 length)
{
//2402 Random read && Sequential read
int i = 0;
_iicMode = SETRDADDR;
_iicPt = 0;
_iicData[0] = (U8)addr ;
_iicDataCount = 1;
iowrite8( 0xaf, R_IICCON );
iowrite8( 0x10, R_IICADD);
iowrite8( 0x10, R_IICSTAT );
iowrite8( slvAddr, R_IICDS );
iowrite8(0xf0,R_IICSTAT); //MasTx,Start
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1)
Run_IicPoll();
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = length;
iowrite8( slvAddr, R_IICDS );
iowrite8( 0xb0, R_IICSTAT); //Master Rx,Start
iowrite8( 0xaf, R_IICCON); //Resumes IIC operation.
while(_iicDataCount!=-1)
Run_IicPoll();
printk("In the Read Function\n");
for(i = 0; i<length;i++)
{
buffer[i] = _iicData[i+1];
// printk("The read num %d is %x\n",i,_iicData[i+2]);
}
//rIICSTAT = 0xd0; //Master Tx condition, Stop(Write), Output Enable
iowrite8( 0xd0, R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8( 0xaf, R_IICCON);
Delay(DELAYTIME);
}
//**********************[ Run_IicPoll ]*********************************
void Run_IicPoll(void)
{
//printk("first ioread8(R_IICCON)=%x\n",ioread8(R_IICCON));
if(ioread8(R_IICCON)& 0x10)
{
//Tx/Rx Interrupt Enable
//udelay(100);
//printk("secont ioread8(R_IICCON)=%x\n",ioread8(R_IICCON));
IicPoll();
}
}
//**********************[IicPoll ]**************************************
void IicPoll(void)
{
U32 iicSt,i;
//iicSt = rIICSTAT;
iicSt = ioread8(R_IICSTAT);
//printk(KERN_ERR"iicSt=%x\n",iicSt);
if(iicSt & 0x8){} //When bus arbitration is failed.
if(iicSt & 0x4){} //When a slave address is matched with IICADD
if(iicSt & 0x2){} //When a slave address is 0000000b
if(iicSt & 0x1){} //When ACK isn't received
_iicStatus = iicSt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -