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

📄 pcl818.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
==============================================================================   ANALOG OUTPUT MODE0, 818 cards   only one sample per call is supported*/static int pcl818_ao_insn_read(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int n;	int chan = CR_CHAN(insn->chanspec);	for(n=0;n<insn->n;n++){		data[n] = devpriv->ao_readback[chan];	}	return n;}static int pcl818_ao_insn_write(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int n;	int chan = CR_CHAN(insn->chanspec);	for(n=0;n<insn->n;n++){		devpriv->ao_readback[chan] = data[n];		outb((data[n] & 0x000f) << 4, dev->iobase+			(chan)?PCL718_DA2_LO:PCL818_DA_LO);		outb((data[n] & 0x0ff0) >> 4, dev->iobase+			(chan)?PCL718_DA2_HI:PCL818_DA_HI);	}	return n;}/* ==============================================================================   DIGITAL INPUT MODE0, 818 cards      only one sample per call is supported*/static int pcl818_di_insn_bits(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	if(insn->n!=2)return -EINVAL;	data[1] = inb(dev->iobase + PCL818_DI_LO) |	        (inb(dev->iobase + PCL818_DI_HI) << 8);	return 2;}/* ==============================================================================   DIGITAL OUTPUT MODE0, 818 cards      only one sample per call is supported*/static int pcl818_do_insn_bits(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	if(insn->n!=2)return -EINVAL;	s->state &= ~data[0];	s->state |= (data[0]&data[1]);	outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);        outb((s->state >> 8), dev->iobase + PCL818_DO_HI);	data[1] = s->state;		return 2;}/*==============================================================================   analog input interrupt mode 1 & 3, 818 cards   one sample per interrupt version   */static void interrupt_pcl818_ai_mode13_int(int irq, void *d, struct pt_regs *regs) {        comedi_device *dev = d;	comedi_subdevice *s = dev->subdevices + 0;        int low;        int timeout=50; /* wait max 50us */	while (timeout--) {		if (inb(dev->iobase + PCL818_STATUS) & 0x10) goto conv_finish;		comedi_udelay(1);        }        outb(0,dev->iobase+PCL818_STATUS); /* clear INT request */        comedi_error(dev,"A/D mode1/3 IRQ without DRDY!");	pcl818_ai_cancel(dev,s);	s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;	comedi_event(dev, s, s->async->events);	return;conv_finish:        low=inb(dev->iobase + PCL818_AD_LO);	comedi_buf_put( s->async,		((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4)) ); // get one sample        outb(0,dev->iobase+PCL818_CLRINT); /* clear INT request */        if ((low & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!		rt_printk("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",(low & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);		pcl818_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev, s, s->async->events);		return;        }        if (s->async->cur_chan == 0) {		// rt_printk("E");		devpriv->int13_act_scan--;        }	if (!devpriv->neverending_ai){		if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */			pcl818_ai_cancel(dev,s);			s->async->events |= COMEDI_CB_EOA;			return;		}	}	comedi_event(dev, s, s->async->events);}/*==============================================================================   analog input dma mode 1 & 3, 818 cards*/static void interrupt_pcl818_ai_mode13_dma(int irq, void *d, struct pt_regs *regs){	comedi_device *dev = d;	comedi_subdevice *s = dev->subdevices + 0;	int i,len,bufptr;	unsigned long flags;        sampl_t *ptr;        disable_dma(devpriv->dma);        devpriv->next_dma_buf=1-devpriv->next_dma_buf;        if ((devpriv->dma_runs_to_end)>-1) {  // switch dma bufs		set_dma_mode(devpriv->dma, DMA_MODE_READ);		flags=claim_dma_lock();		set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]);		if (devpriv->dma_runs_to_end) { set_dma_count(devpriv->dma, devpriv->hwdmasize[devpriv->next_dma_buf]); }					else { set_dma_count(devpriv->dma, devpriv->last_dma_run); }		release_dma_lock(flags);		enable_dma(devpriv->dma);        }        devpriv->dma_runs_to_end--;        outb(0,dev->iobase+PCL818_CLRINT); /* clear INT request */        ptr=(sampl_t *)devpriv->dmabuf[1-devpriv->next_dma_buf];        len=devpriv->hwdmasize[0] >> 1;        bufptr=0;        for (i=0;i<len;i++) {		if ((ptr[bufptr] & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!		        rt_printk("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",(ptr[bufptr] & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);		        pcl818_ai_cancel(dev,s);			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;			comedi_event(dev, s, s->async->events);			return;		}		comedi_buf_put( s->async, ptr[bufptr++] >> 4 ); // get one sample		devpriv->act_chanlist_pos++;		if (!devpriv->neverending_ai)	    		if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */				pcl818_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA;				comedi_event(dev, s, s->async->events);				// printk("done int ai13 dma\n");				return;			}	}	if (len>0) comedi_event(dev, s, s->async->events);}/*==============================================================================   analog input dma mode 1 & 3 over RTC, 818 cards*/static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs *regs){        comedi_device *dev = d;	comedi_subdevice *s = dev->subdevices + 0;        unsigned long tmp;        unsigned int top1,top2,i,bufptr;        long ofs_dats;        sampl_t *dmabuf=(sampl_t *)devpriv->dmabuf[0];        //outb(2,0x378);        switch(devpriv->int818_mode) {	case INT_TYPE_AI1_DMA_RTC:	case INT_TYPE_AI3_DMA_RTC:		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);		mod_timer(&devpriv->rtc_irq_timer, jiffies + HZ/devpriv->rtc_freq + 2*HZ/100);		for (i=0; i<10; i++) {			top1=get_dma_residue(devpriv->dma);			top2=get_dma_residue(devpriv->dma);			if (top1==top2) break;		}		if (top1!=top2) return;		top1=devpriv->hwdmasize[0]-top1; // where is now DMA in buffer		top1>>=1;		ofs_dats=top1-devpriv->last_top_dma;  // new samples from last call		if (ofs_dats<0) ofs_dats=(devpriv->dmasamplsize)+ofs_dats;		if (!ofs_dats) return; // exit=no new samples from last call		// obsluz data		i=devpriv->last_top_dma-1;		i&=(devpriv->dmasamplsize-1);		if (dmabuf[i]!=MAGIC_DMA_WORD) { // DMA overflow!			comedi_error(dev,"A/D mode1/3 DMA buffer overflow!");			//rt_printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize);			pcl818_ai_cancel(dev,s);			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;			comedi_event(dev, s, s->async->events);			return;		}		//rt_printk("r %ld ",ofs_dats);		bufptr=devpriv->last_top_dma;		for (i=0; i<ofs_dats; i++) {			if ((dmabuf[bufptr] & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!				rt_printk("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",(dmabuf[bufptr] & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);				pcl818_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;				comedi_event(dev, s, s->async->events);				return;			}			comedi_buf_put( s->async, dmabuf[bufptr++] >> 4); // get one sample			bufptr&=(devpriv->dmasamplsize-1);			if(s->async->cur_chan == 0){				devpriv->int13_act_scan--;			}			if (!devpriv->neverending_ai)				if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */					pcl818_ai_cancel(dev,s);					s->async->events |= COMEDI_CB_EOA;					comedi_event(dev, s, s->async->events);					//printk("done int ai13 dma\n");					return;				}		}		devpriv->last_top_dma=bufptr;		bufptr--;		bufptr&=(devpriv->dmasamplsize-1);		dmabuf[bufptr]=MAGIC_DMA_WORD;		comedi_event(dev, s, s->async->events);		//outb(0,0x378);		return;	}	//outb(0,0x378);}/*==============================================================================   analog input interrupt mode 1 & 3, 818HD/HG cards*/static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *regs){        comedi_device *dev = d;        comedi_subdevice *s = dev->subdevices + 0;        int i,len,lo;        outb(0, dev->iobase + PCL818_FI_INTCLR);  // clear fifo int request        lo=inb(dev->iobase + PCL818_FI_STATUS);        if (lo&4) {		comedi_error(dev,"A/D mode1/3 FIFO overflow!");		pcl818_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev, s, s->async->events);		return;        }        if (lo&1) {		comedi_error(dev,"A/D mode1/3 FIFO interrupt without data!");		pcl818_ai_cancel(dev,s);		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;		comedi_event(dev, s, s->async->events);		return;	}        if (lo&2) { len=512; }	    else { len=0; }        for (i=0;i<len;i++) {		lo=inb(dev->iobase + PCL818_FI_DATALO);		if ((lo & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!			rt_printk("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",(lo & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);			pcl818_ai_cancel(dev,s);			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;			comedi_event(dev, s, s->async->events);			return;		}		comedi_buf_put( s->async, (lo >> 4)|(inb(dev->iobase + PCL818_FI_DATAHI) << 4) ); // get one sample		if(s->async->cur_chan == 0){			devpriv->int13_act_scan--;		}		if (!devpriv->neverending_ai)			if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */				pcl818_ai_cancel(dev,s);				s->async->events |= COMEDI_CB_EOA;				comedi_event(dev, s, s->async->events);				return;			}	}	if (len>0) comedi_event(dev, s, s->async->events);}/*==============================================================================    INT procedure*/static void interrupt_pcl818(int irq, void *d, struct pt_regs *regs){        comedi_device *dev = d;	if(!dev->attached)	{		comedi_error(dev, "premature interrupt");		return;	}        //rt_printk("I\n");        switch (devpriv->int818_mode) {	case INT_TYPE_AI1_DMA:	case INT_TYPE_AI3_DMA:		interrupt_pcl818_ai_mode13_dma(irq, d, regs);		return;	case INT_TYPE_AI1_INT:	case INT_TYPE_AI3_INT:		interrupt_pcl818_ai_mode13_int(irq, d, regs);		return;	case INT_TYPE_AI1_FIFO:	case INT_TYPE_AI3_FIFO:		interrupt_pcl818_ai_mode13_fifo(irq, d, regs);		return;#ifdef PCL818_MODE13_AO	case INT_TYPE_AO1_INT:	case INT_TYPE_AO3_INT:		interrupt_pcl818_ao_mode13_int(irq, d, regs);		return;#endif	}	outb(0,dev->iobase+PCL818_CLRINT); /* clear INT request */	if ((!dev->irq)|(!devpriv->irq_free)|(!devpriv->irq_blocked)|(!devpriv->int818_mode)) {		if (devpriv->irq_was_now_closed) {			devpriv->irq_was_now_closed=0;			// comedi_error(dev,"last IRQ..");			return;		}		comedi_error(dev,"bad IRQ!");		return;	}        comedi_error(dev,"IRQ from unknow source!");}/*==============================================================================   ANALOG INPUT MODE 1 or 3 DMA , 818 cards*/#ifdef unusedstatic void pcl818_ai_mode13dma_int(int mode, comedi_device * dev, comedi_subdevice * s, comedi_trig * it) {        unsigned int flags;        unsigned int bytes;        bytes=devpriv->hwdmasize[0];        if (!devpriv->neverending_ai) {		bytes=it->n_chan*it->n*sizeof(sampl_t); // how many 		devpriv->dma_runs_to_end=bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fiil		devpriv->last_dma_run=bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved		devpriv->dma_runs_to_end--;		if (devpriv->dma_runs_to_end>=0) bytes=devpriv->hwdmasize[0];		//rt_printk("%d %d %d\n",devpriv->dma_runs_to_end,devpriv->last_dma_run,bytes);	}         devpriv->next_dma_buf=0;	set_dma_mode(devpriv->dma, DMA_MODE_READ);        flags=claim_dma_lock();        clear_dma_ff(devpriv->dma);        set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);        set_dma_count(devpriv->dma, bytes);        release_dma_lock(flags);        enable_dma(devpriv->dma);

⌨️ 快捷键说明

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