⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at24c04driver.c

📁 EEPROM AT24C04在uClinux下的简单驱动
💻 C
字号:
#i nclude <asm/hardware.h>
#i nclude <linux/module.h>
#i nclude <linux/fs.h>
#i nclude <linux/types.h>
#i nclude <linux/malloc.h>
#i nclude <asm/uaccess.h>
#i nclude <asm/page.h>
#i nclude <linux/errno.h>
#i nclude <linux/config.h>
#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<<7)|(0<<6)|(1<<5)|(0xf));    //Enable interrupt, IICCLK=MCLK/16, Enable ACK
    //40Mhz/16/(15+1) = 257Khz 
  CSR_WRITE(rIICADD,0x10);   // S3C44B0X slave address
 CSR_WRITE(rIICSTAT,0x10); 
   
 CSR_WRITE(rI_ISPC,(CSR_READ(rI_ISPC)|BIT_IIC));  // Clear EINT's  Pending Bit
  CSR_WRITE(rINTMSK,(CSR_READ(rINTMSK)&(~BIT_IIC)));  // Enable interrupt

 ret = register_chrdev(IIC_MAJOR,"iic",&IIC_fops);
 if(ret<0) {
   printk("fail to register\n");
   }
 CLEAR_PEND_INT(IIC_IRQ);
 
 if(IIC_IRQ >=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<i)
 {
  cm++;
 }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -