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

📄 adv_pci1710.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	int n,rangereg,chan;	chan=CR_CHAN(insn->chanspec);	rangereg=devpriv->da_ranges & (~(0x03<<(chan<<1)));	rangereg|=(CR_RANGE(insn->chanspec)<<(chan<<1));	if (rangereg!=devpriv->da_ranges) {		outb(rangereg, dev->iobase+PCI1720_RANGE);		devpriv->da_ranges=rangereg;	}	for (n=0; n<insn->n; n++) {		outw(data[n], dev->iobase+PCI1720_DA0+(chan<<1));    		outb(0, dev->iobase + PCI1720_SYNCOUT); // update outputs	}	devpriv->ao_data[chan]=data[n];	return n;}/*==============================================================================*/static void interrupt_pci1710_every_sample(void *d){	comedi_device 	*dev = d;	comedi_subdevice *s = dev->subdevices + 0;	int		m;#ifdef PCI171x_PARANOIDCHECK	sampl_t sampl;#endif	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n");	m=inw(dev->iobase+PCI171x_STATUS);	if (m & Status_FE) {		rt_printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);		pci171x_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev,s,s->async->events);		return;	}	if (m & Status_FF) {		rt_printk("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", dev->minor, m);		pci171x_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev,s,s->async->events);		return;	}	outb(0, dev->iobase + PCI171x_CLRINT);			// clear our INT request	DPRINTK("FOR ");	for (;!(inw(dev->iobase+PCI171x_STATUS)&Status_FE);) {#ifdef PCI171x_PARANOIDCHECK		sampl=inw(dev->iobase+PCI171x_AD_DATA);    		DPRINTK("%04x:",sampl);		if (this_board->cardtype!=TYPE_PCI1713)			if ((sampl & 0xf000)!=devpriv->act_chanlist[s->async->cur_chan]) {	    			rt_printk("comedi: A/D data dropout: received data from channel %d, expected %d!\n",(sampl & 0xf000)>>12,(devpriv->act_chanlist[s->async->cur_chan] & 0xf000)>>12);	    			pci171x_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;				comedi_event(dev,s,s->async->events);				return;			}		DPRINTK("%8d %2d %8d~",s->async->buf_int_ptr,s->async->cur_chan,s->async->buf_int_count);		comedi_buf_put( s->async, sampl & 0x0fff);#else		comedi_buf_put( s->async, inw(dev->iobase+PCI171x_AD_DATA) & 0x0fff);#endif		if(s->async->cur_chan == 0){	// one scan done		        devpriv->ai_act_scan++;        		DPRINTK("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n",s->async->buf_int_count,s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr);        		DPRINTK("adv_pci1710 EDBG: EOS2\n");    			if ((!devpriv->neverending_ai)&&(devpriv->ai_act_scan>=devpriv->ai_scans)) { // all data sampled		    		pci171x_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA;				comedi_event(dev,s,s->async->events);				return;			}		}	}	outb(0, dev->iobase + PCI171x_CLRINT);			// clear our INT request	DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");	comedi_event(dev,s,s->async->events);}/* ==============================================================================*/static int move_block_from_fifo(comedi_device *dev,comedi_subdevice *s, int n, int turn){	int i,j;#ifdef PCI171x_PARANOIDCHECK	int sampl;#endif	DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n",n,turn);	j=s->async->cur_chan;	for(i=0;i<n;i++) {#ifdef PCI171x_PARANOIDCHECK		sampl=inw(dev->iobase+PCI171x_AD_DATA);		if (this_board->cardtype!=TYPE_PCI1713)			if ((sampl & 0xf000)!=devpriv->act_chanlist[j]) {	    			rt_printk("comedi%d: A/D  FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",					 dev->minor, (sampl & 0xf000)>>12,(devpriv->act_chanlist[j] & 0xf000)>>12, i, j, devpriv->ai_act_scan, n, turn, sampl);	    			pci171x_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;				comedi_event(dev,s,s->async->events);				return 1;			}		comedi_buf_put( s->async, sampl & 0x0fff );#else		comedi_buf_put( s->async, inw(dev->iobase+PCI171x_AD_DATA) & 0x0fff );#endif		j++;		if(j>=devpriv->ai_n_chan){			j=0;		        devpriv->ai_act_scan++;		}	}	DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");	return 0;}/* ==============================================================================*/static void interrupt_pci1710_half_fifo(void *d) {	comedi_device 	*dev = d;	comedi_subdevice *s = dev->subdevices + 0;	int		m,samplesinbuf;		DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");	m=inw(dev->iobase+PCI171x_STATUS);	if (!(m & Status_FH)) {		rt_printk("comedi%d: A/D FIFO not half full! (%4x)\n", dev->minor, m);		pci171x_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev,s,s->async->events); 		return;	}	if (m & Status_FF) {		rt_printk("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", dev->minor, m);		pci171x_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev,s,s->async->events); 		return;	}	samplesinbuf=this_board->fifo_half_size;	if(samplesinbuf*sizeof(sampl_t)>=devpriv->ai_data_len){		m=devpriv->ai_data_len/sizeof(sampl_t);		if (move_block_from_fifo(dev,s,m,0))			return;		samplesinbuf-=m;	}	if (samplesinbuf) {		if (move_block_from_fifo(dev,s,samplesinbuf,1))			return;	}	if (!devpriv->neverending_ai)    		if ( devpriv->ai_act_scan>=devpriv->ai_scans ) { /* all data sampled */		        pci171x_ai_cancel(dev,s);			s->async->events |= COMEDI_CB_EOA;			comedi_event(dev,s,s->async->events); 			return;		}	outb(0, dev->iobase + PCI171x_CLRINT);			// clear our INT request	DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");	comedi_event(dev,s,s->async->events); }/* ==============================================================================*/static void interrupt_service_pci1710(int irq, void *d, struct pt_regs *regs) {        comedi_device *dev = d;		DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",irq);	if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) 	// is this interrupt from our board?	    return;						// no, exit	DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n",inw(dev->iobase + PCI171x_STATUS));	if (devpriv->ai_et) {	// Switch from initial TRIG_EXT to TRIG_xxx.		devpriv->ai_et = 0;		outw(Control_SW, dev->iobase+PCI171x_CONTROL);		devpriv->CntrlReg=devpriv->ai_et_CntrlReg;		outb(0,dev->iobase + PCI171x_CLRFIFO);		outb(0,dev->iobase + PCI171x_CLRINT);		outw(devpriv->ai_et_MuxVal, dev->iobase+PCI171x_MUX);		outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL);		// start pacer		start_pacer(dev, 1, devpriv->ai_et_div1, devpriv->ai_et_div2);		return;	}	if (devpriv->ai_eos) {  // We use FIFO half full INT or not?		interrupt_pci1710_every_sample(d);	} else {		interrupt_pci1710_half_fifo(d);	}	DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n");}/* ==============================================================================*/static int pci171x_ai_docmd_and_mode(int mode, comedi_device * dev, comedi_subdevice * s) {        unsigned int divisor1, divisor2;	unsigned int seglen;	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",mode);	start_pacer(dev, -1, 0, 0); // stop pacer        seglen = check_channel_list(dev, s, devpriv->ai_chanlist,		devpriv->ai_n_chan);	if(seglen<1)return -EINVAL;        setup_channel_list(dev, s, devpriv->ai_chanlist,		devpriv->ai_n_chan,seglen);	outb(0, dev->iobase + PCI171x_CLRFIFO);	outb(0, dev->iobase + PCI171x_CLRINT);		devpriv->ai_do=mode;        devpriv->ai_act_scan=0;        s->async->cur_chan=0;        devpriv->ai_buf_ptr=0;        devpriv->neverending_ai=0;	devpriv->CntrlReg&=Control_CNT0;	if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { 	// don't we want wake up every scan?		devpriv->ai_eos=1;		devpriv->ai_eos=1;	} else {		devpriv->CntrlReg|=Control_ONEFH;		devpriv->ai_eos=0;	}	if ((devpriv->ai_scans==0)||(devpriv->ai_scans==-1)) { devpriv->neverending_ai=1; } //well, user want neverending							else { devpriv->neverending_ai=0; }	switch (mode) {	case 1:	case 2:		if (devpriv->ai_timer1<this_board->ai_ns_min) devpriv->ai_timer1=this_board->ai_ns_min;		devpriv->CntrlReg|=Control_PACER|Control_IRQEN;		if (mode == 2) {			devpriv->ai_et_CntrlReg=devpriv->CntrlReg;			devpriv->CntrlReg&=~(Control_PACER|Control_ONEFH|Control_GATE);			devpriv->CntrlReg|=Control_EXT;			devpriv->ai_et=1;		} else {			devpriv->ai_et=0;		}		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,&divisor1,&divisor2,&devpriv->ai_timer1,devpriv->ai_flags&TRIG_ROUND_MASK);                DPRINTK("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n",devpriv->i8254_osc_base,divisor1,divisor2,devpriv->ai_timer1);		outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL);		if (mode != 2) {			// start pacer			start_pacer(dev, mode, divisor1, divisor2);		} else {			devpriv->ai_et_div1 = divisor1;			devpriv->ai_et_div2 = divisor2;		}		break;	case 3:		devpriv->CntrlReg|=Control_EXT|Control_IRQEN;		outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL);		break;	}	    	DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");	return 0;}#ifdef PCI171X_EXTDEBUG/* ==============================================================================*/static void pci171x_cmdtest_out(int e,comedi_cmd *cmd) {	rt_printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n",e,cmd->start_src,cmd->scan_begin_src,cmd->convert_src);	rt_printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n",e,cmd->start_arg,cmd->scan_begin_arg,cmd->convert_arg);	rt_printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n",e,cmd->stop_src,cmd->scan_end_src);	rt_printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",e,cmd->stop_arg,cmd->scan_end_arg,cmd->chanlist_len);}#endif/* ==============================================================================*/static int pci171x_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd){	int err=0;	int tmp,divisor1,divisor2;	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");#ifdef PCI171X_EXTDEBUG	pci171x_cmdtest_out(-1, cmd);#endif	/* step 1: make sure trigger sources are trivially valid */	tmp=cmd->start_src;	cmd->start_src &= TRIG_NOW|TRIG_EXT;	if(!cmd->start_src || tmp!=cmd->start_src)err++;	tmp=cmd->scan_begin_src;	cmd->scan_begin_src &= TRIG_FOLLOW;	if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;	tmp=cmd->convert_src;	cmd->convert_src &= TRIG_TIMER|TRIG_EXT;	if(!cmd->convert_src || tmp!=cmd->convert_src)err++;	tmp=cmd->scan_end_src;	cmd->scan_end_src &= TRIG_COUNT;	if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;	tmp=cmd->stop_src;	cmd->stop_src &= TRIG_COUNT|TRIG_NONE;	if(!cmd->stop_src || tmp!=cmd->stop_src)err++;	if(err) {#ifdef PCI171X_EXTDEBUG		pci171x_cmdtest_out(1, cmd);#endif		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n",err);		return 1;	}	/* step 2: make sure trigger sources are unique and mutually compatible */	if(cmd->start_src!=TRIG_NOW&&cmd->start_src!=TRIG_EXT) {		cmd->start_src=TRIG_NOW;		err++;	}	if(cmd->scan_begin_src!=TRIG_FOLLOW) {		cmd->scan_begin_src=TRIG_FOLLOW;		err++;	}	if(cmd->convert_src!=TRIG_TIMER &&	   cmd->convert_src!=TRIG_EXT) err++;	if(cmd->scan_end_src!=TRIG_COUNT) {		cmd->scan_end_src=TRIG_COUNT;		err++;	}	if(cmd->stop_src!=TRIG_NONE &&	   cmd->stop_src!=TRIG_COUNT) err++;	if(err) {#ifdef PCI171X_EXTDEBUG		pci171x_cmdtest_out(2, cmd);#endif		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n",err);		return 2;	}	/* step 3: make sure arguments are trivially compatible */	if(cmd->start_arg!=0){		cmd->start_arg=0;		err++;	}	if(cmd->scan_begin_arg!=0){		cmd->scan_begin_arg=0;		err++;	}	if(cmd->convert_src==TRIG_TIMER){		if(cmd->convert_arg<this_board->ai_ns_min){			cmd->convert_arg=this_board->ai_ns_min;			err++;		}	} else { /* TRIG_FOLLOW */		if(cmd->convert_arg!=0){			cmd->convert_arg=0;			err++;		}	}	if(!cmd->chanlist_len){		cmd->chanlist_len=1;		err++;	}	if(cmd->chanlist_len>this_board->n_aichan){		cmd->chanlist_len=this_board->n_aichan;		err++;	}	if(cmd->scan_end_arg!=cmd->chanlist_len){		cmd->scan_end_arg=cmd->chanlist_len;		err++;	}	if(cmd->stop_src==TRIG_COUNT){		if(!cmd->stop_arg){			cmd->stop_arg=1;			err++;		}	} else { /* TRIG_NONE */		if(cmd->stop_arg!=0){			cmd->stop_arg=0;			err++;		}	}	if(err) {#ifdef PCI171X_EXTDEBUG		pci171x_cmdtest_out(3, cmd);#endif		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n",err);		return 3;	}	/* step 4: fix up any arguments */	if(cmd->convert_src==TRIG_TIMER){		tmp=cmd->convert_arg;		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,&divisor1,&divisor2,&cmd->convert_arg,cmd->flags&TRIG_ROUND_MASK);		if(cmd->convert_arg<this_board->ai_ns_min)			cmd->convert_arg=this_board->ai_ns_min;		if(tmp!=cmd->convert_arg)err++;	}	if(err) {		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n",err);

⌨️ 快捷键说明

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