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

📄 cb_pcidas.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if( retval < 0 )		return retval;	data[ 0 ] = nvram_data;	return 1;}static int caldac_write_insn( comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data ){	const unsigned int channel = CR_CHAN( insn->chanspec );	return caldac_8800_write( dev, channel, data[0] );}static int caldac_read_insn( comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data ){	data[ 0 ] = devpriv->caldac_value[ CR_CHAN( insn->chanspec ) ];	return 1;}/* 1602/16 pregain offset */static int dac08_write( comedi_device *dev, lsampl_t value ){	if( devpriv->dac08_value == value ) return 1;	devpriv->dac08_value = value;	outw( SELECT_DAC08_BIT | ( value & 0xff ), devpriv->control_status + CALIBRATION_REG );	return 1;}static int dac08_write_insn( comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data ){	return dac08_write( dev, data[ 0 ] );}static int dac08_read_insn( comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data ){	data[ 0 ] = devpriv->dac08_value;	return 1;}static int cb_pcidas_trimpot_write( comedi_device *dev,	unsigned int channel, lsampl_t value ){	if( devpriv->trimpot_value[ channel ] == value ) return 1;	devpriv->trimpot_value[ channel ] = value;	switch( thisboard->trimpot )	{		case AD7376:			trimpot_7376_write( dev, value );			break;		case AD8402:			trimpot_8402_write( dev, channel, value );			break;		default:			comedi_error( dev, "driver bug?" );			return -1;			break;	}	return 1;}static int trimpot_write_insn( comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data ){	unsigned int channel = CR_CHAN( insn->chanspec );	return cb_pcidas_trimpot_write( dev, channel, data[ 0 ] );}static int trimpot_read_insn( comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data ){	unsigned int channel = CR_CHAN( insn->chanspec );	data[ 0 ] = devpriv->trimpot_value[ channel ];	return 1;}static int cb_pcidas_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,	comedi_cmd *cmd){	int err=0;	int tmp;	int i, gain, start_chan;	/* cmdtest tests a particular command to see if it is valid.	 * Using the cmdtest ioctl, a user can create a valid cmd	 * and then have it executes by the cmd ioctl.	 *	 * cmdtest returns 1,2,3,4 or 0, depending on which tests	 * the command passes. */	/* step 1: make sure trigger sources are trivially valid */	tmp = cmd->start_src;	cmd->start_src &= TRIG_NOW | TRIG_EXT;	if(!cmd->start_src || tmp != cmd->start_src)		err++;	tmp = cmd->scan_begin_src;	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;	if(!cmd->scan_begin_src || tmp != cmd->scan_begin_src)		err++;	tmp = cmd->convert_src;	cmd->convert_src &= TRIG_TIMER | TRIG_NOW | 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;	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_EXT)		err++;	if(cmd->scan_begin_src != TRIG_FOLLOW &&		cmd->scan_begin_src != TRIG_TIMER &&		cmd->scan_begin_src != TRIG_EXT)		err++;	if(cmd->convert_src != TRIG_TIMER &&		cmd->convert_src != TRIG_EXT &&		cmd->convert_src != TRIG_NOW)		err++;	if(cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)		err++;	// make sure trigger sources are compatible with each other	if(cmd->scan_begin_src == TRIG_FOLLOW &&		cmd->convert_src == TRIG_NOW)		err++;	if(cmd->scan_begin_src != TRIG_FOLLOW &&		cmd->convert_src != TRIG_NOW)		err++;	if(cmd->start_src == TRIG_EXT &&		(cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))		err++;	if(err) return 2;	/* step 3: make sure arguments are trivially compatible */	if(cmd->start_arg!=0)	{		cmd->start_arg=0;		err++;	}	if (cmd->scan_begin_src == TRIG_TIMER)	{		if (cmd->scan_begin_arg < thisboard->ai_speed * cmd->chanlist_len)		{			cmd->scan_begin_arg = thisboard->ai_speed * cmd->chanlist_len;			err++;		}	}	if (cmd->convert_src == TRIG_TIMER)	{		if (cmd->convert_arg < thisboard->ai_speed)		{			cmd->convert_arg = thisboard->ai_speed;			err++;		}	}	if(cmd->scan_end_arg != cmd->chanlist_len)	{		cmd->scan_end_arg = cmd->chanlist_len;		err++;	}	if(cmd->stop_src == TRIG_NONE)	{		/* TRIG_NONE */		if (cmd->stop_arg != 0)		{			cmd->stop_arg=0;			err++;		}	}	if(err)return 3;	/* step 4: fix up any arguments */	if(cmd->scan_begin_src == TRIG_TIMER)	{		tmp = cmd->scan_begin_arg;		i8253_cascade_ns_to_timer_2div(TIMER_BASE,			&(devpriv->divisor1), &(devpriv->divisor2),			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);		if(tmp != cmd->scan_begin_arg)			err++;	}	if(cmd->convert_src == TRIG_TIMER)	{		tmp=cmd->convert_arg;		i8253_cascade_ns_to_timer_2div(TIMER_BASE,			&(devpriv->divisor1), &(devpriv->divisor2),			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);		if(tmp != cmd->convert_arg)			err++;	}	if(err) return 4;	// check channel/gain list against card's limitations	if(cmd->chanlist)	{		gain = CR_RANGE(cmd->chanlist[0]);		start_chan = CR_CHAN(cmd->chanlist[0]);		for(i = 1; i < cmd->chanlist_len; i++)		{			if(CR_CHAN(cmd->chanlist[i]) != (start_chan + i) % s->n_chan)			{				comedi_error(dev, "entries in chanlist must be consecutive channels, counting upwards\n");				err++;			}			if(CR_RANGE(cmd->chanlist[i]) != gain)			{				comedi_error(dev, "entries in chanlist must all have the same gain\n");				err++;			}		}	}	if(err) return 5;	return 0;}static int cb_pcidas_ai_cmd(comedi_device *dev,comedi_subdevice *s){	comedi_async *async = s->async;	comedi_cmd *cmd = &async->cmd;	unsigned int bits;	unsigned long flags;	// make sure CAL_EN_BIT is disabled	outw(0, devpriv->control_status + CALIBRATION_REG);	// initialize before settings pacer source and count values	outw(0, devpriv->control_status + TRIG_CONTSTAT);	// clear fifo	outw(0, devpriv->adc_fifo + ADCFIFOCLR);	// set mux limits, gain and pacer source	bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |		END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |		GAIN_BITS(CR_RANGE(cmd->chanlist[0]));	// set unipolar/bipolar	if(CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)		bits |= UNIP;	// set singleended/differential	if(CR_AREF(cmd->chanlist[0]) != AREF_DIFF)		bits |= SE;	// set pacer source	if(cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)		bits |= PACER_EXT_RISE;	else		bits |= PACER_INT;	outw(bits, devpriv->control_status + ADCMUX_CONT);#ifdef CB_PCIDAS_DEBUG	rt_printk("comedi: sent 0x%x to adcmux control\n", bits);#endif	// load counters	if(cmd->convert_src == TRIG_TIMER)		cb_pcidas_load_counters(dev, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK);	else if(cmd->scan_begin_src == TRIG_TIMER)		cb_pcidas_load_counters(dev, &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);	// set number of conversions	if(cmd->stop_src == TRIG_COUNT)	{		devpriv->count = cmd->chanlist_len * cmd->stop_arg;	}	// enable interrupts	comedi_spin_lock_irqsave( &dev->spinlock, flags );	devpriv->adc_fifo_bits |= INTE;	devpriv->adc_fifo_bits &= ~INT_MASK;	if(cmd->flags & TRIG_WAKE_EOS)	{		if(cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)			devpriv->adc_fifo_bits |= INT_EOS;	// interrupt end of burst		else			devpriv->adc_fifo_bits |= INT_FNE;	// interrupt fifo not empty	}else	{		devpriv->adc_fifo_bits |= INT_FHF;	//interrupt fifo half full	}#ifdef CB_PCIDAS_DEBUG	rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);#endif	// enable (and clear) interrupts	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL, devpriv->control_status + INT_ADCFIFO);	comedi_spin_unlock_irqrestore( &dev->spinlock, flags );	// set start trigger and burst mode	bits = 0;	if(cmd->start_src == TRIG_NOW)		bits |= SW_TRIGGER;	else if(cmd->start_src == TRIG_EXT)		bits |= EXT_TRIGGER | TGEN | XTRCL;	else	{		comedi_error(dev, "bug!");		return -1;	}	if(cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)		bits |= BURSTE;	outw(bits, devpriv->control_status + TRIG_CONTSTAT);#ifdef CB_PCIDAS_DEBUG	rt_printk("comedi: sent 0x%x to trig control\n", bits);#endif	return 0;}static int cb_pcidas_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,	comedi_cmd *cmd){	int err=0;	int tmp;	/* cmdtest tests a particular command to see if it is valid.	 * Using the cmdtest ioctl, a user can create a valid cmd	 * and then have it executes by the cmd ioctl.	 *	 * cmdtest returns 1,2,3,4 or 0, depending on which tests	 * the command passes. */	/* step 1: make sure trigger sources are trivially valid */	tmp = cmd->start_src;	cmd->start_src &= TRIG_INT;	if(!cmd->start_src || tmp != cmd->start_src)		err++;	tmp = cmd->scan_begin_src;	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;	if(!cmd->scan_begin_src || tmp != cmd->scan_begin_src)		err++;	tmp = cmd->convert_src;	cmd->convert_src &= TRIG_NOW;	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;	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->scan_begin_src != TRIG_TIMER &&		cmd->scan_begin_src != TRIG_EXT)		err++;	if(cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)		err++;	if(err) return 2;	/* step 3: make sure arguments are trivially compatible */	if(cmd->start_arg!=0)	{		cmd->start_arg=0;		err++;	}	if (cmd->scan_begin_src == TRIG_TIMER)	{		if (cmd->scan_begin_arg < thisboard->ao_scan_speed)		{			cmd->scan_begin_arg = thisboard->ao_scan_speed;			err++;		}	}	if(cmd->scan_end_arg != cmd->chanlist_len)	{		cmd->scan_end_arg = cmd->chanlist_len;		err++;	}	if(cmd->stop_src == TRIG_NONE)	{		/* TRIG_NONE */		if (cmd->stop_arg != 0)		{			cmd->stop_arg=0;			err++;		}	}	if(err)return 3;	/* step 4: fix up any arguments */	if(cmd->scan_begin_src == TRIG_TIMER)	{		tmp = cmd->scan_begin_arg;		i8253_cascade_ns_to_timer_2div(TIMER_BASE,			&(devpriv->ao_divisor1), &(devpriv->ao_divisor2),			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);		if(tmp != cmd->scan_begin_arg)			err++;	}	if(err) return 4;	// check channel/gain list against card's limitations	if(cmd->chanlist &&		cmd->chanlist_len > 1)	{		if(CR_CHAN(cmd->chanlist[0]) != 0 ||			CR_CHAN(cmd->chanlist[1]) != 1)		{			comedi_error(dev, "channels must be ordered channel 0, channel 1 in chanlist\n");			err++;		}	}	if(err) return 5;	return 0;}static int cb_pcidas_ao_cmd(comedi_device *dev,comedi_subdevice *s){	comedi_async *async = s->async;

⌨️ 快捷键说明

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