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

📄 patch-scxi

📁 最新rtlinux内核源码
💻
字号:
Index: comedi/drivers/ni_mio_common.c===================================================================RCS file: /var/cvs/comedi/comedi/drivers/ni_mio_common.c,vretrieving revision 1.43diff -u -r1.43 ni_mio_common.c--- comedi/drivers/ni_mio_common.c	2001/02/05 02:58:40	1.43+++ comedi/drivers/ni_mio_common.c	2001/02/05 02:59:48@@ -161,6 +161,11 @@ static int ni_dio(comedi_device *dev,comedi_subdevice *s,comedi_trig *it); #endif +static int ni_serial_insn_config(comedi_device *dev,comedi_subdevice *s,+				 comedi_insn *insn,lsampl_t *data);+static int ni_serial_insn_bits(comedi_device *dev,comedi_subdevice *s,+			       comedi_insn *insn,lsampl_t *data);+ #ifdef USE_TRIG static int ni_eeprom(comedi_device *dev,comedi_subdevice *s,comedi_trig *it); #endif@@ -203,6 +208,11 @@ #define AIMODE_SCAN		2 #define AIMODE_SAMPLE		3 +/* supported serial clock intervals */+#define SERIAL_DISABLED         0+#define SERIAL_600NS          600+#define SERIAL_1_2US         1200+#define SERIAL_10US         10000  static void ni_E_interrupt(int irq,void *d,struct pt_regs * regs) {@@ -1991,6 +2001,203 @@ 	return 2; } +static int ni_serial_insn_config(comedi_device *dev,comedi_subdevice *s,+				 comedi_insn *insn,lsampl_t *data)+{+#ifdef DEBUG_DIO+	printk("SPI serial I/O Config %d\n", data[0]);+#endif++	if(insn->n!=1)return -EINVAL;+	devpriv->serial_interval_ns = data[0];+	devpriv->serial_hw_mode = 1;+	devpriv->dio_control |= DIO_HW_Serial_Enable;+	switch(data[0]) {+	default:+	case SERIAL_DISABLED:+		/* Disable (or use software serial) */+		devpriv->serial_hw_mode = 0;+		devpriv->dio_control &= ~(DIO_HW_Serial_Enable |+					  DIO_Software_Serial_Control);+		break;+	case SERIAL_600NS:+		/* Warning: this clock speed is too fast to reliably+		   control SCXI. */+		devpriv->dio_control &= ~DIO_HW_Serial_Timebase;+		devpriv->clock_and_fout |= Slow_Internal_Timebase;+		devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;+		break;+	case SERIAL_1_2US:+		devpriv->dio_control &= ~DIO_HW_Serial_Timebase;+		devpriv->clock_and_fout |= Slow_Internal_Timebase |+			DIO_Serial_Out_Divide_By_2;+		break;+	case SERIAL_10US:+		devpriv->dio_control |= DIO_HW_Serial_Timebase;+		devpriv->clock_and_fout |= Slow_Internal_Timebase |+			DIO_Serial_Out_Divide_By_2;+		/* Note: DIO_Serial_Out_Divide_By_2 only affects+		   600ns/1.2us. If you turn divide_by_2 off with the+		   slow clock, you will still get 10us, except then+		   all your delays are wrong. */+		break;+	}+	win_out(devpriv->dio_control,DIO_Control_Register);+	win_out(devpriv->clock_and_fout,Clock_and_FOUT_Register);+	return 1;+}++static int ni_serial_hw_readwrite8(comedi_device *dev,comedi_subdevice *s,+				   unsigned char data_out, +				   unsigned char *data_in)+{+	unsigned int status1;+	int err = 0, count = 20;++#ifdef DEBUG_DIO+	printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);+#endif++	if(devpriv->serial_interval_ns == 0) {+		err = -EINVAL;+		goto Error;+	}++	devpriv->dio_output &= ~DIO_Serial_Data_Mask;+	devpriv->dio_output |= DIO_Serial_Data_Out(data_out);+	win_out(devpriv->dio_output,DIO_Output_Register);++	status1 = win_in(Joint_Status_1_Register);+	if(status1 & DIO_Serial_IO_In_Progress_St) {+		err = -EBUSY;+		goto Error;+	}++	devpriv->dio_control |= DIO_HW_Serial_Start;+	win_out(devpriv->dio_control,DIO_Control_Register);+	devpriv->dio_control &= ~DIO_HW_Serial_Start;+	+	/* Wait until STC says we're done, but don't loop infinitely. Also,+	   we don't have to keep updating the window address for this. */+	ni_writew(Joint_Status_1_Register,Window_Address);+	while((status1 = ni_readw(Window_Data)) & DIO_Serial_IO_In_Progress_St) {+		/* Delay one bit per loop */+		nanodelay(devpriv->serial_interval_ns);+		if(--count < 0) {+			printk("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");+			err = -ETIME;+			goto Error;+		}+	}++	/* Delay for last bit. This delay is absolutely necessary, because+	   DIO_Serial_IO_In_Progress_St goes high one bit too early. */+	nanodelay(devpriv->serial_interval_ns);++	if(data_in != NULL) {+		*data_in = win_in(DIO_Serial_Input_Register);+#ifdef DEBUG_DIO+		printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);+#endif+	}+	+ Error:+	win_out(devpriv->dio_control,DIO_Control_Register);+	+	return err;+}++static int ni_serial_sw_readwrite8(comedi_device *dev,comedi_subdevice *s,+				   unsigned char data_out, +				   unsigned char *data_in)+{+	unsigned char mask, input = 0;++#ifdef DEBUG_DIO+	printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);+#endif++	/* Wait for one bit before transfer */+	nanodelay(devpriv->serial_interval_ns);++	for(mask = 0x80; mask; mask >>= 1) {+		/* Output current bit; note that we cannot touch s->state+		   because it is a per-subdevice field, and serial is+		   a separate subdevice from DIO. */+		devpriv->dio_output &= ~DIO_SDOUT;+		if(data_out & mask) {+			devpriv->dio_output |= DIO_SDOUT;+		}+		win_out(devpriv->dio_output,DIO_Output_Register);++		/* Assert SDCLK (active low, inverted), wait for half of+		   the delay, deassert SDCLK, and wait for the other half. */+		devpriv->dio_control |= DIO_Software_Serial_Control;+		win_out(devpriv->dio_control,DIO_Control_Register);++		nanodelay(devpriv->serial_interval_ns / 2);++		devpriv->dio_control &= ~DIO_Software_Serial_Control;+		win_out(devpriv->dio_control,DIO_Control_Register);++		nanodelay(devpriv->serial_interval_ns / 2);++		/* Input current bit */+		if(ni_readw(DIO_Parallel_Input) & DIO_SDIN) {+			input |= mask;+		}+	}+#ifdef DEBUG_DIO+	printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);+#endif+	if(data_in) *data_in = input;++	return 0;+}++static int ni_serial_insn_bits(comedi_device *dev,comedi_subdevice *s,+			       comedi_insn *insn,lsampl_t *data)+{+	int err = insn->n;+	lsampl_t data_out, data_in, num_bits;+	unsigned char byteOut, byteIn;++#ifdef DEBUG_DIO+	printk("ni_serial_insn_bits: num_bits=0x%x data_out=0x%x\n", data[0],+	       data[1]);+#endif++	if(insn->n!=2) return -EINVAL;++	num_bits = data[0];++	if((num_bits % 8) != 0) return -EINVAL;++	data_out = data[1];+	data_in = 0;+	while(num_bits > 0) {+		/* Read from MSB to LSB */+		data_in <<= 8;++		byteOut = (data_out >> (num_bits - 8)) & 0xff;+		if(devpriv->serial_hw_mode) {+			err = ni_serial_hw_readwrite8(dev,s,byteOut,&byteIn);+		} else if(devpriv->serial_interval_ns > 0) {+			err = ni_serial_sw_readwrite8(dev,s,byteOut,&byteIn);+		} else {+			printk("ni_serial_insn_bits: serial disabled!\n");+			return -EINVAL;+		}+		if(err < 0) return err;+		data_in |= byteIn;++		/* Write from MSB to LSB */+		num_bits -= 8;+	}+	data[1] = data_in;+	return insn->n;+}+ /* 	HACK!  @@ -2031,7 +2238,7 @@ { 	comedi_subdevice *s; 	-	dev->n_subdevices=7;+	dev->n_subdevices=8; 	 	if(alloc_subdevices(dev)<0) 		return -ENOMEM;@@ -2144,11 +2351,24 @@ #ifdef USE_TRIG 	s->trig[0]=ni_eeprom; #endif-	++	/* SPI serial I/O */+	s=dev->subdevices+7;+	s->type=COMEDI_SUBD_SERIAL;+	s->subdev_flags=SDF_READABLE|SDF_WRITEABLE|SDF_INTERNAL;+	s->n_chan=1;+	s->maxdata=0xff;+	s->insn_bits=ni_serial_insn_bits;+	s->insn_config=ni_serial_insn_config;++	/* serial configuration */+	devpriv->serial_interval_ns = 0;+	devpriv->serial_hw_mode = 0;+ 	/* ai configuration */ 	ni_ai_reset(dev,dev->subdevices+0);-	win_out(0x1ba0,Clock_and_FOUT_Register);-+	devpriv->clock_and_fout = 0x1ba0;+	win_out(devpriv->clock_and_fout,Clock_and_FOUT_Register);  	/* analog output configuration */ 	Index: include/linux/comedi.h===================================================================RCS file: /var/cvs/comedi/include/linux/comedi.h,vretrieving revision 1.5diff -u -r1.5 comedi.h--- include/linux/comedi.h	2001/01/30 20:19:39	1.5+++ include/linux/comedi.h	2001/02/05 02:59:50@@ -148,7 +148,7 @@ #define COMEDI_SUBD_MEMORY              8	/* memory, EEPROM, DPRAM */ #define COMEDI_SUBD_CALIB               9	/* calibration DACs */ #define COMEDI_SUBD_PROC                10	/* processor, DSP */-+#define COMEDI_SUBD_SERIAL              11      /* SPI serial I/O */  #define COMEDI_INPUT			0 #define COMEDI_OUTPUT			1Index: include/linux/comedidev.h===================================================================RCS file: /var/cvs/comedi/include/linux/comedidev.h,vretrieving revision 1.8diff -u -r1.8 comedidev.h--- include/linux/comedidev.h	2001/02/05 02:09:19	1.8+++ include/linux/comedidev.h	2001/02/05 02:59:51@@ -276,6 +276,18 @@ 	return 0; } +static inline int nanodelay(unsigned long ns)+{+	/* We round up, so the result should always be longer than the+	 * specified time. It's probably not much more precise than+	 * using udelay(). Hopefully, one day Linux will have an+	 * nanodelay() function. */+	unsigned long loops_per_us = (loops_per_sec + 999999) / 1000000;+	unsigned long loops = ((ns * loops_per_us) + 999) / 1000; +	/* printk("nanodelay: ns=%ld loops=%ld\n", ns, loops); */+	__delay(loops);+}+  #ifdef LINUX_V20 extern struct symbol_table comedi_syms;

⌨️ 快捷键说明

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