将一个组中的数据写入到AT24C02中,然后再读出来!
以下为DOME程序!
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define DEV_NAME "/dev/2402_RW"
int main()
{ int fd,ret,i;
int wr_data[5]={0x00,0x10,0x30,0x70,0xf0};
int ra_data[5];
fd=open(DEV_NAME,O_RDWR);
if (fd<0)
{ printf ("the derive is opened fail !!\n");
return fd;
}
else
{ printf ("the derive is opened success !!\n");
write(fd,wr_data,sizeof(wr_data));
for(i=0;i<5;i++)
{ printf ("write-----data=%x\n",wr_data[i]);
}
sleep(2);
read(fd,ra_data,20);
for (i=0;i<5;i++)
{ printf ("read------data=%x\n",ra_data[i]);
}
}
ret=close(fd);
printf ("the ret=%d\n",ret);
}
以下为驱动源码!
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm-generic/errno-base.h>
#include <asm/arch-s3c2410/regs-gpio.h>
#include <asm/arch-s3c2410/regs-iic.h>
#include <asm/arch-s3c2410/irqs.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#define DEV_ID 107
#define DEV_NAME "2402_RW"
#define IICCON 0x54000000
#define IICSTAT 0x54000004
#define IICDS 0x5400000c
#define IICADD 0x54000008
#define IICLC 0x54000010
#define CLKCON 0x4c00000c
static void *S3C2402_IICSTAT;
static void *S3C2402_IICCON;
static void *S3C2402_IICDS;
static void *S3C2402_IICADD;
static void *S3C2402_IICLC;
static void *S3C2440_CLKCON;
static int wr_data[5];
static int ra_data[5];
static int ack=0;
void delay(int t)
{ int i;
for(;t>0;t--)
{ for(i=0;i<20000;i++);
}
}
static int open_2402(struct inode * inode, struct file * file)
{ int cmmd;
writel(0xc0000,S3C2410_GPEUP);
s3c2410_gpio_cfgpin(S3C2410_GPE14,S3C2410_GPE14_IICSCL);
s3c2410_gpio_cfgpin(S3C2410_GPE15,S3C2410_GPE15_IICSDA);
S3C2402_IICCON=ioremap(IICCON,0x00000004);
S3C2402_IICSTAT=ioremap(IICSTAT,0x00000004);
S3C2402_IICDS=ioremap(IICDS,0x00000004);
S3C2402_IICADD=ioremap(IICADD,0x00000004);
S3C2402_IICLC=ioremap(IICLC,0X00000004);
S3C2440_CLKCON=ioremap(CLKCON,0x00000004);
writel(0xf3eb70,S3C2440_CLKCON);
cmmd=((S3C2410_IICCON_ACKEN)|(S3C2410_IICCON_TXDIV_16)|(S3C2410_IICCON_IRQEN)|(0x0f));
writel(cmmd,S3C2402_IICCON);
writel(0x10,S3C2402_IICADD);
writel(0x10,S3C2402_IICSTAT);
writel((S3C2410_IICLC_FILTER_ON|S3C2410_IICLC_SDA_DELAY5),S3C2402_IICLC);
return 0;
}
static int write_2402(struct file * file, const char __user * userbuf,size_t count, loff_t * off)
{ int i;
ack=0;
if(copy_from_user(wr_data,userbuf,count)!=0)
{ printk("write is error!!\n");
return EFAULT;
}
writel(0xa0,S3C2402_IICDS);
writel(0xf0,S3C2402_IICSTAT);
udelay(100);
while(ack==0);
ack=0;
writel(0x00,S3C2402_IICDS);
writel(0xaf,S3C2402_IICCON);
udelay(100);
while(ack==0);
ack=0;
for(i=0;i<5;i++)
{
writel(wr_data[i],S3C2402_IICDS);
printk("wr_data=%x\n",wr_data[i]);
writel((readl(S3C2410_GPFDAT)|wr_data[i]),S3C2410_GPFDAT);
writel(0xaf,S3C2402_IICCON);
udelay(100);
while(ack==0);
printk("ack=%x\n",ack);
ack=0;
}
writel(0xd0,S3C2402_IICSTAT);
writel(0xaf,S3C2402_IICCON);
udelay(100);
return count;
}
static int read_2402 (struct file * file, char __user * userbuf, size_t count, loff_t * off)
{ int i,a;
ack=0;
writel(0xa0,S3C2402_IICDS);
writel(0xf0,S3C2402_IICSTAT);
udelay(100);
while(ack==0);
ack=0;
writel(0x00,S3C2402_IICDS);
writel(0xaf,S3C2402_IICCON);
udelay(100);
while(ack==0);
ack=0;
writel(0xa1,S3C2402_IICDS);
writel(0xb0,S3C2402_IICSTAT);
writel(0xaf,S3C2402_IICCON);
udelay(100);
a=readl(S3C2402_IICDS);
printk("a=%x\n",a);
for (i=0;i<5;i++)
{ while(ack==0);
printk("ack=%x\n",ack);
ack=0;
writel(0xaf,S3C2402_IICCON);
udelay(100);
ra_data[i]=readl(S3C2402_IICDS);
writel((readl(S3C2410_GPFDAT)|ra_data[i]),S3C2410_GPFDAT);
printk("ra_data=%x\n",ra_data[i]);
}
writel(0x90,S3C2402_IICSTAT);
writel(0xaf,S3C2402_IICCON);
udelay(100);
if(copy_to_user(userbuf,ra_data,count)!=0)
{ printk("read is error!!\n");
return EFAULT;
}
return count;
}
static irqreturn_t iic_interrupt(int irq,void *dev_id,struct pt_regs *regs)
{
ack=1;
return IRQ_HANDLED;
}
static struct file_operations test_2402 ={
.open = open_2402,
.write = write_2402,
.read = read_2402,
};
static int __init init_2402(void)
{ int result,ret;
result=register_chrdev(DEV_ID,DEV_NAME,&test_2402);
if (result<0)
{ printk ("the derive register is fail!!!\n");
return ENODEV;
}
else
{ printk ("the derive register is succss!!!\n");
ret=request_irq(IRQ_IIC,&iic_interrupt,SA_INTERRUPT,DEV_NAME,&iic_interrupt);
if(ret<0)
{ printk("the iic_interrupt is requestted fail\n");
return ENODEV;
}
else
{ printk("the iic_interrupt is requestted sccuss!!\n");
devfs_mk_cdev(MKDEV(DEV_ID,0),S_IFCHR | S_IRUSR | S_IWUSR,"2402_RW");
return ret;
}
return result;
}
}
static void __exit exit_2402(void)
{ unregister_chrdev(DEV_ID,DEV_NAME);
disable_irq(IRQ_IIC);
free_irq(IRQ_IIC,&iic_interrupt);
devfs_remove(DEV_NAME);
printk ("the derive is unregister\n");
}
module_init(init_2402);
module_exit(exit_2402);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("KANG");
MODULE_DESCRIPTION("2402_READ_WRITE");