文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>IIC驱动

IIC驱动

时间:2006-07-30  来源:luanjian

IIC驱动

       我使用的开发板,处理器芯片44B0与EEPROM(24C08)通过iic总线连接,因此验证IIC驱动,就是通过写入C08一个数据然后再从中读出的方法。我使用中断的方法来实现IIC数据的传输,查询的方法其实与中断差不多,应该更简单一些。

下面是我的驱动程序

#include <linux/fs.h>

#include <linux/iobuf.h>

#include <linux/major.h>

//#include <linux/capability.h>

#include <linux/smp_lock.h>

#include <asm/uaccess.h>

#include <asm/hardware.h>

#include <asm/arch/s3c44b0x.h>

#include <linux/types.h>

#include <asm/io.h>

//#include <linux/vmalloc.h>

#include <linux/module.h>

#include <linux/init.h>

 

 

#include <linux/poll.h>

#include <asm/irq.h>

#include <asm/arch/irq.h>

#include <asm/arch/irqs.h>

 

#define IIC_MAJOR 254

#define NAME  "eeprom"

 

#define pdataf *(volatile unsigned char *)S3C44B0X_PDATAF

#define pconf *(volatile unsigned char *)S3C44B0X_PCONF

#define pupf *(volatile unsigned char *)S3C44B0X_PUPF

 

#define i2ccon  *(volatile unsigned char *)S3C44B0X_IICCON

#define i2cstat  *(volatile unsigned char *)S3C44B0X_IICSTAT

#define i2caddr  *(volatile unsigned char *)S3C44B0X_IICADD

#define i2cds *(volatile unsigned char *)S3C44B0X_IICDS

 

static DECLARE_WAIT_QUEUE_HEAD(wait);

 

#include <asm/hardware.h>

#include <asm/io.h>

 

 

//void s3c44b0x_mask_irq(unsigned int irq);

//void s3c44b0x_clear_pb(unsigned int irq);

 

void  s3c44b0x_mask_irq(unsigned int irq)

{

        outl( inl(S3C44B0X_INTMSK) | ( 1 << irq ), S3C44B0X_INTMSK);

}

void  s3c44b0x_clear_pb(unsigned int irq)

{

        outl( (1 << irq), S3C44B0X_I_ISPC);

}

 

//extern void s3c44b0x_mask_irq(unsigned int irq);

//extern void s3c44b0x_unmask_irq(unsigned int irq);

//extern void s3c44b0x_clear_pb(unsigned int irq);

//extern void s3c44b0x_mask_ack_irq(unsigned int irq);

 

static ssize_t i2cread (struct file *filp,char  *buf,size_t count,loff_t *offp);

static ssize_t i2cwrite(struct file *filp,const char  *buf,size_t count,loff_t *offp);

static int i2crelease(struct inode *inode,struct file *filp);

static int i2copen(struct inode *inode,struct file *filp);

 

static char condition = 0;

 

static struct file_operations iic_fops = {

       open:i2copen,

       read:i2cread,

       write:i2cwrite,

       release:i2crelease,

};

//byte write

static ssize_t i2cwrite(struct file *filp,const char  *buf,size_t count,loff_t *offp)

{

/****************** transmit the slave address **********************/

       condition = 0;

        i2cds   = 0xa0;

        i2cstat = 0xf0; //MasTx,start,En Tx/Rx,

        wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

//     interruptible_sleep_on(&wait);

       condition = 0;

/***************** transmit the address of where to write ************/

 

        i2cds   = buf[0];  //the write address

        i2ccon  = 0xe2; //resume iic operation

     wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

       condition = 0;

/***************** write the data ************************************/

 

       i2cds       = buf[1];

        i2ccon  = 0xe2; //resume iic operation

        wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

       condition = 0;

/***************** stop trans ***************************************/

 

        i2cstat = 0xd0; //MasTx,stop,En Tx/Rx,

        i2ccon  = 0xe2; //resume iic operation

       udelay(1000);

        return (2);

 

}

 

//this is a random read (24c08)

