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

📄 pcl818.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        outb(0, dev->iobase + PCL818_DA_LO); // DAC=0V        outb(0, dev->iobase + PCL818_DA_HI);        comedi_udelay(1);        outb(0, dev->iobase + PCL818_DO_HI); // DO=$0000        outb(0, dev->iobase + PCL818_DO_LO);        comedi_udelay(1);        outb(0, dev->iobase + PCL818_CONTROL);        outb(0, dev->iobase + PCL818_CNTENABLE);        outb(0, dev->iobase + PCL818_MUX);        outb(0, dev->iobase + PCL818_CLRINT);        outb(0xb0, dev->iobase + PCL818_CTRCTL);/* Stop pacer */        outb(0x70, dev->iobase + PCL818_CTRCTL);        outb(0x30, dev->iobase + PCL818_CTRCTL);	if(this_board->is_818){    	        outb(0, dev->iobase + PCL818_RANGE);	}else{		outb(0, dev->iobase + PCL718_DA2_LO);		outb(0, dev->iobase + PCL718_DA2_HI);	}}/* ==============================================================================  Enable(1)/disable(0) periodic interrupts from RTC*/static int set_rtc_irq_bit(unsigned char bit){        unsigned char val;        unsigned long flags;         if (bit==1) {		RTC_timer_lock++;		if (RTC_timer_lock>1) return 0;	} else {		RTC_timer_lock--;		if (RTC_timer_lock<0) RTC_timer_lock=0;		if (RTC_timer_lock>0) return 0;	}          save_flags(flags);        cli();        val = CMOS_READ(RTC_CONTROL);        if (bit) { val |= RTC_PIE; }    	    else { val &=  ~RTC_PIE; }        CMOS_WRITE(val, RTC_CONTROL);        CMOS_READ(RTC_INTR_FLAGS);        restore_flags(flags);        return 0;}/*==============================================================================  Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)*/#ifdef unusedstatic void rtc_dropped_irq(unsigned long data) {        comedi_device *dev = (void *)data;        unsigned long flags,tmp;	switch(devpriv->int818_mode) {    	case INT_TYPE_AI1_DMA_RTC:	case INT_TYPE_AI3_DMA_RTC:	        mod_timer(&devpriv->rtc_irq_timer, jiffies + HZ/devpriv->rtc_freq + 2*HZ/100);		save_flags(flags);		cli();		tmp=(CMOS_READ(RTC_INTR_FLAGS) & 0xF0);	/* restart */		restore_flags(flags);		break;        };     }/*==============================================================================  Set frequency of interrupts from RTC*/static int rtc_setfreq_irq(int freq) {        int tmp = 0;        int rtc_freq;        unsigned char val;        unsigned long flags;        if (freq<2) freq=2;        if (freq>8192) freq=8192;        while (freq>(1<<tmp))		tmp++;        rtc_freq = 1<<tmp;        save_flags(flags);        cli();	val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;        val |= (16 - tmp);        CMOS_WRITE(val, RTC_FREQ_SELECT);        restore_flags(flags);        return rtc_freq;}#endif/* ==============================================================================  Free any resources that we have claimed  */static void free_resources(comedi_device * dev){        //rt_printk("free_resource()\n");	if(dev->private)  {		pcl818_ai_cancel(dev, devpriv->sub_ai);		pcl818_reset(dev);		if (devpriv->dma) free_dma(devpriv->dma);		if (devpriv->dmabuf[0]) free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);		if (devpriv->dmabuf[1]) free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);		if (devpriv->rtc_irq) comedi_free_irq(devpriv->rtc_irq, dev);		if ((devpriv->dma_rtc)&&(RTC_lock==1)) {			if (devpriv->rtc_iobase)				release_region(devpriv->rtc_iobase, devpriv->rtc_iosize);		}		if (devpriv->dma_rtc)			RTC_lock--;	}	if (dev->irq) free_irq(dev->irq, dev);	if (dev->iobase) release_region(dev->iobase, devpriv->io_range);	//rt_printk("free_resource() end\n");}/* ==============================================================================   Initialization */static int pcl818_attach(comedi_device * dev, comedi_devconfig * it){	int ret;	int iobase;	int irq,dma;	unsigned long pages;	comedi_subdevice *s;	if((ret=alloc_private(dev,sizeof(pcl818_private)))<0)		return ret; /* Can't alloc mem */	/* claim our I/O space */	iobase = it->options[0];	printk("comedi%d: pcl818:  board=%s, ioport=0x%03x",		dev->minor, this_board->name, iobase);	devpriv->io_range=this_board->io_range;	if ((this_board->fifo)&&(it->options[2]==-1)) { // we've board with FIFO and we want to use FIFO		devpriv->io_range=PCLx1xFIFO_RANGE;		devpriv->usefifo = 1;	}	if (check_region(iobase, this_board->io_range) < 0) {		rt_printk("I/O port conflict\n");		return -EIO;	}	request_region(iobase, devpriv->io_range, "pcl818");	dev->iobase=iobase;	if (pcl818_check(iobase)) {		rt_printk(", I can't detect board. FAIL!\n");		return -EIO;	}        /* set up some name stuff */	dev->board_name = this_board->name;        /* grab our IRQ */        irq=0;        if (this_board->IRQbits!=0) { /* board support IRQ */		irq=it->options[1];		if (irq>0)  {/* we want to use IRQ */		        if (((1<<irq)&this_board->IRQbits)==0) {				rt_printk(", IRQ %d is out of allowed range, DISABLING IT",irq);				irq=0; /* Bad IRQ */			} else { 				if (comedi_request_irq(irq, interrupt_pcl818, 0, "pcl818", dev)) {					rt_printk(", unable to allocate IRQ %d, DISABLING IT", irq);					irq=0; /* Can't use IRQ */				} else {					rt_printk(", irq=%d", irq);				}    			}  		}	}        dev->irq = irq;        if (irq) { devpriv->irq_free=1; } /* 1=we have allocated irq */	    else { devpriv->irq_free=0; }         devpriv->irq_blocked=0; /* number of subdevice which use IRQ */        devpriv->int818_mode=0; /* mode of irq */        /* grab RTC for DMA operations */        devpriv->dma_rtc=0;        if (it->options[2]>0) { // we want to use DMA		if (RTC_lock==0) {			if (check_region(RTC_PORT(0), RTC_IO_EXTENT) < 0) goto no_rtc;			request_region(RTC_PORT(0), RTC_IO_EXTENT, "pcl818 (RTC)");		} 		devpriv->rtc_iobase=RTC_PORT(0);		devpriv->rtc_iosize=RTC_IO_EXTENT;		RTC_lock++;		if (!comedi_request_irq(RTC_IRQ, interrupt_pcl818_ai_mode13_dma_rtc, 0, "pcl818 DMA (RTC)", dev)) {			devpriv->dma_rtc=1;			devpriv->rtc_irq=RTC_IRQ;			rt_printk(", dma_irq=%d", devpriv->rtc_irq);		} else {			RTC_lock--;			if (RTC_lock==0) {    				if (devpriv->rtc_iobase) release_region(devpriv->rtc_iobase, devpriv->rtc_iosize);			}			devpriv->rtc_iobase=0;			devpriv->rtc_iosize=0;		}	} no_rtc:        /* grab our DMA */        dma=0;        devpriv->dma=dma;        if ((devpriv->irq_free==0)&&(devpriv->dma_rtc==0)) goto no_dma; /* if we haven't IRQ, we can't use DMA */        if (this_board->DMAbits!=0) { /* board support DMA */		dma=it->options[2];		if (dma<1) goto no_dma; /* DMA disabled */		if (((1<<dma)&this_board->DMAbits)==0) {		        rt_printk(", DMA is out of allowed range, FAIL!\n");			return -EINVAL; /* Bad DMA */		} 		ret=request_dma(dma, "pcl818");		if (ret) {			rt_printk(", unable to allocate DMA %d, FAIL!\n",dma);			return -EBUSY; /* DMA isn't free */		} 		devpriv->dma=dma;		rt_printk(", dma=%d", dma);		pages=2; /* we need 16KB */		devpriv->dmabuf[0]=__get_dma_pages(GFP_KERNEL, pages);		if (!devpriv->dmabuf[0]) {			rt_printk(", unable to allocate DMA buffer, FAIL!\n");			/* maybe experiment with try_to_free_pages() will help .... */			return -EBUSY; /* no buffer :-( */		}		devpriv->dmapages[0]=pages;		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);		devpriv->hwdmasize[0]=(1<<pages)*PAGE_SIZE;		//rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);		if (devpriv->dma_rtc==0) { // we must do duble buff :-(			devpriv->dmabuf[1]=__get_dma_pages(GFP_KERNEL, pages);			if (!devpriv->dmabuf[1]) {				rt_printk(", unable to allocate DMA buffer, FAIL!\n");				return -EBUSY;			}			devpriv->dmapages[1]=pages;			devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);			devpriv->hwdmasize[1]=(1<<pages)*PAGE_SIZE;		}	}no_dma:        if((ret=alloc_subdevices(dev, 4))<0) return ret;	s = dev->subdevices + 0;	if(!this_board->n_aichan_se){		s->type = COMEDI_SUBD_UNUSED;	}else{		dev->read_subdev = s;		s->type = COMEDI_SUBD_AI;		devpriv->sub_ai=s;		s->subdev_flags = SDF_READABLE;		if (check_single_ended(dev->iobase)) {			s->n_chan = this_board->n_aichan_se;			s->subdev_flags|=SDF_COMMON|SDF_GROUND;			printk(", %dchans S.E. DAC",s->n_chan);		} else {			s->n_chan = this_board->n_aichan_diff;			s->subdev_flags|=SDF_DIFF;			printk(", %dchans DIFF DAC",s->n_chan);		}		s->maxdata = this_board->ai_maxdata;		s->len_chanlist = this_board->ai_chanlist;		s->range_table = this_board->ai_range_type;		s->cancel=pcl818_ai_cancel;		s->insn_read = pcl818_ai_insn_read;		//if ((irq)||(devpriv->dma_rtc)) {			//s->trig[1] = pcl818_ai_mode1;			//s->trig[3] = pcl818_ai_mode3;		//}		if(this_board->is_818){			if ((it->options[4]==1)||(it->options[4]==10))				s->range_table=&range_pcl818l_h_ai; // secondary range list jumper selectable		}else{			switch (it->options[4]) {			case 0: s->range_table=&range_bipolar10; break;			case 1: s->range_table=&range_bipolar5; break;			case 2: s->range_table=&range_bipolar2_5; break;			case 3: s->range_table=&range718_bipolar1; break;			case 4: s->range_table=&range718_bipolar0_5; break;			case 6: s->range_table=&range_unipolar10; break;			case 7: s->range_table=&range_unipolar5; break;			case 8: s->range_table=&range718_unipolar2; break;			case 9: s->range_table=&range718_unipolar1; break;			default: s->range_table=&range_unknown; break;			}		}	}	s = dev->subdevices + 1;	if(!this_board->n_aochan){		s->type = COMEDI_SUBD_UNUSED;	}else{		dev->write_subdev = s;		s->type = COMEDI_SUBD_AO;		s->subdev_flags = SDF_WRITABLE|SDF_GROUND;		s->n_chan = this_board->n_aochan;		s->maxdata = this_board->ao_maxdata;		s->len_chanlist = this_board->ao_chanlist;		s->range_table = this_board->ao_range_type;		s->insn_read = pcl818_ao_insn_read;		s->insn_write = pcl818_ao_insn_write;#ifdef unused#ifdef PCL818_MODE13_AO		if (irq) {		        s->trig[1] = pcl818_ao_mode1;			s->trig[3] = pcl818_ao_mode3;		} #endif#endif		if(this_board->is_818){			if ((it->options[4]==1)||(it->options[4]==10)) 				s->range_table=&range_unipolar10; 			if (it->options[4]==2) 				s->range_table=&range_unknown; 		}else{			if ((it->options[5]==1)||(it->options[5]==10)) 				s->range_table=&range_unipolar10; 			if (it->options[5]==2) 				s->range_table=&range_unknown; 		}		}	s = dev->subdevices + 2;	if(!this_board->n_dichan){		s->type = COMEDI_SUBD_UNUSED;	}else{		s->type = COMEDI_SUBD_DI;		s->subdev_flags = SDF_READABLE;		s->n_chan = this_board->n_dichan;		s->maxdata = 1;		s->len_chanlist = this_board->n_dichan;		s->range_table = &range_digital;		s->insn_bits = pcl818_di_insn_bits;	}	s = dev->subdevices + 3;	if(!this_board->n_dochan){		s->type = COMEDI_SUBD_UNUSED;	}else{		s->type = COMEDI_SUBD_DO;		s->subdev_flags = SDF_WRITABLE;		s->n_chan = this_board->n_dochan;		s->maxdata = 1;		s->len_chanlist = this_board->n_dochan;		s->range_table = &range_digital;		s->insn_bits = pcl818_do_insn_bits;	}	/* select 1/10MHz oscilator */        if ((it->options[3]==0)||(it->options[3]==10)) { 		devpriv->i8253_osc_base= 100; 	} else { 		devpriv->i8253_osc_base=1000; 	}	         /* max sampling speed */        devpriv->ns_min=this_board->ns_min;	  	if(!this_board->is_818){		if ((it->options[6]==1)||(it->options[6]==100)) 			devpriv->ns_min=10000;  /* extended PCL718 to 100kHz DAC */	}	pcl818_reset(dev); 	rt_printk("\n");	return 0;}/*==============================================================================  Removes device */static int pcl818_detach(comedi_device * dev) {        //  rt_printk("comedi%d: pcl818: remove\n", dev->minor);        free_resources(dev);        return 0;}

⌨️ 快捷键说明

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