免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 884 | 回复: 0
打印 上一主题 下一主题

44b0的IIC---AT24C04的uclinux驱动(原创) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-03 09:56 |只看该作者 |倒序浏览
看了很多书上写的44b0的IIC的驱动都是很难理解的那种,都是照抄三星的程序的,于是就自己改写了IIC的驱动,我认为这样有助于理解执行的过程,很简单易懂.
/*
*iic.c:
* read and write only one byte for AT24C04
*/
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude "IIC.h"
void vdelay(unsigned short i);
static DECLARE_WAIT_QUEUE_HEAD(wait);
unsigned char WrData= 0 ;
unsigned char RecvData[2] = {0,0};
volatile static unsigned char ack_tag;
volatile static unsigned int addr;
static int IIC_read(struct file *filp,char *buf,size_t count,loff_t *f_pos) //count读取的数量;
{
   
    //printk("read addr %d \n",addr);
/****************** 读** 写入设备地址 **********************/
       ack_tag = 0;
       CSR_WRITE(rIICDS,0xa0);   //设备地址
       CSR_WRITE(rIICSTAT,0xf0); //MasTx,start,En Tx/Rx,
       wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
       ack_tag = 0;
/***************** 读**写入读取的低地址 ************/
       CSR_WRITE(rIICDS,(char)addr);   //the read address
       CSR_WRITE(rIICCON,0xaf); //resume iic operation
       wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
       ack_tag = 0;
/****************** 读**再次写入设备地址 **********************/
       CSR_WRITE(rIICDS,0xa0);   //设备地址
       CSR_WRITE(rIICSTAT,0xb0); //MasRx,start,En Tx/Rx,
       CSR_WRITE(rIICCON,0xaf); //resume iic operation
       wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
       ack_tag = 0;
/***************** read the data ************************************/
       RecvData[1]=CSR_READ(rIICDS);   //这次读到的没有用
       CSR_WRITE(rIICCON,0x2f);    //只读一位
       wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
       ack_tag = 0;
       RecvData[0]=CSR_READ(rIICDS);  
       printk("read data %d \n",RecvData[0]);     
/***************** stop trans ***************************************/
       CSR_WRITE(rIICSTAT,0x90); //MasRx,stop,En Tx/Rx,
       CSR_WRITE(rIICCON,0xaf); //resume iic operation  
       vdelay(100);
                     
       copy_to_user(buf, &RecvData, sizeof(char));
    return (1);
}
static int IIC_write(struct file *filp,char *buf,size_t count,loff_t *f_pos)
{
//unsigned int i;
if(copy_from_user(&WrData, buf, sizeof(char)))
{
  printk("error writing, copy_from_user\n");  
  return -EFAULT;
}  
printk("write address %d \n",addr);
printk("write data %d \n",WrData);
/****************** 写** 写入设备地址 **********************/
     ack_tag = 0;
     CSR_WRITE(rIICDS,0xa0);
     CSR_WRITE(rIICSTAT,0xf0); //MasTx,start,En Tx/Rx,
     wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
     ack_tag = 0;
/***************** 写** 写入存储器的内部地址低位 ************/
     CSR_WRITE(rIICDS,(char)addr);  //the write high address
     CSR_WRITE(rIICCON,0xaf); //resume iic operation
     wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
     ack_tag = 0;
/***************** write the data ************************************/
     CSR_WRITE(rIICDS,WrData);  //the write high address
     CSR_WRITE(rIICCON,0xaf); //resume iic operation
     wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete
     ack_tag = 0;
/***************** stop trans ***************************************/
     CSR_WRITE(rIICSTAT,0xd0); //MasTx,stop,En Tx/Rx,
     CSR_WRITE(rIICCON,0xaf); //resume iic operation
     vdelay(100);
     return (1);
}
static int IIC_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
addr = arg;     
return 1;
}
static int IIC_open(struct inode *inode,struct file *filp)
{
MOD_INC_USE_COUNT;
printk("someone open iic!\n");
return 0;
}
static int IIC_release(struct inode *inode,struct file *filp)
{
MOD_DEC_USE_COUNT;
printk("someone close iic\n");
return 0;
}
static int IIC_select(struct file *file,struct poll_table_struct *wait)
{
return 0;
}
void IIC_handle(int irq,void *dev_id,struct pt_regs *regs)
{
  //char rec;
  //rec = CSR_READ(rIICDS);
  //printk(" \n %d \ n",rec);
  CSR_WRITE(rI_ISPC,(CSR_READ(rI_ISPC)|BIT_IIC));  // Clear IIC  Pending Bit
  ack_tag = 1;
  wake_up_interruptible(&wait);
}

void IIC_init(void)
{
int ret;
CSR_WRITE(rPCONF,((CSR_READ(rPCONF)&0xfffffff0)|0xa)); //PF0:IICSCL,PF1:IICSDA
CSR_WRITE(rPUPF,(CSR_READ(rPUPF)|0x3));//禁止内部上拉
CSR_WRITE(rIICCON,0xaf);//(1=0){
  ret = request_irq(IIC_IRQ,IIC_handle,SA_INTERRUPT,"IICS",NULL);
  if(ret){
    printk("IIC:cant get assigned irq %i\n",IIC_IRQ);
    }
  else{
   printk("IIC:request external interrupt %i\n",IIC_IRQ);
   INT_ENABLE(IIC_IRQ);
   }
  }
}
void vdelay(unsigned short i)
{
ushort cm=0;
while(cm

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/82516/showart_1849544.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP