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

📄 adl_pci9118.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ch=CR_CHAN(insn->chanspec);	if (ch) { chanreg=PCI9118_DA2;} 	    else { chanreg=PCI9118_DA1; } 	for (n=0; n<insn->n; n++) {		outl(data[n], dev->iobase + chanreg);		devpriv->ao_data[ch]=data[n];	}	return n;}/* ==============================================================================*/static int pci9118_insn_read_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data) {	int n,chan;		chan=CR_CHAN(insn->chanspec);	for (n=0; n<insn->n; n++) 		data[n]=devpriv->ao_data[chan];	return n;}/*==============================================================================*/static int pci9118_insn_bits_di(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){	data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;	return 2;}/*==============================================================================*/static int pci9118_insn_bits_do(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){	if(data[0]){		s->state &= ~data[0];		s->state |= (data[0]&data[1]);		outl(s->state & 0x0f, dev->iobase + PCI9118_DO);	}	data[1] = s->state;	return 2;}/*==============================================================================*/static void interrupt_pci9118_ai_mode4_switch(comedi_device *dev) {	devpriv->AdFunctionReg=AdFunction_PDTrg|AdFunction_PETrg|AdFunction_AM;	outl(devpriv->AdFunctionReg,dev->iobase+PCI9118_ADFUNC);	outl(0x30, dev->iobase + PCI9118_CNTCTRL);	outl((devpriv->dmabuf_hw[1-devpriv->dma_actbuf]>>1)&0xff, dev->iobase + PCI9118_CNT0);	outl((devpriv->dmabuf_hw[1-devpriv->dma_actbuf]>>9)&0xff, dev->iobase + PCI9118_CNT0);	devpriv->AdFunctionReg|=AdFunction_Start;	outl(devpriv->AdFunctionReg,dev->iobase+PCI9118_ADFUNC);}/* ==============================================================================  Skip a few samples at begin of every scan if is used software generated  sample&hold signal*/static int skip_front_samples_16b(comedi_device *dev, comedi_subdevice *s,	sampl_t **dma, int *bufs, char x){	unsigned int n;	n=devpriv->ai_add_front-devpriv->ai_act_dmapos; //	DPRINTK("n=%d bufs=%d *dma=0x%08x dmapos=%d %d\n",n,*bufs,*dma,devpriv->ai_act_dmapos,x);	if (*bufs>n) {		(*bufs)-=n;		(*dma)+=n;		devpriv->ai_act_dmapos+=n;// well, whole begin is skipped//		DPRINTK("0 bufs=%d *dma=0x%08x dmapos=%d\n",*bufs,*dma,devpriv->ai_act_dmapos);		return 0;	} else {  // we cann't skip all		(*dma)+=*bufs;		devpriv->ai_act_dmapos+=*bufs;		(*bufs)=0;//		DPRINTK("1 bufs=%d *dma=0x%08x dmapos=%d\n",*bufs,*dma,devpriv->ai_act_dmapos);		return 1; // no more samples in source	}	return -1;}/*==============================================================================*/static int move_block_from_dma_12bit_16b(comedi_device *dev, comedi_subdevice *s,	void *dma_void, int *sampls, int *bufs){	unsigned int cc,sp,chans,chns;	sampl_t sampl;	uint16_t **dma = (uint16_t **) dma_void;	cc=s->async->cur_chan;	sp=devpriv->ai_act_scanpos;	chans=devpriv->ai_n_chan;//	DPRINTK("bufs:%d sampls:%d dmapos=%d cc=%d sp=%d\n",*bufs,*sampls,devpriv->ai_act_dmapos,cc,sp);	while (*bufs&&*sampls) {		if (devpriv->ai_add_front)  // skip added front			if (skip_front_samples_16b(dev, s, dma, bufs, 2))				break;		chns=chans;//		DPRINTK("0 cc=%d sp=%d *bufs=%d *sampls=%d chns=%d/%d dmapos=%d\n",cc,sp,*bufs,*sampls,chns,chans,devpriv->ai_act_dmapos);		(*bufs)-=chns-cc;		(*sampls)-=chns-cc;		if (*sampls<0) { (*bufs)-=*sampls; chns+=*sampls; *sampls=0; }//		DPRINTK("1 cc=%d sp=%d *bufs=%d *sampls=%d chns=%d/%d dmapos=%d\n",cc,sp,*bufs,*sampls,chns,chans,devpriv->ai_act_dmapos);		if ((*bufs<0)||(*sampls<0)) {			s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;			pci9118_ai_cancel(dev,s);			comedi_event(dev,s,s->async->events);			return -1;		}		for (;cc<chns;cc++) {			sampl=**dma; (*dma)++;#ifdef PCI9118_PARANOIDCHECK			if ((sampl & 0x0f00)!=devpriv->chanlist[cc]) {		    		rt_printk("comedi: A/D  DMA - data dropout: received channel %04x, expected %04x!\n",(sampl & 0x0f00),devpriv->chanlist[cc]);	    			DPRINTK("comedi:  bufs=%d cc=%d sp=%d dmapos=%d chans=%d af=%d ab=%d sampls=%d (dma)=%04x dma=%04x!\n",*bufs,cc,sp,devpriv->ai_act_dmapos,chans,devpriv->ai_add_front,devpriv->ai_add_back,*sampls,*(*dma-1),(int)(*dma-1));				s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;				pci9118_ai_cancel(dev,s);				comedi_event(dev,s,s->async->events);				return -1;			}#endif			sampl=((sampl & 0xff)<<4)|((sampl & 0xf000)>>12); // get one sample			cfc_write_to_buffer( s, sampl);		}		sp+=cc;		if (cc>=chans) {			cc=0;			devpriv->ai_act_dmapos=0;			if (devpriv->ai_add_back)  // drop added one				if (*bufs) {					(*bufs)--;					(*dma)++;				}		} 		if(sp>=devpriv->ai_n_scanlen) { // is end of one scan?			sp=0;		        devpriv->ai_act_scan++;			if (*sampls)				if (devpriv->ai_flags & TRIG_WAKE_EOS) {					comedi_event(dev,s,s->async->events);					s->async->events=0;				}		}	}//	DPRINTK("9 cc=%d sp=%d *bufs=%d *sampls=%d chns=%d/%d dmapos=%d\n",cc,sp,*bufs,*sampls,chns,chans,devpriv->ai_act_dmapos);	devpriv->ai_act_scanpos=sp;	return 0;}/*==============================================================================*/static int move_block_from_dma_16bit_16b(comedi_device *dev, comedi_subdevice *s,	void *dma_void, int *sampls, int *bufs){	unsigned int cc,sp,chans,chns;	sampl_t sampl;	uint16_t **dma = (uint16_t **) dma_void;	cc=s->async->cur_chan;	sp=devpriv->ai_act_scanpos;	chans=devpriv->ai_n_chan;//	DPRINTK("bufs:%d sampls:%d dmapos=%d cc=%d sp=%d\n",*bufs,*sampls,devpriv->ai_act_dmapos,cc,sp);	while (*bufs&&*sampls) {		if (devpriv->ai_add_front)  // skip added front			if (skip_front_samples_16b(dev, s, dma, bufs, 2))				break;		chns=chans;//		DPRINTK("0 cc=%d sp=%d *bufs=%d *sampls=%d chns=%d/%d dmapos=%d\n",cc,sp,*bufs,*sampls,chns,chans,devpriv->ai_act_dmapos);		(*bufs)-=chns-cc;		(*sampls)-=chns-cc;		if (*sampls<0) { (*bufs)-=*sampls; chns+=*sampls; *sampls=0; }//		DPRINTK("1 cc=%d sp=%d *bufs=%d *sampls=%d chns=%d/%d dmapos=%d\n",cc,sp,*bufs,*sampls,chns,chans,devpriv->ai_act_dmapos);		if ((*bufs<0)||(*sampls<0)) {			s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;			pci9118_ai_cancel(dev,s);			comedi_event(dev,s,s->async->events);			return -1;		}		for (;cc<chns;cc++) {			sampl=**dma; (*dma)++;			sampl=(((sampl & 0xff)<<8)|((sampl & 0xff00)>>8))^0x8000; // get one sample			cfc_write_to_buffer( s, sampl );		}		sp+=cc;		if (cc>=chans) {			cc=0;			devpriv->ai_act_dmapos=0;			if (devpriv->ai_add_back)  // drop added one				if (*bufs) {					(*bufs)--;					(*dma)++;				}		} 		if(sp>=devpriv->ai_n_scanlen) { // is end of one scan?			sp=0;		        devpriv->ai_act_scan++;			if (*sampls)				if (devpriv->ai_flags & TRIG_WAKE_EOS) {					comedi_event(dev,s,s->async->events);					s->async->events=0;				}		}	}//	DPRINTK("9 cc=%d sp=%d *bufs=%d *sampls=%d chns=%d/%d dmapos=%d\n",cc,sp,*bufs,*sampls,chns,chans,devpriv->ai_act_dmapos);	devpriv->ai_act_scanpos=sp;	return 0;}/*==============================================================================  Skip a few samples at begin of every scan if is used software generated  sample&hold signal*/static int skip_front_samples_32b(comedi_device *dev, comedi_subdevice *s,	lsampl_t **dma, unsigned int *bufs, char x){	unsigned int n;	n=(devpriv->ai_add_front-devpriv->ai_act_dmapos)>>1;//	DPRINTK("n=%d bufs=%d *dma=0x%08x dmapos=%d %d\n",n,*bufs,*dma,devpriv->ai_act_dmapos,x);	if (*bufs>n) {		(*bufs)-=n;		(*dma)+=n;		devpriv->ai_act_dmapos+=n;// well, whole begin is skipped//		DPRINTK("0 bufs=%d *dma=0x%08x dmapos=%d\n",*bufs,*dma,devpriv->ai_act_dmapos);		return 0;	} else {  // we cann't skip all		(*dma)+=*bufs;		devpriv->ai_act_dmapos+=*bufs;		(*bufs)=0;//		DPRINTK("1 bufs=%d *dma=0x%08x dmapos=%d\n",*bufs,*dma,devpriv->ai_act_dmapos);		return 1; // no more samples in source	}	return -1;}/*==============================================================================*/static int move_block_from_dma_12bit_32b(comedi_device *dev, comedi_subdevice *s,	void *dma_void, int *sampls, int *bufs){	int cc,sp,chans,chns,xx,yy;	lsampl_t sampl;#ifdef PCI9118_PARANOIDCHECK	lsampl_t *chanlist=(lsampl_t *)devpriv->chanlist;#endif	uint32_t ** dma = ( uint32_t ** ) dma_void;	cc=s->async->cur_chan;	sp=devpriv->ai_act_scanpos;	chans=devpriv->ai_n_chan>>1;	xx=*bufs>>1;	yy=*sampls>>1;	while (xx&&yy) {		if (devpriv->ai_add_front)  // skip added front			if (skip_front_samples_32b(dev, s, dma, &xx, 2))				break;		chns=chans;		xx-=chns-cc;		yy-=chns-cc;		if (yy<0) { xx-=yy; chns+=yy; yy=0; }		for (;cc<chns;cc++) {			sampl=**dma; (*dma)++;#ifdef PCI9118_PARANOIDCHECK			if ((sampl & 0x000f000f)!=chanlist[cc]) {		    		rt_printk("comedi: A/D  DMA - data dropout: received channel %08x, expected %08x!\n",(sampl & 0x000f000f),chanlist[cc]);		    		DPRINTK("comedi:  bufs=%d cc=%d sp=%d dmapos=%d chns=%d chans=%d af=%d ab=%d sampls=%d (dma)=%08x dma=%08x!\n",*bufs,cc,sp,devpriv->ai_act_dmapos,chns,chans,devpriv->ai_add_front,devpriv->ai_add_back,*sampls,*(*dma-1),(int)(*dma-1));				s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;				pci9118_ai_cancel(dev,s);				comedi_event(dev,s,s->async->events);				return -1;			}#endif			sampl=((sampl & 0xfff0)<<12)|((sampl & 0xfff00000)>>20);			cfc_write_long_to_buffer( s, sampl );		}		sp+=cc<<1;		if (cc>=chans) {			cc=0;			devpriv->ai_act_dmapos=0;		}		if(sp>=devpriv->ai_n_scanlen) { // is end of one scan?			sp=0;		        devpriv->ai_act_scan++;			if (*sampls)				if (devpriv->ai_flags & TRIG_WAKE_EOS) {					comedi_event(dev,s,s->async->events);					s->async->events=0;				}		}	}	*bufs-=*bufs-(xx<<1);	*sampls-=*sampls-(yy<<1);	devpriv->ai_act_scanpos=sp;	return 0;}/*==============================================================================*/static int move_block_from_dma_16bit_32b(comedi_device *dev, comedi_subdevice *s,	void *dma_void, int *sampls, int *bufs){	int cc,sp,chans,chns,xx,yy;	lsampl_t sampl;	uint32_t **dma = ( uint32_t ** ) dma_void;	cc=s->async->cur_chan;	sp=devpriv->ai_act_scanpos;	chans=devpriv->ai_n_chan>>1;	xx=*bufs>>1;	yy=*sampls>>1;	while (xx&&yy) {		if (devpriv->ai_add_front)  // skip added front			if (skip_front_samples_32b(dev, s, dma, &xx, 2))				break;		chns=chans;		xx-=chns-cc;		yy-=chns-cc;		if (yy<0) { xx-=yy; chns+=yy; yy=0; }		for (;cc<chns;cc++) {			sampl=**dma; (*dma)++;			sampl=(((sampl & 0xffff)<<16)|((sampl & 0xffff0000)>>16))^0x80008000;			cfc_write_long_to_buffer( s, sampl );		}		sp+=cc<<1;		if (cc>=chans) {			cc=0;			devpriv->ai_act_dmapos=0;		}		if(sp>=devpriv->ai_n_scanlen) { // is end of one scan?			sp=0;		        devpriv->ai_act_scan++;			if (*sampls)				if (devpriv->ai_flags & TRIG_WAKE_EOS) {					comedi_event(dev,s,s->async->events);					s->async->events=0;				}		}	}	*bufs-=*bufs-(xx<<1);	*sampls-=*sampls-(yy<<1);	devpriv->ai_act_scanpos=sp;	return 0;}/* ==============================================================================*/static char pci9118_decode_error_status(comedi_device *dev,comedi_subdevice *s,unsigned char m){	if (m & 0x100) {		comedi_error(dev,"A/D FIFO Full status (Fatal Error!)");		devpriv->ai_maskerr&=~0x100L;

⌨️ 快捷键说明

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