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

📄 pciioctl.c

📁 个人根据海德汉平面光栅Windows下的程序编写得Linux下的驱动程去源码
💻 C
字号:
#ifndef __KERNEL__#	define __KERNEL__#endif#ifndef MODULE#	define MODULE#endif#define __NO_VERSION__#include <linux/kernel.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/pci.h>#include <math.h>#include <asm/io.h>#include <asm/segment.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm/uaccess.h>#include <rtai_sched.h>#include <rtai_leds.h>#include <rtai_fifos.h>#include <rtai_shm.h>#include <linux/ioctl.h>#include <linux/delay.h>#include <linux/time.h>#include "pciioctl.h"#include "portdefine.h"#include "pgm.h"#define IK_VENDOR 	0x8086#define IK_DEVICE	 0x24c5#define DRV_NAME 	"IK220"#define TV_2s		2000000000#define TV_1ms		1000000#define TV_100us	100000	static RT_TASK task_one;MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;int Xbaseport;int Ybaseport;int cardbaseport;int cardconfreg;static int codemode;int latchstate;//read_write_t IK_read(struct inode *inode,struct file *filp,char *buf,count_t count);//read_write_t IK_write(struct inode *inode,struct file *filp,char *buf,count_t count);/*	pre-defined function	*/int IK_open(struct inode *inode,struct file *filp);int IK_release(struct inode *inode,struct file *filp);int IK_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);//	input and output function defined	void IKoutw(int axisbase,int adr,int data){	int address;	address=axisbase+adr;	writew(data,address);}int IKinw(int axisbase,int adr,int *pbuffer){	int address;	address=axisbase+adr;	*pbuffer=readw(address);	return TRUE;}int IKinl(int axisbase,int adr,int *pbuffer){	int address;	address=axisbase+adr;	*((int*)pbuffer)=readw(address);	*((int*)(pbuffer+1))=readw(address+1);	return TRUE;}		int IKoutcmd(int ax,int IK220CMD){	int reg;	IKoutw(ax,CMDPORT,IK220CMD);	IKinw(ax,DATPORT0,&reg);	if(reg!=IK220CMD)	{		printk("error when write cmd to IK220");		return FALSE;	}	return TRUE;}int timeout(unsigned long just,unsigned long tv){	unsigned long now;	now=rt_get_time_ns();	just=just+tv;	if(now>=just)		return TRUE;	else		return FALSE;}int ramwrite(int axisadd,int ramadd,int data){	int reg;	unsigned long tv_just;	IKoutw(axisadd,CONTROLREG,BOOTMODE);	tv_just=rt_get_time_ns();	do	{		IKinw(axisadd,STATUSREG,&reg);	}	while(!(reg&PIPEEMPTY)&&!timeout(tv_just,TV_1ms));	IKinw(axisadd,STATUSREG,&reg);	if(!(reg&PIPEEMPTY))		return FALSE;	IKoutw(axisadd,G28PORT0,ramadd); 	IKoutw(axisadd,G28PORT1,data); 	IKoutw(axisadd,CONTROLREG,WRITERAMMODE); 		return TRUE;}int download(int add,int *ppgmdata,int pgmsize){	int i;	int ramadr;	if((pgmsize<(3*2))|(pgmsize>65536+2)*2)		return FALSE;	ppgmdata++;	ramadr=*ppgmdata++;	for(i=1;i<=(pgmsize/2)-2;i++)		if(!(ramwrite(add,ramadr++,*ppgmdata++)))			return FALSE-1;	return TRUE;}int IK220init(int addr){	int reg;	unsigned long tv_just;	if(!download(addr,&pgm220[0],sizeof(pgm220)))		return FALSE;	if(!IKinw(addr,CLRFLAG1REG,&reg))		return FALSE-1;	IKoutw(addr,CONTROLREG,RUNMODE);	tv_just=rt_get_time_ns();	do	{		if(!IKinw(addr,FLAG1REG,&reg))			return FALSE-3;	}	while(!(reg&G28SEM10)&&!timeout(tv_just,TV_2s));		if(!IKinw(addr,FLAG1REG,&reg))		return FALSE-4;	if(!(reg&G28SEM10))			{			printk("timeout!\n");		return FALSE-5;	}		if(!IKinw(addr,CLRFLAG1REG,&reg))		return FALSE-6;	return TRUE;			}int Get48val(int adr,int la){	int reg;	double data=0;	double *pdata=(double *)&data;	int count=0;	int *pcount=(int*)&count;	IKinw(adr,STAPORT,&reg);	if(!(reg&(1<<la)))	{			printk("error latch for get data");			return FALSE;	}		IKoutcmd(adr,(int)(CMDGETCNT0+la));	IKinl(adr,DATPORT1,pcount);	pcount=pcount+2;	IKinw(adr,DATPORT3,pcount);		if(*pcount&0x8000)	{		pcount=pcount+1;		*pcount=0xFFFF;	}	*pdata=(double)count/65536.0;	return *pdata;}//	read parameter to registerint IK220writepar(int address,int parnum,long parval){	int reg;	IKoutw(address,DATPORT1,parnum);		IKoutw(address,DATPORT2,(parval&&0xFFFF));	//write high 16 bit	IKoutw(address,DATPORT1,(parnum>>16));		//write low 16 bit	if(!IKoutcmd(address,CMDWRITEPAR))		return FALSE;	IKinw(address,DATPORT2,&reg);	if(reg!=0)			return FALSE;		return TRUE;}int latchint(int address)	//card base address{	int reg,data;	reg=address+CONFREG_CNTRL;	data=readl(reg);	data=data&0xFFFFFEFF;	writel(data,reg);	udelay(2);	data=data|0x00000100;	writel(data,reg);	return TRUE;}int IKlatch(int address,int la)		//axis base address{	if(!IKoutcmd(address,(int)(CMDLATCH0+la)))		return FALSE;	else		return TRUE;}int IKlatched(int addr,int la,int *ls){	int reg;	*ls=FALSE;		IKinw(addr,STAPORT,&reg);	if((reg&(1<<la)))		*ls=TRUE;	return *ls;}int IKwaitlatched(int addr,int la){	int reg;	unsigned long tv_just;		tv_just=rt_get_time_ns();	do	{		IKinw(addr,STAPORT,&reg);	}	while(!(reg&(1<<la))&&!timeout(tv_just,TV_100us));	IKinw(addr,STAPORT,&reg);	if(!(reg&(1<<la)))		return FALSE;	return TRUE;}int IKstart(int addr){	if(!IKoutcmd(addr,CMDSTART))		return FALSE;	return TRUE;}int IKreset(int addr){	if(!IKoutcmd(addr,CMDRESET))		return FALSE;	return TRUE;}int IKstop(int addr){	if(!IKoutcmd(addr,CMDSTOP))		return FALSE;	return TRUE;}//	file operations for user to control kernel modulestatic struct file_operations IK_fops={	owner:		THIS_MODULE,//	read:		IK_read,//	write:		IK_write,	open:		IK_open,	release:	IK_release,	ioctl:		IK_ioctl,};int IK_open(struct inode *inode,struct file *filp){	MOD_INC_USE_COUNT;	printk("now open the device\n");	return 0;}	int IK_release(struct inode *inode,struct file *filp){	MOD_DEC_USE_COUNT;	return 0;}//	ioctlsint IK_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){	int ret=0;	switch(cmd) {//	#ifdef IK_DEBUG		case IK_IOCHARDRESET:		while(MOD_IN_USE)			MOD_DEC_USE_COUNT;		MOD_INC_USE_COUNT;//	#endif		case IK_IOCSTART:			IKstart(Xbaseport);			IKstart(Ybaseport);			sample_period=resetnum*1000000;			rt_task_make_periodic_relative_ns(&task_one,0,sample_period);					ret=1;			checkstate=1;			break;		case IK_IOCSTOP:			IKstop(Xbaseport);			IKstop(Ybaseport);			rt_task_suspend(&task_one);			ret=2;			checkstate=0;			break;		case IK_IOCRESET:			rt_task_suspend(&task_one);			if(arg==1)				IKreset(Xbaseport);			else if(arg==2)				IKreset(Ybaseport);			else			{				IKreset(Xbaseport);				IKreset(Ybaseport);			}						rt_task_make_periodic_relative_ns(&task_one,0,sample_period);					break;	//		code mode select:incremental or Endata model			case IK_IOCENCODE:			if(arg==1||arg==0)			{				if(!IK220writepar(Xbaseport,1,arg))					{					printk("error when write par for code X");					break;				}
				if(!IK220writepar(Ybaseport,1,arg))	
				{
					printk("error when write par for code Y");
					break;
				}//	no Endata 		if(arg==1)	//if select ENDAT model//	when debug       	{//					reset code model//					if(!IK220reseten(AXIS,&enstatus))//						printk("error in reseten");//						configen(not understand???//					if(!IK220configen(AXIS,&enstatus,...))//				}			}			else				printk("wrong input command\n");			if(arg==0)					codemode=0;			else					codemode=1;						ret=3;			break;	//		signal model select			case IK_IOCSIGNAL:			if(arg==1||arg==0)			{				if(!IK220writepar(Xbaseport,2,arg))	
				{					printk("error when write par for X axis signal\n ");
					break;
				}
				if(!IK220writepar(Ybaseport,2,arg))
				{
					printk("error when write par for Y axis signal\n ");
					break;
				}			}			else				printk("wrong input command for signal");			ret=4;			break;//		set sampling period		case IK_IOCSETPERIOD:			if(checkstate==1)			{					printk("Stop the task first!\n");				break;			}			resetnum=arg;			ret=5;			break;		case IK_IOCREAD:			break;		default:			return -10;	}	return 1;}//	PCI drivers for getting IK_card informations	static struct pci_device_id IK_pci_tbl[] __initdata={	{IK_VENDOR,IK_DEVICE,PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{0,}};/*		Get card informations get iobase port address,memory address,	configure port address...	Initialize registers*/static int __init IK_probe(struct pci_dev *dev,const struct pci_device_id *id){		int ionum;///////////////////////////////////////////////////////////////////////////////////////////Get PORTBASE,Xbaseport,Ybaseport,MEMBASE,remap address...  ///////////////////////////////////////////////////////////////////////////////		if(pci_enable_device(dev))		return -EIO;		printk("irq=%d",dev->irq);	for(ionum=0;ionum<6;ionum++)	{		cardbaseport=pci_resource_start(dev,ionum);		if(cardbaseport!=0)			printk("IOBASE%d=%x ",ionum,cardbaseport);	}	Xbaseport=0;	Ybaseport=0;	cardbaseport=0;	cardconfreg=0;///////////////////////////////////////////////////////////////////////////////////////////	Init ...	////////////////////////////////////////////////////////////////////////////////		IK220init(Xbaseport);		//init X axis	IK220init(Ybaseport);		//init Y axis		encodetype=0;				//init code type	signaltype=1;				//init signal type	IK220writepar(Xbaseport,1,encodetype);	IK220writepar(Xbaseport,2,encodetype);	IK220writepar(Ybaseport,1,encodetype);	IK220writepar(Ybaseport,2,encodetype);		latchint(cardconfreg);		//init int latch	IKlatch(Xbaseport,0);		//latch0 for X axis	IKlatch(Ybaseport,0);		//latch0 for Y axis	//	IKstart(Xbaseport);		//start X axis	counter	//	IKstart(Ybaseport);		//start Y axis	counter			return 0;}/*	Free memory space 	Unregisting all...*/static void __devexit IK_remove(struct pci_dev *dev){	printk("remove device irq=%d\n",dev->irq);}static struct pci_driver IK_driver={	name:DRV_NAME,	id_table:IK_pci_tbl,	probe:IK_probe,	remove:__devexit_p(IK_remove),};/* *	Task for get x,y axis data and save them in memory  *	or put them to user space and do control with the data  */static void IK_task(int fifo){	while(1)	{		printk("now in rt_task\t");		if(codemode)	//Endata model		{//			xposition=GetEnval(Xbaseport,latchx);			//			yposition=GetEnval(Ybaseport,latchy);		}		else		//incremental model		{			if(!IKlatched(Xbaseport,0,&latchstate))			{				if(IKwaitlatched(Xbaseport,0))					xposition=Get48val(Xbaseport,0);				else					printk("latched X axis failed\n");			}			else				xposition=Get48val(Xbaseport,0);			if(!IKlatched(Ybaseport,0,&latchstate))			{				if(IKwaitlatched(Xbaseport,0))					xposition=Get48val(Ybaseport,0);				else					printk("latched Y axis failed\n");			}			else				xposition=Get48val(Ybaseport,0);				xpresent=xpresent+xposition;			ypresent=ypresent+yposition;		}		rt_task_wait_period();	}}static int __init IK_init_module(void){	int result;	resetnum=10;	rt_task_init(&task_one,IK_task,0,10000,0,1,0);	rt_set_oneshot_mode();	start_rt_timer(1);	result=register_chrdev(140,"PCI_IK",&IK_fops);	if(result<0)	{	 	printk("PCI_IK:can't register"); 	 	return result;	}	else		return pci_module_init(&IK_driver);}static void __exit IK_cleanup_module(void){	unregister_chrdev(140,"PCI_IK");	pci_unregister_driver(&IK_driver);	printk("test finished!");}	module_init(IK_init_module);module_exit(IK_cleanup_module);

⌨️ 快捷键说明

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