static ssize_t i2cread (struct file *filp,char  *buf,size_t count,loff_t *offp)

{

/****************** transmit the slave address **********************/

       condition = 0;

       i2cds       = 0xa0;

       i2cstat = 0xf0; //MasTx,start,En Tx/Rx,

       wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

       condition = 0;

/***************** transmit the address of where to read ************/

 

       i2cds       = 0x74;   //the read address

       i2ccon  = 0xe2; //resume iic operation

       wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

       condition = 0;

       buf[0] = i2cds;

/***************** read the data ************************************/

      

       i2cds   = 0xa1; //read address

       i2cstat = 0xb0; //MasRx,start,En Tx/Rx,

       i2ccon  = 0xe2; //resume iic operation

       wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

       condition = 0;

       i2ccon  = (0xe2 & (~0x80));

       wait_event_interruptible(wait, (condition != 0)); //wait the trans complete

       condition = 0;

       buf[1]  = i2cds;

       printk("<1>the read  data  = %x  |  %x\n",buf[0],buf[1]);

 

/***************** stop trans ***************************************/

 

       i2cstat = 0x90; //MasRx,stop,En Tx/Rx,

       i2ccon  = 0xe2; //resume iic operation

       udelay(1000);

       return (2);

}

 

void iic_irq(int irq, void *dev_id, struct pt_regs *regs)

{

       if(i2cstat & 0x04)

              printk("slave address received\n");

       printk("iicaddress = %x \n",i2caddr);

       condition = 1;

       printk("interrupt\n");

       wake_up_interruptible( &wait );

       s3c44b0x_clear_pb( S3C44B0X_INTERRUPT_IIC );

}

 

static int i2copen(struct inode *inode,struct file *filp)

{

       int ret;

       unsigned long flag;

       ret = request_irq(S3C44B0X_INTERRUPT_IIC,iic_irq,SA_INTERRUPT,"iic",NULL);

       if(ret < 0)

       {

              printk("iic interrupt request failed!\n");

              free_irq(S3C44B0X_INTERRUPT_IIC,NULL);

              return ret;

       }

 

       local_irq_save(flag);

       pconf &= 0xfff0;  //config the io

        pconf |= 0x000a;  //iicsda iicsdl

        pupf  &= 0xfc;

 

       i2caddr = 0x10;

       i2ccon = 0xe2; //ack, enable interrupt,Fiiclk=Fmclk/512=117k,

       i2cstat = 0x10; //en rx/tx

//     i2caddr = 0xa0;

 

       local_irq_restore(flag);

 

       MOD_INC_USE_COUNT;

       return ret;

}

 

static int i2crelease(struct inode *inode,struct file *filp)

{

       MOD_DEC_USE_COUNT;

       s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_IIC);

       free_irq(S3C44B0X_INTERRUPT_IIC,NULL);

       return 0;

}

 

 

static int __init i2c_init(void)

{

       int ret;

       ret = register_chrdev(IIC_MAJOR,NAME,&iic_fops);

       if(ret < 0)

       {

              printk("<1>eeprom device register failed");

              return ret;

       }

       return 0;

}

 

static void  __exit i2c_exit(void)

{

       int ret;

       ret = unregister_chrdev(IIC_MAJOR,NAME);

       if (ret < 0)

       {

              printk("<1>eeprom device unregister failed");

              return;

       }

       printk("iic device uninstalled!\n");

}

 

module_init(i2c_init);

module_exit(i2c_exit);

现在这个驱动实现了uclinux下的读写功能,但是其中还有一点还没弄明白。为什么这个iicaddr寄存器写入0xa0后,状态标志寄存器的地址匹配标志位不致“1”,如果哪位看客有高见,谢谢你的指点。

相关阅读 更多 +
排行榜 更多 +
儿童涂色填色涂涂乐

儿童涂色填色涂涂乐

休闲益智 下载
子弹落下来安卓版

子弹落下来安卓版

飞行射击 下载
恐怖追逐盖瑞模组

恐怖追逐盖瑞模组

飞行射击 下载