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

📄 dt3000.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		cmd->scan_end_arg=cmd->chanlist_len;		err++;	}	if(cmd->stop_src==TRIG_COUNT){		if(cmd->stop_arg>0x00ffffff){			cmd->stop_arg=0x00ffffff;			err++;		}	}else{		/* TRIG_NONE */		if(cmd->stop_arg!=0){			cmd->stop_arg=0;			err++;		}	}	if(err)return 3;	/* step 4: fix up any arguments */	if(cmd->scan_begin_src==TRIG_TIMER){		tmp=cmd->scan_begin_arg;		dt3k_ns_to_timer(100,&cmd->scan_begin_arg,				cmd->flags&TRIG_ROUND_MASK);		if(tmp!=cmd->scan_begin_arg)err++;	}else{		/* not supported */	}	if(cmd->convert_src==TRIG_TIMER){		tmp=cmd->convert_arg;		dt3k_ns_to_timer(50,&cmd->convert_arg,				cmd->flags&TRIG_ROUND_MASK);		if(tmp!=cmd->convert_arg)err++;		if(cmd->scan_begin_src==TRIG_TIMER &&		  cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg){			cmd->scan_begin_arg = cmd->convert_arg * cmd->scan_end_arg;			err++;		}	}else{		/* not supported */	}	if(err)return 4;	return 0;}static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,	unsigned int round_mode){	int divider, base, prescale;	/* This function needs improvment */	/* Don't know if divider==0 works. */	for(prescale=0;prescale<16;prescale++){		base = timer_base * (prescale+1);		switch(round_mode){		case TRIG_ROUND_NEAREST:		default:			divider = (*nanosec+base/2)/base;			break;		case TRIG_ROUND_DOWN:			divider = (*nanosec)/base;			break;		case TRIG_ROUND_UP:			divider = (*nanosec)/base;			break;		}		if(divider<65536){			*nanosec = divider*base;			return (prescale<<16)|(divider);		}	}		prescale = 15;	base = timer_base * (1<<prescale);	divider = 65535;	*nanosec = divider*base;	return (prescale<<16)|(divider);}static int dt3k_ai_cmd(comedi_device *dev,comedi_subdevice *s){	comedi_cmd *cmd = &s->async->cmd;	int i;	unsigned int chan,range,aref;	unsigned int divider;	unsigned int tscandiv;	int ret;	unsigned int mode;printk("dt3k_ai_cmd:\n");	for(i=0;i<cmd->chanlist_len;i++){		chan=CR_CHAN(cmd->chanlist[i]);		range=CR_RANGE(cmd->chanlist[i]);				writew((range<<6)|chan,dev->iobase+DPR_ADC_buffer+i);	}	aref=CR_AREF(cmd->chanlist[0]);		writew(cmd->scan_end_arg,dev->iobase+DPR_Params(0));printk("param[0]=0x%04x\n",cmd->scan_end_arg);	if(cmd->convert_src==TRIG_TIMER){		divider = dt3k_ns_to_timer(50,&cmd->convert_arg,			cmd->flags&TRIG_ROUND_MASK);		writew((divider>>16),dev->iobase+DPR_Params(1));printk("param[1]=0x%04x\n",divider>>16);		writew((divider&0xffff),dev->iobase+DPR_Params(2));printk("param[2]=0x%04x\n",divider&0xffff);	}else{		/* not supported */	}	if(cmd->scan_begin_src==TRIG_TIMER){		tscandiv = dt3k_ns_to_timer(100,&cmd->scan_begin_arg,			cmd->flags&TRIG_ROUND_MASK);		writew((tscandiv>>16),dev->iobase+DPR_Params(3));printk("param[3]=0x%04x\n",tscandiv>>16);		writew((tscandiv&0xffff),dev->iobase+DPR_Params(4));printk("param[4]=0x%04x\n",tscandiv&0xffff);	}else{		/* not supported */	}		mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;	writew(mode,dev->iobase+DPR_Params(5));printk("param[5]=0x%04x\n",mode);	writew(aref==AREF_DIFF,dev->iobase+DPR_Params(6));printk("param[6]=0x%04x\n",aref==AREF_DIFF);	writew(AI_FIFO_DEPTH/2,dev->iobase+DPR_Params(7));printk("param[7]=0x%04x\n",AI_FIFO_DEPTH/2);		writew(SUBS_AI,dev->iobase+DPR_SubSys);	ret = dt3k_send_cmd(dev,CMD_CONFIG);	writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,		dev->iobase + DPR_Int_Mask);debug_n_ints = 0;	writew(SUBS_AI,dev->iobase+DPR_SubSys);	ret = dt3k_send_cmd(dev,CMD_START);	return 0;}static int dt3k_ai_cancel(comedi_device *dev,comedi_subdevice *s){	int ret;	writew(SUBS_AI,dev->iobase+DPR_SubSys);	ret = dt3k_send_cmd(dev,CMD_STOP);	writew(0, dev->iobase + DPR_Int_Mask);	return 0;}static int dt3k_ai_insn(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	int i;	unsigned int chan,gain,aref;	chan=CR_CHAN(insn->chanspec);	gain=CR_RANGE(insn->chanspec);	/* XXX docs don't explain how to select aref */	aref=CR_AREF(insn->chanspec);	for(i=0;i<insn->n;i++){		data[i]=dt3k_readsingle(dev,SUBS_AI,chan,gain);	}	return i;}static int dt3k_ao_insn(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	int i;	unsigned int chan;	chan=CR_CHAN(insn->chanspec);	for(i=0;i<insn->n;i++){		dt3k_writesingle(dev,SUBS_AO,chan,data[i]);		devpriv->ao_readback[chan]=data[i];	}	return i;}static int dt3k_ao_insn_read(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	int i;	unsigned int chan;	chan=CR_CHAN(insn->chanspec);	for(i=0;i<insn->n;i++){		data[i]=devpriv->ao_readback[chan];	}	return i;}static void dt3k_dio_config(comedi_device *dev,int bits){	/* XXX */	writew(SUBS_DOUT,dev->iobase+DPR_SubSys);		writew(bits,dev->iobase+DPR_Params(0));#if 0	/* don't know */	writew(0,dev->iobase+DPR_Params(1));	writew(0,dev->iobase+DPR_Params(2));#endif		dt3k_send_cmd(dev,CMD_CONFIG);}static int dt3k_dio_insn_config(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	int mask;	if(insn->n!=1)return -EINVAL;	mask=(CR_CHAN(insn->chanspec)<4)?0x0f:0xf0;	if(data[0]==COMEDI_OUTPUT)s->io_bits|=mask;	else s->io_bits&=~mask;	mask=(s->io_bits&0x01)|((s->io_bits&0x10)>>3);	dt3k_dio_config(dev,mask);	return 1;}static int dt3k_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	if(insn->n!=2)return -EINVAL;	if(data[0]){		s->state &= ~data[0];		s->state |= data[1]&data[0];		dt3k_writesingle(dev,SUBS_DOUT,0,s->state);	}	data[1]=dt3k_readsingle(dev,SUBS_DIN,0,0);	return 2;}static int dt3k_mem_insn_read(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	unsigned int addr=CR_CHAN(insn->chanspec);	int i;	for(i=0;i<insn->n;i++){		writew(SUBS_MEM,dev->iobase+DPR_SubSys);		writew(addr,dev->iobase+DPR_Params(0));		writew(1,dev->iobase+DPR_Params(1));		dt3k_send_cmd(dev,CMD_READCODE);		data[i]=readw(dev->iobase+DPR_Params(2));	}		return i;}static int dt_pci_probe(comedi_device *dev);static int dt3000_attach(comedi_device *dev,comedi_devconfig *it){	comedi_subdevice *s;	int ret=0;		printk("dt3000:");	if(!pci_present()){		printk(" no PCI bus\n");		return -EINVAL;	}		if((ret=alloc_private(dev,sizeof(dt3k_private)))<0)		return ret;	ret=dt_pci_probe(dev);	if(ret<0)return ret;	if(ret==0){		printk(" no DT board found\n");		return -ENODEV;	}	dev->board_name = this_board->name;	if(comedi_request_irq(devpriv->pci_dev->irq, dt3k_interrupt,			SA_SHIRQ, "dt3000", dev)){		printk(" unable to allocate IRQ %d\n", devpriv->pci_dev->irq);		return -EINVAL;	}	dev->irq = devpriv->pci_dev->irq;	if( (ret = alloc_subdevices(dev, 4)) <0)		return ret;	s=dev->subdevices;	dev->read_subdev = s;	/* ai subdevice */	s->type=COMEDI_SUBD_AI;	s->subdev_flags=SDF_READABLE|SDF_GROUND|SDF_DIFF;	s->n_chan=this_board->adchan;	s->insn_read=dt3k_ai_insn;	s->maxdata=(1<<this_board->adbits)-1;	s->len_chanlist=512;	s->range_table=&range_dt3000_ai; /* XXX */	s->do_cmd = dt3k_ai_cmd;	s->do_cmdtest = dt3k_ai_cmdtest;	s->cancel = dt3k_ai_cancel;	s++;	/* ao subsystem */	s->type=COMEDI_SUBD_AO;	s->subdev_flags=SDF_WRITABLE;	s->n_chan=2;	s->insn_read=dt3k_ao_insn_read;	s->insn_write=dt3k_ao_insn;	s->maxdata=(1<<this_board->dabits)-1;	s->len_chanlist=1;	s->range_table=&range_bipolar10;	s++;	/* dio subsystem */	s->type=COMEDI_SUBD_DIO;	s->subdev_flags=SDF_READABLE|SDF_WRITABLE;	s->n_chan=8;	s->insn_config=dt3k_dio_insn_config;	s->insn_bits=dt3k_dio_insn_bits;	s->maxdata=1;	s->len_chanlist=8;	s->range_table=&range_digital;	s++;	/* mem subsystem */	s->type=COMEDI_SUBD_MEMORY;	s->subdev_flags=SDF_READABLE;	s->n_chan=0x1000;	s->insn_read=dt3k_mem_insn_read;	s->maxdata=0xff;	s->len_chanlist=1;	s->range_table=&range_unknown;#if 0	s++;	/* proc subsystem */	s->type=COMEDI_SUBD_PROC;#endif	return 0;}static int dt3000_detach(comedi_device *dev){	if(dev->irq)comedi_free_irq(dev->irq,dev);	/* XXX */	return 0;}static struct pci_dev *dt_pci_find_device(struct pci_dev *from,int *board);static int setup_pci(comedi_device *dev);static int dt_pci_probe(comedi_device *dev){	int board;	devpriv->pci_dev=dt_pci_find_device(NULL,&board);	dev->board_ptr=dt3k_boardtypes+board;	if(!devpriv->pci_dev)		return 0;	setup_pci(dev);	return 1;}static int setup_pci(comedi_device *dev){	unsigned long		offset;	u32			addr;	int ret;	ret = pci_enable_device(devpriv->pci_dev);	if(ret<0)return ret;	addr=pci_resource_start(devpriv->pci_dev,0);	devpriv->phys_addr=addr;	offset = devpriv->phys_addr & ~PAGE_MASK;	devpriv->io_addr = ioremap(devpriv->phys_addr & PAGE_MASK, DT3000_SIZE + offset )		+ offset;#if DEBUG	printk("0x%08lx mapped to %p, ",devpriv->phys_addr,devpriv->io_addr);#endif	dev->iobase = (int)devpriv->io_addr;	return 0;}#if LINUX_VERSION_CODE < 0x020300static struct pci_dev *dt_pci_find_device(struct pci_dev *from,int *board){	int i;		if(!from){		from=pci_devices;	}else{		from=from->next;	}	while(from){		if(from->vendor == PCI_VENDOR_ID_DT){			for(i=0;i<n_dt3k_boards;i++){				if(from->device == dt3k_boardtypes[i].device_id){					*board=i;					return from;				}			}			printk("unknown Data Translation PCI device found with device_id=0x%04x\n",from->device);		}		from=from->next;	}	*board=-1;	return from;}#elsestatic struct pci_dev *dt_pci_find_device(struct pci_dev *from,int *board){	int i;		if(!from){		from=(struct pci_dev *)(pci_devices.next);	}else{		from=(struct pci_dev *)(from->global_list.next);	}	while(from){		if(from->vendor == PCI_VENDOR_ID_DT){			for(i=0;i<n_dt3k_boards;i++){				if(from->device == dt3k_boardtypes[i].device_id){					*board=i;					return from;				}			}			printk("unknown Data Translation PCI device found with device_id=0x%04x\n",from->device);		}		from=(struct pci_dev *)(from->global_list.next);	}	*board=-1;	return from;}#endif

⌨️ 快捷键说明

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