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

📄 adl_pci9118.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if (!cmd->chanlist_len) {		cmd->chanlist_len=1;		err++;	}	if (cmd->chanlist_len>this_board->n_aichanlist) {		cmd->chanlist_len=this_board->n_aichanlist;		err++;	}	if (cmd->scan_end_arg<cmd->chanlist_len) {		cmd->scan_end_arg=cmd->chanlist_len;		err++;	}	if ((cmd->scan_end_arg % cmd->chanlist_len)) {		cmd->scan_end_arg=cmd->chanlist_len*(cmd->scan_end_arg/cmd->chanlist_len);		err++;	}	if(err) return 3;	/* step 4: fix up any arguments */	if (cmd->scan_begin_src==TRIG_TIMER) {		tmp=cmd->scan_begin_arg;//		rt_printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,&divisor1,&divisor2,&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);//		rt_printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);		if(cmd->scan_begin_arg<this_board->ai_ns_min)			cmd->scan_begin_arg=this_board->ai_ns_min;		if(tmp!=cmd->scan_begin_arg)err++;	} 	if (cmd->convert_src&(TRIG_TIMER|TRIG_NOW)) {		tmp=cmd->convert_arg;		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,&divisor1,&divisor2,&cmd->convert_arg,cmd->flags&TRIG_ROUND_MASK);//		rt_printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);		if (cmd->convert_arg<this_board->ai_ns_min)			cmd->convert_arg=this_board->ai_ns_min;		if (tmp!=cmd->convert_arg) err++;		if (cmd->scan_begin_src==TRIG_TIMER && cmd->convert_src==TRIG_NOW) {			if (cmd->convert_arg==0) {				if (cmd->scan_begin_arg<this_board->ai_ns_min*(cmd->scan_end_arg+2)) {					cmd->scan_begin_arg=this_board->ai_ns_min*(cmd->scan_end_arg+2);//		rt_printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);					err++;				}			} else {	    			if (cmd->scan_begin_arg<cmd->convert_arg*cmd->chanlist_len) {					cmd->scan_begin_arg=cmd->convert_arg*cmd->chanlist_len;//		rt_printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);					err++;				}			}		}	}	if (err) return 4;	if (cmd->chanlist)		if (!check_channel_list(dev, s, cmd->chanlist_len,			cmd->chanlist,0,0)) return 5; // incorrect channels list	return 0;}/*==============================================================================*/static int Compute_and_setup_dma(comedi_device *dev){	unsigned int dmalen0,dmalen1,i;	DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");	dmalen0=devpriv->dmabuf_size[0];	dmalen1=devpriv->dmabuf_size[1];	DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1, devpriv->ai_data_len);	// isn't output buff smaller that our DMA buff?	if (dmalen0>(devpriv->ai_data_len)) {		dmalen0=devpriv->ai_data_len&~3L; // allign to 32bit down	}	if (dmalen1>(devpriv->ai_data_len)) {		dmalen1=devpriv->ai_data_len&~3L; // allign to 32bit down	}	DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);		// we want wake up every scan?	if (devpriv->ai_flags & TRIG_WAKE_EOS) {		if (dmalen0<(devpriv->ai_n_realscanlen<<1)) {			// uff, too short DMA buffer, disable EOS support!			devpriv->ai_flags&=(~TRIG_WAKE_EOS); 			rt_printk("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",dev->minor,dmalen0,devpriv->ai_n_realscanlen<<1);		} else {			// short first DMA buffer to one scan			dmalen0=devpriv->ai_n_realscanlen<<1;			DPRINTK("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen0, devpriv->ai_n_realscanlen,devpriv->useeoshandle);			if (devpriv->useeoshandle) dmalen0+=2;			if (dmalen0<4) {				rt_printk("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",dev->minor,dmalen0);				dmalen0=4;			}		}	}	if (devpriv->ai_flags & TRIG_WAKE_EOS) {		if (dmalen1<(devpriv->ai_n_realscanlen<<1)) {			// uff, too short DMA buffer, disable EOS support!			devpriv->ai_flags&=(~TRIG_WAKE_EOS); 			rt_printk("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",dev->minor,dmalen1,devpriv->ai_n_realscanlen<<1);		} else {			// short second DMA buffer to one scan			dmalen1=devpriv->ai_n_realscanlen<<1;			DPRINTK("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen,devpriv->useeoshandle);			if (devpriv->useeoshandle) dmalen1-=2;			if (dmalen1<4) {				rt_printk("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",dev->minor,dmalen1);				dmalen1=4;			}		}	}		DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);	// transfer without TRIG_WAKE_EOS	if (!(devpriv->ai_flags&TRIG_WAKE_EOS)) {		// if it's possible then allign DMA buffers to length of scan		i=dmalen0;		dmalen0=(dmalen0/(devpriv->ai_n_realscanlen<<1))*(devpriv->ai_n_realscanlen<<1);		dmalen0&=~3L;		if (!dmalen0) dmalen0=i; // uff. very long scan?		i=dmalen1;		dmalen1=(dmalen1/(devpriv->ai_n_realscanlen<<1))*(devpriv->ai_n_realscanlen<<1);		dmalen1&=~3L;		if (!dmalen1) dmalen1=i; // uff. very long scan?		// if measure isn't neverending then test, if it whole fits into one or two DMA buffers		if (!devpriv->ai_neverending) { 			// fits whole measure into one DMA buffer?			if (dmalen0>((devpriv->ai_n_realscanlen<<1)*devpriv->ai_scans)) {				DPRINTK("3.0 ai_n_realscanlen=%d ai_scans=%d \n", devpriv->ai_n_realscanlen, devpriv->ai_scans);				dmalen0=(devpriv->ai_n_realscanlen<<1)*devpriv->ai_scans;				DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);				dmalen0&=~3L;			} else { // fits whole measure into two DMA buffer?				if (dmalen1>((devpriv->ai_n_realscanlen<<1)*devpriv->ai_scans-dmalen0)) 					dmalen1=(devpriv->ai_n_realscanlen<<1)*devpriv->ai_scans-dmalen0;					DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);					dmalen1&=~3L;			}		}	}		DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);	// these DMA buffer size we'll be used	devpriv->dma_actbuf=0;	devpriv->dmabuf_use_size[0]=dmalen0;	devpriv->dmabuf_use_size[1]=dmalen1;		DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);#if 0	if (devpriv->ai_n_scanlen<this_board->half_fifo_size) {		devpriv->dmabuf_panic_size[0]=(this_board->half_fifo_size/devpriv->ai_n_scanlen+1)*devpriv->ai_n_scanlen*sizeof(sampl_t);		devpriv->dmabuf_panic_size[1]=(this_board->half_fifo_size/devpriv->ai_n_scanlen+1)*devpriv->ai_n_scanlen*sizeof(sampl_t);	} else {		devpriv->dmabuf_panic_size[0]=(devpriv->ai_n_scanlen<<1)%devpriv->dmabuf_size[0];		devpriv->dmabuf_panic_size[1]=(devpriv->ai_n_scanlen<<1)%devpriv->dmabuf_size[1];	}#endif		outl(inl(devpriv->iobase_a+AMCC_OP_REG_MCSR)&(~EN_A2P_TRANSFERS), devpriv->iobase_a+AMCC_OP_REG_MCSR); // stop DMA	outl(devpriv->dmabuf_hw[0], devpriv->iobase_a+AMCC_OP_REG_MWAR);	outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a+AMCC_OP_REG_MWTC);	// init DMA transfer	outl(0x00000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);//	outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);		outl(inl(devpriv->iobase_a+AMCC_OP_REG_MCSR)|RESET_A2P_FLAGS|A2P_HI_PRIORITY|EN_A2P_TRANSFERS, devpriv->iobase_a+AMCC_OP_REG_MCSR);    	outl(inl(devpriv->iobase_a+AMCC_OP_REG_INTCSR)|EN_A2P_TRANSFERS, devpriv->iobase_a+AMCC_OP_REG_INTCSR);	// allow bus mastering	DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");	return 0;}/* ==============================================================================*/static int pci9118_ai_docmd_sampl(comedi_device * dev, comedi_subdevice * s) {	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",dev->minor,devpriv->ai_do); 	switch (devpriv->ai_do) {	case 1: 		devpriv->AdControlReg|=AdControl_TmrTr;		break;	case 2: 		comedi_error(dev,"pci9118_ai_docmd_sampl() mode 2 bug!\n");		return -EIO;	case 3: 		devpriv->AdControlReg|=AdControl_ExtM;		break;	case 4: 		comedi_error(dev,"pci9118_ai_docmd_sampl() mode 4 bug!\n");		return -EIO;	default: 		comedi_error(dev,"pci9118_ai_docmd_sampl() mode number bug!\n");		return -EIO;	}; 	devpriv->int_ai_func=interrupt_pci9118_ai_onesample; //transfer function	if (devpriv->ai12_startstop)		pci9118_exttrg_add(dev,EXTTRG_AI);	// activate EXT trigger				if ((devpriv->ai_do==1)||(devpriv->ai_do==2)) 		devpriv->IntControlReg|=Int_Timer;	devpriv->AdControlReg|=AdControl_Int;		outl(inl(devpriv->iobase_a+AMCC_OP_REG_INTCSR)|0x1f00, devpriv->iobase_a+AMCC_OP_REG_INTCSR); // allow INT in AMCC	if (!(devpriv->ai12_startstop&(START_AI_EXT|START_AI_INT))) {		outl(devpriv->IntControlReg,dev->iobase+PCI9118_INTCTRL);		outl(devpriv->AdFunctionReg,dev->iobase+PCI9118_ADFUNC);		if (devpriv->ai_do!=3) {			start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);			devpriv->AdControlReg|=AdControl_SoftG;		}		outl(devpriv->IntControlReg,dev->iobase+PCI9118_INTCTRL);	}	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");	return 0;}/* ==============================================================================*/static int pci9118_ai_docmd_dma(comedi_device * dev, comedi_subdevice * s) {	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",dev->minor,devpriv->ai_do,devpriv->usedma);	Compute_and_setup_dma(dev); 	switch (devpriv->ai_do) {	case 1: 		devpriv->AdControlReg|=((AdControl_TmrTr|AdControl_Dma) & 0xff);		break;	case 2: 		devpriv->AdControlReg|=((AdControl_TmrTr|AdControl_Dma) & 0xff);		devpriv->AdFunctionReg=AdFunction_PDTrg|AdFunction_PETrg|AdFunction_BM|AdFunction_BS;		if (devpriv->usessh&&(!devpriv->softsshdelay)) 			devpriv->AdFunctionReg|=AdFunction_BSSH;		outl(devpriv->ai_n_realscanlen, dev->iobase+PCI9118_BURST); 		break;	case 3: 		devpriv->AdControlReg|=((AdControl_ExtM|AdControl_Dma) & 0xff);		devpriv->AdFunctionReg=AdFunction_PDTrg|AdFunction_PETrg;		break;	case 4: 		devpriv->AdControlReg|=((AdControl_TmrTr|AdControl_Dma) & 0xff);		devpriv->AdFunctionReg=AdFunction_PDTrg|AdFunction_PETrg|AdFunction_AM;		outl(devpriv->AdFunctionReg,dev->iobase+PCI9118_ADFUNC);		outl(0x30, dev->iobase + PCI9118_CNTCTRL);		outl((devpriv->dmabuf_hw[0]>>1)&0xff, dev->iobase + PCI9118_CNT0);		outl((devpriv->dmabuf_hw[0]>>9)&0xff, dev->iobase + PCI9118_CNT0);		devpriv->AdFunctionReg|=AdFunction_Start;		break;	default: 		comedi_error(dev,"pci9118_ai_docmd_dma() mode number bug!\n");		return -EIO;	}; 	if (devpriv->ai12_startstop) {		pci9118_exttrg_add(dev,EXTTRG_AI);	// activate EXT trigger	}	devpriv->int_ai_func=interrupt_pci9118_ai_dma; //transfer function	switch (devpriv->usedma) { 	case 2: // 32 bit DMA mode		if (devpriv->ai16bits) { // select interrupt function			devpriv->dma_ai_read_block=move_block_from_dma_16bit_32b;		} else {			devpriv->dma_ai_read_block=move_block_from_dma_12bit_32b;		}		outl(0x00000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);		break;	case 1: // 16 bit DMA mode		if (devpriv->ai16bits) { // select interrupt function			devpriv->dma_ai_read_block=move_block_from_dma_16bit_16b;		} else {			devpriv->dma_ai_read_block=move_block_from_dma_12bit_16b;		}		outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);		break;	default:		comedi_error(dev,"pci9118_ai_docmd_dma() usedma!={1,2}\n");		return -EIO;	}		if (!(devpriv->ai12_startstop&(START_AI_EXT|START_AI_INT))) {		outl(devpriv->AdFunctionReg,dev->iobase+PCI9118_ADFUNC);		outl(devpriv->IntControlReg,dev->iobase+PCI9118_INTCTRL);		if (devpriv->ai_do!=3) {			start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);			devpriv->AdControlReg|=AdControl_SoftG;		}		outl(devpriv->AdControlReg, dev->iobase+PCI9118_ADCNTRL);	}	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");	return 0;}/*==============================================================================*/static int pci9118_ai_cmd(comedi_device *dev,comedi_subdevice *s){	comedi_cmd *cmd=&s->async->cmd;	unsigned int addchans=0;	int ret=0;		DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n",dev->minor);	devpriv->ai12_startstop=0;	devpriv->ai_flags=cmd->flags;	devpriv->ai_n_chan=cmd->chanlist_len;	devpriv->ai_n_scanlen=cmd->scan_end_arg;	devpriv->ai_chanlist=cmd->chanlist;	devpriv->ai_data=s->async->prealloc_buf;	devpriv->ai_data_len=s->async->prealloc_bufsz;	devpriv->ai_timer1=0;	devpriv->ai_timer2=0;	devpriv->ai_add_front=0;	devpriv->ai_add_back=0;	devpriv->ai_maskerr=0x10e;	// prepare for start/stop conditions	if (cmd->start_src==TRIG_EXT) devpriv->ai12_startstop|=START_AI_EXT;	if (cmd->stop_src==TRIG_EXT) {		devpriv->ai_neverending=1;		devpriv->ai12_startstop|=STOP_AI_EXT;	}	if (cmd->start_src==TRIG_INT) {		devpriv->ai12_startstop|=START_AI_INT;		devpriv->ai_inttrig_start=cmd->start_arg;		s->async->inttrig=pci9118_ai_inttrig;	}#if 0	if (cmd->stop_src==TRIG_INT) {		devpriv->ai_neverending=1;		devpriv->ai12_startstop|=STOP_AI_INT;	}#endif	if (cmd->stop_src==TRIG_NONE) devpriv->ai_neverending=1;	if (cmd->stop_src==TRIG_COUNT) { devpriv->ai_scans=cmd->stop_arg; devpriv->ai_neverending=0; }				else   { devpriv->ai_scans=0; }		 // use sample&hold signal?	if (cmd->convert_src==TRIG_NOW)	 { devpriv->usessh=1; } // yes 				    else { devpriv->usessh=0; } // no	DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n", 		devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh, devpriv->ai12_startstop);	// use additional sample at end of every scan to satisty DMA 32 bit transfer?	devpriv->ai_add_front=0;	devpriv->ai_add_back=0;	devpriv->useeoshandle=0;	if (devpriv->master) {		devpriv->usedma=2; // assume 32 bit DMA transfer now		if ((cmd->flags&TRIG_WAKE_EOS) &&		    (devpriv->ai_n_scanlen==1)) {		    	if (cmd->convert_src==TRIG_NOW) { 				devpriv->usedma=1;	// 16 BIT dma MODE

⌨️ 快捷键说明

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