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

📄 adl_pci9118.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if (m & 0x008) {		comedi_error(dev,"A/D Burst Mode Overrun Status (Fatal Error!)");		devpriv->ai_maskerr&=~0x008L;	}	if (m & 0x004) {		comedi_error(dev,"A/D Over Speed Status (Warning!)");		devpriv->ai_maskerr&=~0x004L;	}	if (m & 0x002) {		comedi_error(dev,"A/D Overrun Status (Fatal Error!)");		devpriv->ai_maskerr&=~0x002L;	}	if (m & devpriv->ai_maskharderr) {		s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;		pci9118_ai_cancel(dev,s);		comedi_event(dev,s,s->async->events);		return 1;	}	return 0;}/*==============================================================================*/static void interrupt_pci9118_ai_onesample(comedi_device *dev,comedi_subdevice *s,	unsigned short int_adstat, unsigned int int_amcc, unsigned short int_daq){	register sampl_t sampl;	s->async->events=0;	if (int_adstat & devpriv->ai_maskerr)		if (pci9118_decode_error_status(dev,s,int_adstat))			return;	sampl=inw(dev->iobase+PCI9118_AD_DATA);	if (devpriv->ai16bits) {		cfc_write_to_buffer( s, sampl ^ 0x8000 );	} else {#ifdef PCI9118_PARANOIDCHECK		if ((sampl & 0x000f)!=devpriv->chanlist[s->async->cur_chan]) { // data dropout!	    		rt_printk("comedi: A/D  SAMPL - data dropout: received channel %d, expected %d!\n",sampl & 0x000f, devpriv->chanlist[s->async->cur_chan]);			s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;			pci9118_ai_cancel(dev,s);			comedi_event(dev,s,s->async->events);			return;		}#endif		cfc_write_to_buffer( s, ( sampl >> 4 ) & 0x0fff );	}	if (s->async->cur_chan == 0) {	/* one scan done */		devpriv->ai_act_scan++;		if (!(devpriv->ai_neverending))			if (devpriv->ai_act_scan>=devpriv->ai_scans) {	/* all data sampled */				pci9118_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA;			}	}	if (s->async->events)		comedi_event(dev,s,s->async->events);}/*==============================================================================*/static void interrupt_pci9118_ai_dma(comedi_device *dev,comedi_subdevice *s,	unsigned short int_adstat, unsigned int int_amcc, unsigned short int_daq){        lsampl_t 	*ptr;	unsigned int	next_dma_buf, samplesinbuf, sampls, m;	s->async->events=0;	if (int_amcc&MASTER_ABORT_INT) {		comedi_error(dev,"AMCC IRQ - MASTER DMA ABORT!");		s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;		pci9118_ai_cancel(dev,s);		comedi_event(dev,s,s->async->events);		return;	}	if (int_amcc&TARGET_ABORT_INT) {    		comedi_error(dev,"AMCC IRQ - TARGET DMA ABORT!");		s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;		pci9118_ai_cancel(dev,s);		comedi_event(dev,s,s->async->events);		return;	}	if (int_adstat & devpriv->ai_maskerr)//	if (int_adstat & 0x106)		if (pci9118_decode_error_status(dev,s,int_adstat))			return;	samplesinbuf=devpriv->dmabuf_use_size[devpriv->dma_actbuf]>>1; // number of received real samples//	DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf);	if (devpriv->dma_doublebuf) {	// switch DMA buffers if is used double buffering    		next_dma_buf=1-devpriv->dma_actbuf;		outl(devpriv->dmabuf_hw[next_dma_buf], devpriv->iobase_a+AMCC_OP_REG_MWAR);    		outl(devpriv->dmabuf_use_size[next_dma_buf], devpriv->iobase_a+AMCC_OP_REG_MWTC);		devpriv->dmabuf_used_size[next_dma_buf]=devpriv->dmabuf_use_size[next_dma_buf];		if (devpriv->ai_do==4)			interrupt_pci9118_ai_mode4_switch(dev);	}        ptr=(lsampl_t *)devpriv->dmabuf_virt[devpriv->dma_actbuf];	while (samplesinbuf) {		m = devpriv->ai_data_len >> 1; // how many samples is to end of buffer//		DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);		sampls=m;		if (devpriv->dma_ai_read_block(dev, s, &ptr,		    &sampls, &samplesinbuf))			return; // Uiii, error		m=m-sampls; // m= how many samples was transfered	}//	DPRINTK("YYY\n");	if (!devpriv->ai_neverending)    		if ( devpriv->ai_act_scan>=devpriv->ai_scans ) { /* all data sampled */			pci9118_ai_cancel(dev,s);			s->async->events|=COMEDI_CB_EOA;		}	if (devpriv->dma_doublebuf) { // switch dma buffers		devpriv->dma_actbuf=1-devpriv->dma_actbuf;	} else { // restart DMA if is not used double buffering		outl(devpriv->dmabuf_hw[0], devpriv->iobase_a+AMCC_OP_REG_MWAR);		outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a+AMCC_OP_REG_MWTC);		if (devpriv->ai_do==4) 			interrupt_pci9118_ai_mode4_switch(dev); 	}	comedi_event(dev,s,s->async->events);}/* ==============================================================================*/static void interrupt_pci9118(int irq, void *d, struct pt_regs *regs) {	comedi_device *dev = d;	unsigned int	int_daq=0,int_amcc,int_adstat;			int_daq=inl(dev->iobase+PCI9118_INTSRC) & 0xf;		// get IRQ reasons from card	int_amcc=inl(devpriv->iobase_a+AMCC_OP_REG_INTCSR);	// get INT register from AMCC chip//	DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);	if ((!int_daq)&&(!(int_amcc&ANY_S593X_INT)))		return;	// interrupt from other source	outl(int_amcc|0x00ff0000, devpriv->iobase_a+AMCC_OP_REG_INTCSR); // shutdown IRQ reasons in AMCC	int_adstat=inw(dev->iobase+PCI9118_ADSTAT)&0x1ff;	// get STATUS register	if (devpriv->ai_do) {		if (devpriv->ai12_startstop) 			if ((int_adstat&AdStatus_DTH)&&(int_daq&Int_DTrg)) {	// start stop of measure				if (devpriv->ai12_startstop&START_AI_EXT) {					devpriv->ai12_startstop&=~START_AI_EXT;					if (!(devpriv->ai12_startstop&STOP_AI_EXT))						pci9118_exttrg_del(dev,EXTTRG_AI);		// deactivate EXT trigger					start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);	// start pacer					outl(devpriv->AdControlReg, dev->iobase+PCI9118_ADCNTRL);				} else {					if (devpriv->ai12_startstop&STOP_AI_EXT) {						devpriv->ai12_startstop&=~STOP_AI_EXT;						pci9118_exttrg_del(dev,EXTTRG_AI);		// deactivate EXT trigger						devpriv->ai_neverending=0; //well, on next interrupt from DMA/EOC measure will stop					}				}			}		(devpriv->int_ai_func)(dev,dev->subdevices + 0,int_adstat,int_amcc,int_daq);	}}/*==============================================================================*/static int pci9118_ai_inttrig(comedi_device *dev,comedi_subdevice *s,	unsigned int trignum){	if (trignum!=devpriv->ai_inttrig_start) return -EINVAL;	devpriv->ai12_startstop&=~START_AI_INT;	s->async->inttrig=NULL;	outl(devpriv->IntControlReg,dev->iobase+PCI9118_INTCTRL);	outl(devpriv->AdFunctionReg,dev->iobase+PCI9118_ADFUNC);	if (devpriv->ai_do!=3) {		start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);		devpriv->AdControlReg|=AdControl_SoftG;	}	outl(devpriv->AdControlReg, dev->iobase+PCI9118_ADCNTRL);	return 1;}/*==============================================================================*/static int pci9118_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd){	int err=0;	int tmp,divisor1,divisor2;	/* step 1: make sure trigger sources are trivially valid */	tmp=cmd->start_src;	cmd->start_src &= TRIG_NOW|TRIG_EXT|TRIG_INT;	if (!cmd->start_src || tmp!=cmd->start_src) err++;	tmp=cmd->scan_begin_src;	if (devpriv->master) {		cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT|TRIG_FOLLOW;	} else {		cmd->scan_begin_src &= TRIG_FOLLOW;	}	if (!cmd->scan_begin_src || tmp!=cmd->scan_begin_src) err++;	tmp=cmd->convert_src;	if (devpriv->master) {		cmd->convert_src &= TRIG_TIMER|TRIG_EXT|TRIG_NOW;	} else {		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|TRIG_EXT;	if (!cmd->stop_src || tmp!=cmd->stop_src) err++;	if (err) return 1;	/* step 2: make sure trigger sources are unique and mutually compatible */	if (cmd->start_src!=TRIG_NOW &&	    cmd->start_src!=TRIG_INT &&	    cmd->start_src!=TRIG_EXT) {		cmd->start_src=TRIG_NOW;		err++;	}	if (cmd->scan_begin_src!=TRIG_TIMER &&	    cmd->scan_begin_src!=TRIG_EXT &&	    cmd->scan_begin_src!=TRIG_INT &&	    cmd->scan_begin_src!=TRIG_FOLLOW) { 		cmd->scan_begin_src=TRIG_FOLLOW;		err++;	}	if (cmd->convert_src!=TRIG_TIMER &&	    cmd->convert_src!=TRIG_EXT &&	    cmd->convert_src!=TRIG_NOW) {		cmd->convert_src=TRIG_TIMER;		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 &&	    cmd->stop_src!=TRIG_INT &&	    cmd->stop_src!=TRIG_EXT) {		cmd->stop_src=TRIG_COUNT;		err++;	}	if (cmd->start_src==TRIG_EXT &&	    cmd->scan_begin_src==TRIG_EXT) {		cmd->start_src=TRIG_NOW;		err++;	}	if (cmd->start_src==TRIG_INT &&	    cmd->scan_begin_src==TRIG_INT) {		cmd->start_src=TRIG_NOW;		err++;	}	if ((cmd->scan_begin_src&(TRIG_TIMER|TRIG_EXT)) &&	    (!(cmd->convert_src&(TRIG_TIMER|TRIG_NOW)))) {		cmd->convert_src=TRIG_TIMER;		err++;	}			if ((cmd->scan_begin_src==TRIG_FOLLOW) &&	    (!(cmd->convert_src&(TRIG_TIMER|TRIG_EXT)))) {		cmd->convert_src=TRIG_TIMER;		err++;	}			if (cmd->stop_src==TRIG_EXT &&	    cmd->scan_begin_src==TRIG_EXT) {		cmd->stop_src=TRIG_COUNT;		err++;	}	if (err) return 2;	/* step 3: make sure arguments are trivially compatible */	if (cmd->start_src&(TRIG_NOW|TRIG_EXT)) 		if (cmd->start_arg!=0) {			cmd->start_arg=0;			err++;		}	if (cmd->scan_begin_src&(TRIG_FOLLOW|TRIG_EXT))		if (cmd->scan_begin_arg!=0) {			cmd->scan_begin_arg=0;			err++;		}	if ((cmd->scan_begin_src==TRIG_TIMER) &&	    (cmd->convert_src==TRIG_TIMER) &&	    (cmd->scan_end_arg==1)) {		cmd->scan_begin_src=TRIG_FOLLOW;		cmd->convert_arg=cmd->scan_begin_arg;		cmd->scan_begin_arg=0;	}		if (cmd->scan_begin_src==TRIG_TIMER)		if (cmd->scan_begin_arg<this_board->ai_ns_min) {			cmd->scan_begin_arg=this_board->ai_ns_min;			err++;		}	if (cmd->scan_begin_src==TRIG_EXT)		if (cmd->scan_begin_arg) {			cmd->scan_begin_arg=0;			err++;		if (cmd->scan_end_arg>65535) {			cmd->scan_end_arg=65535;			err++;			}		}	if (cmd->convert_src&(TRIG_TIMER|TRIG_NOW))		if (cmd->convert_arg<this_board->ai_ns_min) {			cmd->convert_arg=this_board->ai_ns_min;			err++;		}	if (cmd->convert_src==TRIG_EXT)		if (cmd->convert_arg) {			cmd->convert_arg=0;			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++;		}

⌨️ 快捷键说明

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