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

📄 ni_mio_common.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}static int ni_ao_insn_read(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];	return 1;}static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	unsigned int chan = CR_CHAN(insn->chanspec);	unsigned int invert;	invert = ni_ao_config_chanlist(dev,s,&insn->chanspec,1);	devpriv->ao[chan] = data[0];	ni_writew(data[0] ^ invert,(chan)? DAC1_Direct_Data : DAC0_Direct_Data);	return 1;}static int ni_ao_insn_write_671x(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	unsigned int chan = CR_CHAN(insn->chanspec);	unsigned int invert;	ao_win_out(1 << chan, AO_Immediate_671x);	invert = 1 << (boardtype.aobits - 1);	if( boardtype.reg_611x == 0 )		ni_ao_config_chanlist(dev,s,&insn->chanspec,1);	devpriv->ao[chan] = data[0];	ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));	return 1;}static int ni_ao_inttrig(comedi_device *dev,comedi_subdevice *s,	unsigned int trignum){	int ret;	int bits;	if(trignum!=0)return -EINVAL;	win_out(devpriv->ao_mode3|AO_Not_An_UPDATE,AO_Mode_3_Register);	win_out(devpriv->ao_mode3,AO_Mode_3_Register);	/* wait for DACs to be loaded */	comedi_udelay(100);	win_out(devpriv->ao_cmd1|AO_UI_Arm|AO_UC_Arm|AO_BC_Arm|AO_DAC1_Update_Mode|AO_DAC0_Update_Mode,		AO_Command_1_Register);	bits = AO_Error_Interrupt_Enable;#ifdef PCIDMA	win_out(0, DAC_FIFO_Clear);	// offset load doesn't seem to be necessary	//ao_win_out( 0x6, AO_FIFO_Offset_Load_611x );	ni_ao_setup_MITE_dma(dev, &s->async->cmd);	ret = ni_ao_wait_for_dma_load(dev);	if(ret < 0) return ret;	ni_set_bits(dev, Interrupt_B_Enable_Register, AO_FIFO_Interrupt_Enable, 0);#else	ret = ni_ao_prep_fifo(dev,s);	if(ret==0)return -EPIPE;	bits |= AO_FIFO_Interrupt_Enable;#endif	ni_set_bits(dev, Interrupt_B_Enable_Register, bits, 1);	win_out(devpriv->ao_cmd2|AO_START1_Pulse,AO_Command_2_Register);	s->async->inttrig=NULL;	return 0;}static int ni_ao_cmd(comedi_device *dev,comedi_subdevice *s){	comedi_cmd *cmd = &s->async->cmd;	int trigvar;	int bits;	trigvar = ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);	win_out(AO_Configuration_Start,Joint_Reset_Register);	win_out(AO_Disarm,AO_Command_1_Register);	ni_ao_config_chanlist(dev,s,cmd->chanlist,cmd->chanlist_len);	if(cmd->stop_src==TRIG_NONE){		devpriv->ao_mode1|=AO_Continuous;		devpriv->ao_mode1&=~AO_Trigger_Once;	}else{		devpriv->ao_mode1&=~AO_Continuous;		devpriv->ao_mode1|=AO_Trigger_Once;	}	win_out(devpriv->ao_mode1,AO_Mode_1_Register);	devpriv->ao_trigger_select&=~(AO_START1_Polarity|AO_START1_Select(-1));	devpriv->ao_trigger_select|=AO_START1_Edge|AO_START1_Sync;	win_out(devpriv->ao_trigger_select,AO_Trigger_Select_Register);	devpriv->ao_mode3&=~AO_Trigger_Length;	win_out(devpriv->ao_mode3,AO_Mode_3_Register);	win_out(devpriv->ao_mode1,AO_Mode_1_Register);	devpriv->ao_mode2&=~AO_BC_Initial_Load_Source;	win_out(devpriv->ao_mode2,AO_Mode_2_Register);	if(cmd->stop_src==TRIG_NONE){		win_out2(0xffffff,AO_BC_Load_A_Register);	}else{		win_out2(0,AO_BC_Load_A_Register);	}	win_out(AO_BC_Load,AO_Command_1_Register);	devpriv->ao_mode2&=~AO_UC_Initial_Load_Source;	win_out(devpriv->ao_mode2,AO_Mode_2_Register);	switch(cmd->stop_src){	case TRIG_COUNT:		win_out2(cmd->stop_arg,AO_UC_Load_A_Register);		win_out(AO_UC_Load,AO_Command_1_Register);		win_out2(cmd->stop_arg - 1,AO_UC_Load_A_Register);		break;	case TRIG_NONE:		win_out2(0xffffff,AO_UC_Load_A_Register);		win_out(AO_UC_Load,AO_Command_1_Register);		win_out2(0xffffff,AO_UC_Load_A_Register);		break;	default:		win_out2(0,AO_UC_Load_A_Register);		win_out(AO_UC_Load,AO_Command_1_Register);		win_out2(cmd->stop_arg,AO_UC_Load_A_Register);	}	devpriv->ao_cmd2&=~AO_BC_Gate_Enable;	win_out(devpriv->ao_cmd2,AO_Command_2_Register);	devpriv->ao_mode1&=~(AO_UI_Source_Select(0x1f)|AO_UI_Source_Polarity);	win_out(devpriv->ao_mode1,AO_Mode_1_Register);	devpriv->ao_mode2&=~(AO_UI_Reload_Mode(3)|AO_UI_Initial_Load_Source);	win_out(devpriv->ao_mode2,AO_Mode_2_Register);	win_out2(1,AO_UI_Load_A_Register);	win_out(AO_UI_Load,AO_Command_1_Register);	win_out2(trigvar,AO_UI_Load_A_Register);	if( boardtype.ao_671x == 0 ){		if(cmd->scan_end_arg>1){			devpriv->ao_mode1|=AO_Multiple_Channels;			win_out(AO_Number_Of_Channels(cmd->scan_end_arg-1)|				AO_UPDATE_Output_Select(1),				AO_Output_Control_Register);		}else{			devpriv->ao_mode1&=~AO_Multiple_Channels;			win_out(AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]))|				AO_UPDATE_Output_Select(1),				AO_Output_Control_Register);		}		win_out(devpriv->ao_mode1,AO_Mode_1_Register);	}	win_out(AO_DAC0_Update_Mode|AO_DAC1_Update_Mode,AO_Command_1_Register);	devpriv->ao_mode3|=AO_Stop_On_Overrun_Error;	win_out(devpriv->ao_mode3,AO_Mode_3_Register);	devpriv->ao_mode2 &= AO_FIFO_Mode_Mask;#ifdef PCIDMA	devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;#else	devpriv->ao_mode2 |= AO_FIFO_Mode_HF;#endif	devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;	win_out(devpriv->ao_mode2,AO_Mode_2_Register);	bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |		AO_TMRDACWR_Pulse_Width;	if( boardtype.ao_fifo_depth )		bits |= AO_FIFO_Enable;	win_out(bits, AO_Personal_Register);	// enable sending of ao dma requests	win_out(AO_AOFREQ_Enable, AO_Start_Select_Register);	win_out(AO_Configuration_End,Joint_Reset_Register);	if(cmd->stop_src==TRIG_COUNT) {		win_out(AO_BC_TC_Interrupt_Ack,Interrupt_B_Ack_Register);		ni_set_bits(dev, Interrupt_B_Enable_Register,			AO_BC_TC_Interrupt_Enable, 1);	}	s->async->inttrig=ni_ao_inttrig;	return 0;}static int ni_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd){	int err=0;	int tmp;	/* 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;	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->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 0	/* XXX need ao_speed */	if(cmd->scan_begin_arg<boardtype.ao_speed){		cmd->scan_begin_arg=boardtype.ao_speed;		err++;	}#endif	if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){ /* XXX check */		cmd->scan_begin_arg=TIMER_BASE*0xffffff;		err++;	}	if(cmd->convert_arg!=0){		cmd->convert_arg=0;		err++;	}	if(cmd->scan_end_arg!=cmd->chanlist_len){		cmd->scan_end_arg=cmd->chanlist_len;		err++;	}	if(cmd->stop_src==TRIG_COUNT){ /* XXX check */		if(cmd->stop_arg>0x00ffffff){			cmd->stop_arg=0x00ffffff;			err++;		}	}else{		/* TRIG_NONE */		if(cmd->stop_arg!=0){			cmd->stop_arg=0;			err++;		}	}	if(err)return 3;	/* step 4: fix up any arguments */	tmp = cmd->scan_begin_arg;	ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);	if(tmp!=cmd->scan_begin_arg)err++;		if(err)return 4;	/* step 5: fix up chanlist */	if(cmd->chanlist_len != cmd->scan_end_arg){		cmd->chanlist_len = cmd->scan_end_arg;		err++;	}	if(err)return 5;	return 0;}static int ni_ao_reset(comedi_device *dev,comedi_subdevice *s){	//devpriv->ao0p=0x0000;	//ni_writew(devpriv->ao0p,AO_Configuration);	//devpriv->ao1p=AO_Channel(1);	//ni_writew(devpriv->ao1p,AO_Configuration);#ifdef PCIDMA	mite_dma_disarm(devpriv->mite, AO_DMA_CHAN);	writel(CHOR_DMARESET | CHOR_FRESET, devpriv->mite->mite_io_addr + MITE_CHOR +		CHAN_OFFSET(AO_DMA_CHAN));#endif	win_out(AO_Configuration_Start,Joint_Reset_Register);	win_out(AO_Disarm,AO_Command_1_Register);	ni_set_bits(dev,Interrupt_B_Enable_Register,~0,0);	win_out(0x0010,AO_Personal_Register);	win_out(0x3f98,Interrupt_B_Ack_Register);	win_out(AO_BC_Source_Select | AO_UPDATE_Pulse_Width |		AO_TMRDACWR_Pulse_Width, AO_Personal_Register);	win_out(0,AO_Output_Control_Register);	win_out(0,AO_Start_Select_Register);	devpriv->ao_cmd1=0;	win_out(devpriv->ao_cmd1,AO_Command_1_Register);	devpriv->ao_cmd2=0;	devpriv->ao_mode1=0;	devpriv->ao_mode2=0;	devpriv->ao_mode3=0;	devpriv->ao_trigger_select=0;	if(boardtype.ao_671x){		ao_win_out(0x3, AO_Immediate_671x);		ao_win_out(CLEAR_WG, AO_Misc_611x);	}	return 0;}static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){#ifdef DEBUG_DIO	printk("ni_dio_insn_config() chan=%d io=%d\n",		CR_CHAN(insn->chanspec),data[0]);#endif	if(insn->n!=1)return -EINVAL;	switch(data[0]){	case COMEDI_OUTPUT:		s->io_bits |= 1<<CR_CHAN(insn->chanspec);		break;	case COMEDI_INPUT:		s->io_bits &= ~(1<<CR_CHAN(insn->chanspec));		break;	default:		return -EINVAL;	}	devpriv->dio_control &= ~DIO_Pins_Dir_Mask;	devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);	win_out(devpriv->dio_control,DIO_Control_Register);	return 1;}static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){#ifdef DEBUG_DIO	printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n",data[0],data[1]);#endif	if(insn->n!=2)return -EINVAL;	if(data[0]){		s->state &= ~data[0];		s->state |= (data[0]&data[1]);		devpriv->dio_output &= ~DIO_Parallel_Data_Mask;		devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);		win_out(devpriv->dio_output,DIO_Output_Register);	}	data[1] = win_in(DIO_Parallel_Input_Register);	return 2;}static void mio_common_detach(comedi_device *dev){	if(dev->subdevices && boardtype.has_8255)		subdev_8255_cleanup(dev,dev->subdevices+3);}static int ni_E_init(comedi_device *dev,comedi_devconfig *it){	comedi_subdevice *s;	int bits;	if(alloc_subdevices(dev, 8)<0)		return -ENOMEM;	/* analog input subdevice */	s=dev->subdevices+0;	dev->read_subdev=s;	if(boardtype.n_adchan){		s->type=COMEDI_SUBD_AI;		s->subdev_flags=SDF_READABLE|SDF_DIFF;		if( boardtype.reg_611x == 0 )			s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;		s->subdev_flags|=SDF_DITHER;		s->n_chan=boardtype.n_adchan;		s->len_chanlist=512;		s->maxdata=(1<<boardtype.adbits)-1;		s->range_table=ni_range_lkup[boardtype.gainlkup];		s->insn_read=ni_ai_insn_read;		s->insn_config=ni_ai_insn_config;		s->do_cmdtest=ni_ai_cmdtest;		s->do_cmd=ni_ai_cmd;		s->cancel=ni_ai_reset;		s->poll=ni_ai_poll;		s->munge=ni_ai_munge;	}else{		s->type=COMEDI_SUBD_UNUSED;	}	/* analog output subdevice */	s=dev->subdevices+1;	if(boardtype.n_aochan){		dev->write_subdev=s;		s->type=COMEDI_SUBD_AO;		s->subdev_flags=SDF_WRITABLE|SDF_DEGLITCH|SDF_GROUND;		s->n_chan=boardtype.n_aochan;		s->maxdata=(1<<boardtype.aobits)-1;		if(boardtype.ao_unipolar){			s->range_table=&range_ni_E_ao_ext;	/* XXX wrong for some boards */		}else{			s->range_table=&range_bipolar10;		}		s->insn_read=ni_ao_insn_read;		if(boardtype.ao_671x){			s->insn_write=ni_ao_insn_write_671x;		}else{			s->insn_write=ni_ao_insn_write;		}		if(boardtype.ao_fifo_depth){			s->do_cmd=ni_ao_cmd;			s->do_cmdtest=ni_ao_cmdtest;			s->len_chanlist = 2;		}		s->cancel=ni_ao_reset;		s->munge=ni_ao_munge;	}else{		s->type=COMEDI_SUBD_UNUSED;	}	/* digital i/o subdevice */	s=dev->subdevices+2;	s->type=COMEDI_SUBD_DIO;	s->subdev_flags=SDF_WRITABLE|SDF_READABLE;	s->n_chan=8;	s->maxdata=1;	s->range_table=&range_digital;	s->io_bits=0;		/* all bits input */	s->insn_bits=ni_dio_insn_bits;	s->insn_config=ni_dio_insn_config;	/* dio setup */	devpriv->dio_control = DIO_Pins_Dir(s->io_bits);	win_out(devpriv->dio_control,DIO_Control_Register);		/* 8255 device */	s=dev->subdevices+3;	if(boardtype.has_8255){		subdev_8255_init(dev,s,ni_8255_callback,(unsigned long)dev);	}else{		s->type=COMEDI_SUBD_UNUSED;	}		/* general purpose counter/timer device */	s=dev->subdevices+4;	s->type=COMEDI_SUBD_COUNTER;	s->subdev_flags=SDF_READABLE|SDF_WRITABLE;	s->insn_read=  ni_gpct_insn_read;	s->insn_write= ni_gpct_insn_write;	s->insn_config=ni_gpct_insn_config;	s->n_chan=2;	s->maxdata=1;	devpriv->an_trig_etc_reg = 0;	GPCT_Reset(dev,0);	GPCT_Reset(dev,1);		/* calibration subdevice -- ai and ao */	s=dev->subdevices+5;	s->type=COMEDI_SUBD_CALIB;	s->subdev_flags=SDF_WRITABLE|SDF_INTERNAL;	s->insn_read=ni_calib_insn_read;	s->insn_write=ni_calib_insn_write;	caldac_setup(dev,s);		/* EEPROM */	s=dev->subdevices+6;	s->type=COMEDI_SUBD_MEMORY;	s->subdev_flags=SDF_READABLE|SDF_INTERNAL;	s->n_chan=512;	s->maxdata=0xff;	s->insn_read=ni_eeprom_insn_re

⌨️ 快捷键说明

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