|
下面是我写的一个8255的驱动程序。用的是EP9315。以下是驱动代码:
#ifdef MODULE
#define __NO_VERSION__
#include
#include
#endif
#define __KERNEL__
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define r8255_Con 0x30C00006
#define r8255_A 0x30C00000
#define r8255_B 0x30C00002
#define r8255_C 0x30C00004
volatile unsigned long Con;
volatile unsigned long PortA;
volatile unsigned long PortB;
volatile unsigned long PortC;
static int D8255_write(struct file *filp,char *buf,int len,loff_t *off);
static unsigned int MAJOR_NUM=254;
static struct file_operations D8255_fops=
{
write:(void(*))D8255_write,
};
char Dname[]="8255DRV";
static int __init D8255_init(void)
{
int ret;
ret = register_chrdev(MAJOR_NUM, Dname, &D8255_fops);
if(ret<0)
{
printk("<1> 8255 register failure!\n");
}
PortA=(volatile unsigned long)ioremap_nocache(r8255_A,1024);
if (check_mem_region(PortA, 1024)<0)
{
printk("8255A: Cannot map memory:%08x, memory already in use\n", (int)r8255_A);
return -1;
}
else
{
printk("8255A: Memory remap:%x => %lx\n",r8255_A,PortA);
}
request_mem_region(PortA,1024,"8255DRV");
PortB=PortA+2;
printk("8255 B port's virtual addr base=0x%lx\n",PortB);
PortC=PortA+4;
printk("8255 C port's virtual addr base=0x%lx\n",PortC);
Con=PortA+6;
printk("8255 control port's virtual addr base=0x%lx\n",Con);
printk("<1>8255 register success!");
return ret;
}
static void __exit D8255_clearup(void)
{
int ret;
ret = unregister_chrdev(MAJOR_NUM, Dname);
if(ret<0)
{
printk("<1>8255 unregister failure!\n");
}
else
{
iounmap((long *)Con);
iounmap((long *)PortA);
iounmap((long *)PortB);
iounmap((long *)PortC);
release_mem_region(PortA,1024);
printk("8255 unregister success!\n");
}
}
static int D8255_write(struct file *filp,char *buf,int len,loff_t *off)
{
unsigned long iodata;
barrier();
writew(0x8080,Con);//设置控制字,均为方式0输出
udelay(2);
mb();
printk("write Con=%x\n",readw(Con));
if(copy_from_user(&iodata,buf,len))
{return -EFAULT;}
udelay(2);
writew(iodata,PortA);//A口输出数据
udelay(5);
printk("write A!\n");
return len;
}
module_init(D8255_init);
module_exit(D8255_clearup);
驱动程序加载等都成功。
8255的片选信号和写信号都正确,用示波器已经测量过。但是为什么writew(0x8080,Con);测量数据线上的总是不对。我用的是双通道示波器,将片选下降沿作为触发。此时用另一只表笔测量数据线,发现从d7到d0全是在片选的下降沿一会高一会低,这八位变化情况一样。测量执行writew(iodata,PortA)时,测量数据线上的数据在、都是正确的。这是什么原因呢?请各位大侠帮忙分析一下。
|
|