I2C铁电存储器驱动程序,测试程序出问题

发布于 2022-10-15 06:34:03 字数 25818 浏览 23 评论 0

这是一个I2C铁电存储器驱动程序,驱动已经编译、并加载到arm开发板s3c2440上,
测试程序运行结果不成功,这是怎么回事,是测试程序错了吗,如果要调试驱动程序的话如何调试呢?
请各位帮帮忙啦


FM24CL16驱动程序:





#include <asm/io.h>
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include "hardware.h"
#include <linux/gpio.h>
#include <mach/regs-gpio.h>




#define u32 unsigned int
#define u16 unsigned short
#define s32 int
#define s16 short int
#define u8 unsigned char


/*  I/O PORT */

//#define PCONF        (*(volatile unsigned *)0x56000040)
//#define PDATF        (*(volatile unsigned *)0x56000044)
//#define PUPF        (*(volatile unsigned *)0x5600004



/*
#define IICCON        (*(volatile unsigned *)0x54000000)
#define IICSTAT        (*(volatile unsigned *)0x54000004)
#define IICADD        (*(volatile unsigned *)0x5400000
#define IICDS        (*(volatile unsigned *)0x5400000c)
*/






#define   iiccon  0x54000000
#define   iicstat 0x54000004
#define   iicds 0x5400000c
#define   iicadd 0x54000008
#define   iicl  0x54000010
#define   clkcon 0x4c00000c
static void *IICSTAT;
static void *IICCON;
static void *IICDS;
static void *IICADD;
static void *IICLC;












#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_iic_dir, devfs_iicraw;
#endif

#define SKQ_IIC_MODULE_NAME        "IICBUS"
/*60--63,120--127,240--254*/
#define IICBUS_MAJOR        240
#define IICBUSRAW_MINOR 1

#define IICBUS_INT IRQ_IIC


static char *IICBUD_id = "SKQ IICBUS driver v1.0 (2005-06-02)<psc@hualiangtech.com>";

/* debug macros */
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK( x... )            printk("SKQ IICBUS: "##x)
#else
#define DPRINTK( x... )
#endif


#define WRDATA                (1)
#define POLLACK                (2)
#define RDDATA                (3)
#define SETRDADDR        (4)


#define IICBUFSIZE 2048

char IICBUS_Buf[IICBUFSIZE];

static int opencount=0;
static int tsMajor=0;
static loff_t newpos=0;
int writeFM24CL16(char * buffer, size_t count, int address)
{
unsigned long timeo;
u16 i;
u16 PageAdd;
char slvAddr, tpICON,tempIICSTAT;
IICCON=(1<<7)|(0<<6)|(1<<5)|(0xf);
IICSTAT=0x10;

slvAddr=0xa0;
PageAdd=address;
/*  send the bit of start and address of device and page of address */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char)PageAdd;
slvAddr|=0xa0;
IICDS=slvAddr;  //0xa0      
IICSTAT=0xf0;   //MasTx,Start

timeo = jiffies + (HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;        /* pending */
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;        /* ack */
if((tpICON==0x10)) break; //&&(tempIICSTAT==0x00)
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf; /*clr pending */

IICDS=(char)address;  //0xa0
timeo = jiffies +(HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break;  // &&tempIICSTAT==0x00)
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;

for(i=0;i<count;i++)
{
IICDS=buffer;
timeo=jiffies + (HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)&&(tempIICSTAT==0x00)) break;
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;  /* clr pending */
}
IICSTAT =0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return count;
}


int ReadFM24CL16(char *buffer, size_t count, int address)
{
unsigned long timeo;
u16 i;
u8 slvAddr ,tpICON,tempIICSTAT;
u16 PageAdd;
PageAdd=address;
/* 发送起始位和设备地址和页地址 */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char )PageAdd;
slvAddr|=0xa0;
IICDS=slvAddr;  //0xa0;
IICSTAT=0xf0;   //MasTx,Start
timeo = jiffies +(HZ/100);
while(1){
        tpICON=IICCON;
        tpICON&=0x10;
        // tempIICSTAT=rIICSTAT;
        //tempIICSTAT&=0x01;
        if((tpICON==0x10)) break;  //&&(tempIICSTAT==0x00)
        if(time_after(jiffies,timeo))
        {
                IICSTAT=0x90;
                IICCON=0xaf;
                udelay(200);
                IICCON=0xaf;
                IICSTAT=0x10;
                return -1;
        }
};
IICCON=0xaf;
/* 发送地址低8位 */
IICDS=(char)address;
timeo = jiffies + (HZ/100);
while(1){
        tpICON=IICCON;
        tpICON&=0x10;
        tempIICSTAT=IICSTAT;
        tempIICSTAT&=0x01;
        if((tpICON==0x10)) break;  //&&(tempIICSTAT==0x00)
        if(time_after(jiffies, timeo))
        {
                IICSTAT=0x90;
                IICCON=0xaf;
                udelay(200);
                IICCON=0xaf;
                IICSTAT=0x10;
                return -1;
        }
};
IICCON=0xaf;
//IICSTAT&=0xef;
/* 发送起始位和设备地址和页地址 */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char )PageAdd;
slvAddr|=0xa1;
IICDS=slvAddr;
IICSTAT=0xb0;  //MasRx,Start
timeo = jiffies +(HZ/100);
while(1){
        tpICON=IICCON;
        tpICON&=0x10;
        tempIICSTAT=IICSTAT;
        tempIICSTAT&=0x01;
        if((tpICON==0x10)) break; // &&(tempIICSTAT==0x00)
        if(time_after(jiffies,timeo))
        {
                IICSTAT=0x90;
                IICCON=0xaf;
                udelay(200);
                IICCON=0xaf;
                IICSTAT=0x10;
                return -1;
        }
};
IICCON=0xaf;

