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

📄 ni_atmio16d.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	outw(0x1025, dev->iobase+AM9513A_DATA_REG);	outw(0xFF0C, dev->iobase+AM9513A_COM_REG);	if(sample_count < 65536) {		/* use only Counter 4 */		outw(sample_count, dev->iobase+AM9513A_DATA_REG);		outw(0xFF48, dev->iobase+AM9513A_COM_REG);		outw(0xFFF4, dev->iobase+AM9513A_COM_REG);		outw(0xFF28, dev->iobase+AM9513A_COM_REG);		devpriv->com_reg_1_state &= ~COMREG1_1632CNT;		outw(devpriv->com_reg_1_state, dev->iobase+COM_REG_1);	} else {		/* Counter 4 and 5 are needed */		if( (tmp=sample_count&0xFFFF) ) {			outw(tmp-1, dev->iobase+AM9513A_DATA_REG);		} else {			outw(0xFFFF, dev->iobase+AM9513A_DATA_REG);		}		outw(0xFF48, dev->iobase+AM9513A_COM_REG);		outw(0, dev->iobase+AM9513A_DATA_REG);		outw(0xFF28, dev->iobase+AM9513A_COM_REG);		outw(0xFF05, dev->iobase+AM9513A_COM_REG);		outw(0x25, dev->iobase+AM9513A_DATA_REG);		outw(0xFF0D, dev->iobase+AM9513A_COM_REG);		tmp=sample_count&0xFFFF;		if( (tmp == 0) || (tmp == 1) ) {			outw( (sample_count>>16)&0xFFFF, dev->iobase+AM9513A_DATA_REG);		} else {			outw( ((sample_count>>16)&0xFFFF)+1, dev->iobase+AM9513A_DATA_REG);		}		outw(0xFF70, dev->iobase+AM9513A_COM_REG);		devpriv->com_reg_1_state |= COMREG1_1632CNT;		outw(devpriv->com_reg_1_state, dev->iobase+COM_REG_1);	}	/* Program the scan interval timer ONLY IF SCANNING IS ENABLED */	/* Figure out which clock to use then get an	 * appropriate timer value */	if(cmd->chanlist_len > 1) {		if(cmd->scan_begin_arg<65536000) {			base_clock = CLOCK_1_MHZ;			timer = cmd->scan_begin_arg/1000;		} else if(cmd->scan_begin_arg<655360000) {			base_clock = CLOCK_100_KHZ;			timer = cmd->scan_begin_arg/10000;		} else if(cmd->scan_begin_arg<0xffffffff /* 6553600000 */ ) {			base_clock = CLOCK_10_KHZ;			timer = cmd->scan_begin_arg/100000;		} else if(cmd->scan_begin_arg<0xffffffff /* 65536000000 */ ) {			base_clock = CLOCK_1_KHZ;			timer = cmd->scan_begin_arg/1000000;		}		outw(0xFF02, dev->iobase+AM9513A_COM_REG);		outw(base_clock, dev->iobase+AM9513A_DATA_REG);		outw(0xFF0A, dev->iobase+AM9513A_COM_REG);		outw(0x2, dev->iobase+AM9513A_DATA_REG);		outw(0xFF42, dev->iobase+AM9513A_COM_REG);		outw(0xFFF2, dev->iobase+AM9513A_COM_REG);		outw(timer, dev->iobase+AM9513A_DATA_REG);		outw(0xFF22, dev->iobase+AM9513A_COM_REG);	}		/* Clear the A/D FIFO and reset the MUX counter */	outw(0, dev->iobase+AD_CLEAR_REG);	outw(0, dev->iobase+MUX_CNTR_REG);	outw(0, dev->iobase+INT2CLR_REG);	/* enable this acquisition operation */	devpriv->com_reg_1_state |= COMREG1_DAQEN;	outw(devpriv->com_reg_1_state, dev->iobase+COM_REG_1);	/* enable interrupts for conversion completion */	devpriv->com_reg_1_state |= COMREG1_CONVINTEN;	devpriv->com_reg_2_state |= COMREG2_INTEN;	outw(devpriv->com_reg_1_state, dev->iobase+COM_REG_1);	outw(devpriv->com_reg_2_state, dev->iobase+COM_REG_2);	/* apply a trigger. this starts the counters! */	outw(0, dev->iobase+START_DAQ_REG);	return 0;}/* This will cancel a running acquisition operation */static int atmio16d_ai_cancel(comedi_device *dev, comedi_subdevice *s){	reset_atmio16d(dev);		return 0;}/* Mode 0 is used to get a single conversion on demand */static int atmio16d_ai_insn_read(comedi_device * dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int i, t;	int chan;	int gain;	int status;		#ifdef DEBUG1	printk("atmio16d_ai_insn_read\n");#endif	chan = CR_CHAN(insn->chanspec);	gain = CR_RANGE(insn->chanspec);	/* reset the Analog input circuitry */	//outw( 0, dev->iobase+AD_CLEAR_REG );	/* reset the Analog Input MUX Counter to 0 */	//outw( 0, dev->iobase+MUX_CNTR_REG );	/* set the Input MUX gain */	outw( chan|(gain<<6), dev->iobase+MUX_GAIN_REG);	for(i=0 ; i < insn->n ; i++) {		/* start the conversion */		outw(0, dev->iobase+START_CONVERT_REG);		/* wait for it to finish */		for(t = 0; t < ATMIO16D_TIMEOUT; t++) {			/* check conversion status */			status=inw(dev->iobase+STAT_REG);#ifdef DEBUG1			printk("status=%x\n",status);#endif			if( status&STAT_AD_CONVAVAIL ) {				/* read the data now */				data[i] = inw( dev->iobase+AD_FIFO_REG );				/* change to two's complement if need be */				if( devpriv->adc_coding == adc_2comp ) {					data[i] ^= 0x800;				}				break;			}			if( status&STAT_AD_OVERFLOW ){				printk("atmio16d: a/d FIFO overflow\n");				outw(0,dev->iobase+AD_CLEAR_REG);				return -ETIME;			}		}		/* end waiting, now check if it timed out */		if( t == ATMIO16D_TIMEOUT ){			rt_printk("atmio16d: timeout\n");			return -ETIME;		}	}		return i;}static int atmio16d_ao_insn_read(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int i;#ifdef DEBUG1	printk("atmio16d_ao_insn_read\n");#endif	for(i=0;i<insn->n;i++){		data[i]=devpriv->ao_readback[CR_CHAN(insn->chanspec)];	}	return i;}static int atmio16d_ao_insn_write(comedi_device * dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int i;	int chan;	int d;#ifdef DEBUG1	printk("atmio16d_ao_insn_write\n");#endif	chan=CR_CHAN(insn->chanspec);	for(i=0; i < insn->n; i++) {		d = data[i];		switch(chan){		case 0:			if (devpriv->dac0_coding == dac_2comp) {				d ^= 0x800;			}			outw(d, dev->iobase + DAC0_REG);			break;		case 1:			if (devpriv->dac1_coding == dac_2comp) {				d ^= 0x800;			}			outw(d, dev->iobase + DAC1_REG);			break;		default:			return -EINVAL;		}		devpriv->ao_readback[chan] = data[i];	}	return i;}static int atmio16d_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	if(insn->n!=2)return -EINVAL;	if(data[0]){		s->state &= ~data[0];		s->state |= (data[0]|data[1]);		outw(s->state, dev->iobase+MIO_16_DIG_OUT_REG );	}	data[1] = inw(dev->iobase+MIO_16_DIG_IN_REG);	return 2;}static int atmio16d_dio_insn_config(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int i;	int mask;	for(i=0;i<insn->n;i++){		mask=(CR_CHAN(insn->chanspec)<4)?0x0f:0xf0;		s->io_bits &= ~mask;		if(data[i])s->io_bits |= mask;	}	devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0|COMREG2_DOUTEN1);	if(s->io_bits&0x0f)		devpriv->com_reg_2_state |= COMREG2_DOUTEN0;	if(s->io_bits&0xf0)		devpriv->com_reg_2_state |= COMREG2_DOUTEN1;	outw(devpriv->com_reg_2_state, dev->iobase+COM_REG_2);	return i;}/*   options[0] - I/O port   options[1] - MIO irq                0 == no irq                N == irq N {3,4,5,6,7,9,10,11,12,14,15}   options[2] - DIO irq                0 == no irq                N == irq N {3,4,5,6,7,9}   options[3] - DMA1 channel                0 == no DMA                N == DMA N {5,6,7}   options[4] - DMA2 channel                0 == no DMA                N == DMA N {5,6,7}   options[5] - a/d mux   	0=differential, 1=single   options[6] - a/d range   	0=bipolar10, 1=bipolar5, 2=unipolar10   options[7] - dac0 range   	0=bipolar, 1=unipolar   options[8] - dac0 reference    0=internal, 1=external   options[9] - dac0 coding   	0=2's comp, 1=straight binary      options[10] - dac1 range   options[11] - dac1 reference   options[12] - dac1 coding */static int atmio16d_attach(comedi_device * dev, comedi_devconfig * it){	int irq;	int iobase;	int ret;		comedi_subdevice *s;	/* make sure the address range is free and allocate it */	iobase = it->options[0];	printk("comedi%d: atmio16d: 0x%04x ", dev->minor, iobase);	if (check_region(iobase, ATMIO16D_SIZE) < 0) {		printk("I/O port conflict\n");		return -EIO;	}	request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d");	dev->iobase = iobase;		/* board name */	dev->board_name = boardtype->name;	if((ret=alloc_subdevices(dev, 4))<0)		return ret;	if((ret=alloc_private(dev,sizeof(atmio16d_private)))<0)		return ret;	/* reset the atmio16d hardware */	reset_atmio16d(dev);		/* check if our interrupt is available and get it */	irq=it->options[1];	if(irq>0){		if((ret=comedi_request_irq(irq,atmio16d_interrupt,			0, "atmio16d", dev))<0)			return ret;		dev->irq=irq;		printk("( irq = %d )\n",irq);	} else if(irq == 0){		printk("( no irq )");	}	/* set device options */	devpriv->adc_mux = it->options[5];	devpriv->adc_range = it->options[6];		devpriv->dac0_range = it->options[7];	devpriv->dac0_reference = it->options[8];	devpriv->dac0_coding = it->options[9];	devpriv->dac1_range = it->options[10];	devpriv->dac1_reference = it->options[11];	devpriv->dac1_coding = it->options[12];		/* setup sub-devices */	s=dev->subdevices+0;	dev->read_subdev = s;	/* ai subdevice */	s->type=COMEDI_SUBD_AI;	s->subdev_flags=SDF_READABLE|SDF_GROUND;	s->n_chan=(devpriv->adc_mux? 16 : 8);	s->len_chanlist=16;	s->insn_read = atmio16d_ai_insn_read;	s->do_cmdtest=atmio16d_ai_cmdtest;	s->do_cmd=atmio16d_ai_cmd;	s->cancel=atmio16d_ai_cancel;	s->maxdata=0xfff;	/* 4095 decimal */	switch (devpriv->adc_range) {	case adc_bipolar10:		s->range_table = &range_atmio16d_ai_10_bipolar;		break;	case adc_bipolar5:		s->range_table = &range_atmio16d_ai_5_bipolar;		break;	case adc_unipolar10:		s->range_table = &range_atmio16d_ai_unipolar;		break;	}	/* ao subdevice */	s++;	s->type=COMEDI_SUBD_AO;	s->subdev_flags=SDF_WRITABLE;	s->n_chan=2;	s->insn_read=atmio16d_ao_insn_read;	s->insn_write=atmio16d_ao_insn_write;	s->maxdata=0xfff;	/* 4095 decimal */	s->range_table_list=devpriv->ao_range_type_list;	switch (devpriv->dac0_range) {	case dac_bipolar:		devpriv->ao_range_type_list[0] = &range_bipolar10;		break;	case dac_unipolar:		devpriv->ao_range_type_list[0] = &range_unipolar10;		break;	}	switch (devpriv->dac1_range) {	case dac_bipolar:		devpriv->ao_range_type_list[1] = &range_bipolar10;		break;	case dac_unipolar:		devpriv->ao_range_type_list[1] = &range_unipolar10;		break;	}	/* Digital I/O */	s++;	s->type=COMEDI_SUBD_DIO;	s->subdev_flags=SDF_WRITABLE|SDF_READABLE;	s->n_chan=8;	s->insn_bits = atmio16d_dio_insn_bits;	s->insn_config = atmio16d_dio_insn_config;	s->maxdata=1;	s->range_table=&range_digital;		/* 8255 subdevice */	s++;	if(boardtype->has_8255){		subdev_8255_init(dev,s,NULL,(unsigned long)dev->iobase);	}else{		s->type=COMEDI_SUBD_UNUSED;	}/* don't yet know how to deal with counter/timers */#if 0	s++;	/* do */	s->type=COMEDI_SUBD_TIMER;	s->n_chan=0;	s->maxdata=0#endif	printk("\n");	return 0;}static int atmio16d_detach(comedi_device * dev){	printk("comedi%d: atmio16d: remove\n", dev->minor);	if(dev->subdevices && boardtype->has_8255)		subdev_8255_cleanup(dev,dev->subdevices + 3);	if(dev->irq)		comedi_free_irq(dev->irq,dev);	reset_atmio16d(dev);		if(dev->iobase)		release_region(dev->iobase, ATMIO16D_SIZE);	return 0;}

⌨️ 快捷键说明

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