for(i=0;i<count;i++)
{
        IICDS=slvAddr;
        //timeo =jiffies +(HZ/100);
        while(1){
                tpICON=IICCON;
                tpICON&=0x10;
                tempIICSTAT=IICSTAT;
                tempIICSTAT&=0x01;
                if((tpICON==0x10)) break ;//(tempIICSTAT==0x00)
                //else
                //        {
                //        if((tpICON==0x10)&&(i==count-1))break;
                //        }
                if(time_after(jiffies, timeo))
                {
                        IICSTAT=0x90;
                        IICCON=0xaf;
                        udelay(200);
                        IICCON=0xaf;
                        IICSTAT=0x10;
                        return -1;
                }
        };
        buffer=IICDS;
        if(i==count-1) IICCON=0x2f;
        else IICCON=0xaf;
}

IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;

return count;
}

loff_t  IICBUS_llseek(struct file *filp, loff_t off,int whence)
{
        switch(whence){
        case 0 :        /* SEEK_SET */
                newpos=off;
                break;
        default:        /* cant,t happen */
                return -EINVAL;
        }
        if(newpos<0) return -EINVAL;
        return newpos;
}

static ssize_t IICBUS_write(struct file *file,const char *buffer,size_t count, loff_t *ppos)
{
        int ret;
        int address=(int)newpos;
        if(count>204 return 0;
        // copy_from_user(&address,ppos, sizeof(loff_t));
        // address=(int)*ppos;
        // printk("IICBUS_write address=%ld\n",address);
        if(address+count>204 return 0;
        copy_from_user(IICBUS_Buf, buffer, address);
        ret=writeFM24CL16(IICBUS_Buf,count,address);
        return ret;
}
static ssize_t IICBUS_read(struct file *filp,char *buffer,size_t count, loff_t *ppos)
{
        int len;
        int address=(int)newpos;
        //int address1;
        if(count>204 return 0;
        //copy_from_user(&address,ppos, sizeof(loff_t));
        //address=(int)*ppos;
        //printk("IICBUS_read address=%d\n",address);
        if(address+count>204 return 0;
        //address1=(int)*ppos;
        //printk("IICBUS_read address1=%ld\n",address);
        //printk("IICBUS_read ppos=%ld\n",ppos);
        len=ReadFM24CL16(IICBUS_Buf,count,address);
        copy_to_user(buffer,IICBUS_Buf,len);
        DPRINTK("read data=%d\n",data);
        return len;
}

static int IICBUS_open(struct inode *inode, struct file *file)
{
        //if(opencount==1)
        //return -EBUSY;
        opencount++;
       try_module_get(THIS_MODULE);        //MOD_INC_USE_COUNT;
        DPRINTK("device open\n";
        return 0;
}

static int IICBUS_release(struct inode *inode, struct file *filp)
{
        opencount--;
        module_put(THIS_MODULE);   //MOD_DEC_USE_COUNT;
        DPRINTK("device release\n";
        return 0;
}
static struct file_operations s3c44b0_iicbus_fops ={
owner:        THIS_MODULE,
llseek:        IICBUS_llseek,
write:        IICBUS_write,
read:        IICBUS_read,
open:        IICBUS_open,
release:        IICBUS_release,
};

static int __init IICBUS_init(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPB(14),S3C2410_GPE14_IICSCL);
s3c2410_gpio_cfgpin(S3C2410_GPB(15),S3C2410_GPE15_IICSDA);

IICCON=ioremap(iiccon,0x00000004);
IICSTAT=ioremap(iicstat,0x00000004);
IICDS=ioremap(iicds,0x00000004);
IICADD=ioremap(iicadd,0x00000004);
IICLC=ioremap(iicl,0X00000004);







        int ret;
        int flags;
        //local_irq_save(flags);
        /* port F */
                /* Bit8                 7         6        5        4        3        2       
                     SPICKL            SPIMISO        SPICS        SPIMOSI        INCARD2        NC        NC */
             //        PCONF |=0x0a;        //PF0:IICSCL,PF1:IICSDA
               //      PUPF |=0x03;        //pull-up disable
                     IICCON=(1<<7)|(0<<6)|(0<<5)|(0xf);
                     //Enable interrupt,IICCLK=MCKL/16,Enable ACK
                     //40Mhz/16/(15+1)=257khz
                     IICADD=0x10;  //s3c44B0X slave address
                     IICSTAT=0x10;
        //             local_irq_restore(flags);
                     opencount=0;
                     ret = register_chrdev(IICBUS_MAJOR, SKQ_IIC_MODULE_NAME,&s3c44b0_iicbus_fops);
                     if (ret<0)
                     {
                     printk( "can't get major number\n";      
                     return -1;
                     }
                     tsMajor=ret;
                     #if 0
                     if(0 !=request_irq(IICBUS_INT,IICBUS_isr,SA_INTERRUPT,IICBUD_id,NULL))
                     {
                                  printk(KERN_WARNING "tce44b0_usb:failed to get IRQ\n";
                                  return 1;
                     }
                     #endif
#ifdef CONFIG_DEVFS_FS
        devfs_iic_dir = devfs_mk_dir(NULL,SKQ_IIC_MODULE_NAME,NULL);
               devfs_iicraw = devfs_register(devfs_iic_dir, "0",DEVFS_FL_DEFAULT,
                                             tsMajor,IICBUSRAW_MINOR,S_IFCHR | S_IRUSR | S_IWUSR,        &s3c44b0_iicbus_fops,NULL);
#endif
            printk(SKQ_IIC_MODULE_NAME " initialized\n";
                  return 0;
}


static void __exit IICBUS_exit(void)
{
        printk("<0>SKQ IIC Exit.\n";
//        free_irq(IICBUS_INT, IICBUD_id);
         unregister_chrdev_region(IICBUS_MAJOR,1);
}

module_init(IICBUS_init);
module_exit(IICBUS_exit);
MODULE_DESCRIPTION("SKQ IIC driver";
MODULE_AUTHOR("pengshicao ";
MODULE_LICENSE("GPL";            
                                    
                                  
                                       
                     

测试程序:
(dev/IICBUS 是一个手动创建的设备文件)


               
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define  DEV_NAME   "/dev/IICBUS"
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);
              }
      sleep(2);
   read(fd,ra_data,20);
  for (i=0;i<5;i++)
    {  printf ("read------data=%x\n",ra_data);
              }
        }
   ret=close(fd);
   printf ("the ret=%d\n",ret);
   }



360安全浏览器截图19792140.jpg (22.2 KB, 下载次数: 7)

下载附件

2011-05-19 14:38 上传

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文