Exemple #1
0
static int daq700_ai_rinsn(struct comedi_device *dev,
			   struct comedi_subdevice *s,
			   struct comedi_insn *insn, unsigned int *data)
{
	int n;
	int d;
	int ret;
	unsigned int chan	= CR_CHAN(insn->chanspec);
	unsigned int aref	= CR_AREF(insn->chanspec);
	unsigned int range	= CR_RANGE(insn->chanspec);
	unsigned int r3_bits	= 0;

	/* set channel input modes */
	if (aref == AREF_DIFF)
		r3_bits |= CMD_R3_DIFF;
	/* write channel mode/range */
	if (range >= 1)
		range++;        /* convert range to hardware value */
	outb(r3_bits | (range & 0x03), dev->iobase + CMD_R3);

	/* write channel to multiplexer */
	/* set mask scan bit high to disable scanning */
	outb(chan | 0x80, dev->iobase + CMD_R1);
	/* mux needs 2us to really settle [Fred Brooks]. */
	udelay(2);

	/* convert n samples */
	for (n = 0; n < insn->n; n++) {
		/* trigger conversion with out0 L to H */
		outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */
		outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */
		outb(0x00, dev->iobase + ADCLEAR_R);	/* clear the ADC FIFO */
		/* read 16bit junk from FIFO to clear */
		inw(dev->iobase + ADFIFO_R);
		/* mode 1 out0 H, L to H, start conversion */
		outb(0x32, dev->iobase + CMO_R);

		/* wait for conversion to end */
		ret = comedi_timeout(dev, s, insn, daq700_ai_eoc, 0);
		if (ret)
			return ret;

		/* read data */
		d = inw(dev->iobase + ADFIFO_R);
		/* mangle the data as necessary */
		/* Bipolar Offset Binary: 0 to 4095 for -10 to +10 */
		d &= 0x0fff;
		d ^= 0x0800;
		data[n] = d;
	}
	return n;
}
int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
	struct comedi_insn *insn, unsigned int *data)
{
	int i_ReturnValue = 0;
	unsigned char b_Cpt;
	unsigned char b_Length;
	unsigned char b_Schift;
	unsigned char b_SSICpt;
	unsigned int dw_And;
	unsigned int dw_And1;
	unsigned int dw_And2;
	unsigned int dw_StatusReg;
	unsigned int dw_CounterValue;
	unsigned char b_ModulNbr;
	unsigned char b_SelectedSSI;
	unsigned char b_ReadType;
	unsigned int *pul_Position;
	unsigned int *pul_TurnCpt;
	unsigned int *pul_Position1;
	unsigned int *pul_TurnCpt1;

	i_ReturnValue = insn->n;
	pul_Position1 = (unsigned int *) &data[0];
/* For Read1 */
	pul_TurnCpt1 = (unsigned int *) &data[1];
/* For Read all */
	pul_Position = (unsigned int *) &data[0];	/* 0-2 */
	pul_TurnCpt = (unsigned int *) &data[3];	/* 3-5 */
	b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
	b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec);
	b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);

	/**************************/
	/* Test the module number */
	/**************************/

	if (b_ModulNbr < 4) {
	   /***********************/
		/* Test if SSI counter */
	   /***********************/

		if ((devpriv->s_BoardInfos.
				dw_MolduleConfiguration[b_ModulNbr] &
				0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
	      /***************************/
			/* Test if SSI initialised */
	      /***************************/

			if (devpriv->s_ModuleInfo[b_ModulNbr].
				s_SSICounterInfo.b_SSIInit == 1) {

				switch (b_ReadType) {

				case APCI1710_SSI_READ1VALUE:
		 /****************************************/
					/* Test the selected SSI counter number */
		 /****************************************/

					if (b_SelectedSSI < 3) {
		    /************************/
						/* Start the conversion */
		    /************************/

						outl(0, devpriv->s_BoardInfos.
							ui_Address + 8 +
							(64 * b_ModulNbr));

						do {
		       /*******************/
							/* Read the status */
		       /*******************/

							dw_StatusReg =
								inl(devpriv->
								s_BoardInfos.
								ui_Address +
								(64 * b_ModulNbr));
						} while ((dw_StatusReg & 0x1)
							 != 0);

		    /******************************/
						/* Read the SSI counter value */
		    /******************************/

						dw_CounterValue =
							inl(devpriv->
							s_BoardInfos.
							ui_Address + 4 +
							(b_SelectedSSI * 4) +
							(64 * b_ModulNbr));

						b_Length =
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_SSIProfile / 2;

						if ((b_Length * 2) !=
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_SSIProfile) {
							b_Length++;
						}

						b_Schift =
							b_Length -
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_PositionTurnLength;

						*pul_Position1 =
							dw_CounterValue >>
							b_Schift;

						dw_And = 1;

						for (b_Cpt = 0;
							b_Cpt <
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_PositionTurnLength;
							b_Cpt++) {
							dw_And = dw_And * 2;
						}

						*pul_Position1 =
							*pul_Position1 &
							((dw_And) - 1);

						*pul_TurnCpt1 =
							dw_CounterValue >>
							b_Length;

						dw_And = 1;

						for (b_Cpt = 0;
							b_Cpt <
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_TurnCptLength;
							b_Cpt++) {
							dw_And = dw_And * 2;
						}

						*pul_TurnCpt1 =
							*pul_TurnCpt1 &
							((dw_And) - 1);
					} else {
		    /*****************************/
						/* The selected SSI is wrong */
		    /*****************************/

						DPRINTK("The selected SSI is wrong\n");
						i_ReturnValue = -5;
					}
					break;

				case APCI1710_SSI_READALLVALUE:
					dw_And1 = 1;

					for (b_Cpt = 0;
						b_Cpt <
						devpriv->
						s_ModuleInfo[b_ModulNbr].
						s_SSICounterInfo.
						b_PositionTurnLength; b_Cpt++) {
						dw_And1 = dw_And1 * 2;
					}

					dw_And2 = 1;

					for (b_Cpt = 0;
						b_Cpt <
						devpriv->
						s_ModuleInfo[b_ModulNbr].
						s_SSICounterInfo.
						b_TurnCptLength; b_Cpt++) {
						dw_And2 = dw_And2 * 2;
					}

		 /************************/
					/* Start the conversion */
		 /************************/

					outl(0, devpriv->s_BoardInfos.
						ui_Address + 8 +
						(64 * b_ModulNbr));

					do {
		    /*******************/
						/* Read the status */
		    /*******************/

						dw_StatusReg =
							inl(devpriv->
							s_BoardInfos.
							ui_Address +
							(64 * b_ModulNbr));
					} while ((dw_StatusReg & 0x1) != 0);

					for (b_SSICpt = 0; b_SSICpt < 3;
						b_SSICpt++) {
		    /******************************/
						/* Read the SSI counter value */
		    /******************************/

						dw_CounterValue =
							inl(devpriv->
							s_BoardInfos.
							ui_Address + 4 +
							(b_SSICpt * 4) +
							(64 * b_ModulNbr));

						b_Length =
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_SSIProfile / 2;

						if ((b_Length * 2) !=
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_SSIProfile) {
							b_Length++;
						}

						b_Schift =
							b_Length -
							devpriv->
							s_ModuleInfo
							[b_ModulNbr].
							s_SSICounterInfo.
							b_PositionTurnLength;

						pul_Position[b_SSICpt] =
							dw_CounterValue >>
							b_Schift;
						pul_Position[b_SSICpt] =
							pul_Position[b_SSICpt] &
							((dw_And1) - 1);

						pul_TurnCpt[b_SSICpt] =
							dw_CounterValue >>
							b_Length;
						pul_TurnCpt[b_SSICpt] =
							pul_TurnCpt[b_SSICpt] &
							((dw_And2) - 1);
					}
					break;

				default:
					printk("Read Type Inputs Wrong\n");

				}	/*  switch  ending */

			} else {
int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
	struct comedi_insn *insn, unsigned int *data)
{
	int i_ReturnValue = 0;
	unsigned int ui_TimerValue;
	unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
		b_PCIInputClock, b_SSICountingMode;
	unsigned int ul_SSIOutputClock;

	b_ModulNbr = CR_AREF(insn->chanspec);
	b_SSIProfile = (unsigned char) data[0];
	b_PositionTurnLength = (unsigned char) data[1];
	b_TurnCptLength = (unsigned char) data[2];
	b_PCIInputClock = (unsigned char) data[3];
	ul_SSIOutputClock = (unsigned int) data[4];
	b_SSICountingMode = (unsigned char) data[5];

	i_ReturnValue = insn->n;
	/**************************/
	/* Test the module number */
	/**************************/

	if (b_ModulNbr < 4) {
	   /***********************/
		/* Test if SSI counter */
	   /***********************/

		if ((devpriv->s_BoardInfos.
				dw_MolduleConfiguration[b_ModulNbr] &
				0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
	      /*******************************/
			/* Test the SSI profile length */
	      /*******************************/

			/*  CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */
			if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
		 /*************************************/
				/* Test the SSI position data length */
		 /*************************************/

				if (b_PositionTurnLength > 0
					&& b_PositionTurnLength < 32) {
		    /*****************************************/
					/* Test the SSI turn counter data length */
		    /*****************************************/

					if (b_TurnCptLength > 0
						&& b_TurnCptLength < 32) {
		       /***************************/
						/* Test the profile length */
		       /***************************/

						if ((b_TurnCptLength +
								b_PositionTurnLength)
							<= b_SSIProfile) {
			  /****************************/
							/* Test the PCI input clock */
			  /****************************/

							if (b_PCIInputClock ==
								APCI1710_30MHZ
								||
								b_PCIInputClock
								==
								APCI1710_33MHZ)
							{
			     /*************************/
								/* Test the output clock */
			     /*************************/

								if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
									if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
				   /**********************/
										/* Save configuration */
				   /**********************/
										devpriv->
											s_ModuleInfo
											[b_ModulNbr].
											s_SSICounterInfo.
											b_SSIProfile
											=
											b_SSIProfile;

										devpriv->
											s_ModuleInfo
											[b_ModulNbr].
											s_SSICounterInfo.
											b_PositionTurnLength
											=
											b_PositionTurnLength;

										devpriv->
											s_ModuleInfo
											[b_ModulNbr].
											s_SSICounterInfo.
											b_TurnCptLength
											=
											b_TurnCptLength;

				   /*********************************/
										/* Initialise the profile length */
				   /*********************************/

										if (b_SSICountingMode == APCI1710_BINARY_MODE) {

											outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
										} else {

											outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
										}

				   /******************************/
										/* Calculate the output clock */
				   /******************************/

										ui_TimerValue
											=
											(unsigned int)
											(
											((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);

				   /************************/
										/* Initialise the timer */
				   /************************/

										outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));

				   /********************************/
										/* Initialise the counting mode */
				   /********************************/

										outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));

										devpriv->
											s_ModuleInfo
											[b_ModulNbr].
											s_SSICounterInfo.
											b_SSIInit
											=
											1;
									} else {
				   /*****************************************************/
										/* The selected SSI counting mode parameter is wrong */
				   /*****************************************************/

										DPRINTK("The selected SSI counting mode parameter is wrong\n");
										i_ReturnValue
											=
											-9;
									}
								} else {
				/******************************************/
									/* The selected SSI output clock is wrong */
				/******************************************/

									DPRINTK("The selected SSI output clock is wrong\n");
									i_ReturnValue
										=
										-8;
								}
							} else {
			     /*****************************************/
								/* The selected PCI input clock is wrong */
			     /*****************************************/

								DPRINTK("The selected PCI input clock is wrong\n");
								i_ReturnValue =
									-7;
							}
						} else {
			  /********************************************/
							/* The selected SSI profile length is wrong */
			  /********************************************/

							DPRINTK("The selected SSI profile length is wrong\n");
							i_ReturnValue = -4;
						}
					} else {
		       /******************************************************/
						/* The selected SSI turn counter data length is wrong */
		       /******************************************************/

						DPRINTK("The selected SSI turn counter data length is wrong\n");
						i_ReturnValue = -6;
					}
				} else {
		    /**************************************************/
					/* The selected SSI position data length is wrong */
		    /**************************************************/

					DPRINTK("The selected SSI position data length is wrong\n");
					i_ReturnValue = -5;
				}
			} else {
		 /********************************************/
				/* The selected SSI profile length is wrong */
		 /********************************************/

				DPRINTK("The selected SSI profile length is wrong\n");
				i_ReturnValue = -4;
			}
		} else {
	      /**********************************/
			/* The module is not a SSI module */
	      /**********************************/

			DPRINTK("The module is not a SSI module\n");
			i_ReturnValue = -3;
		}
	} else {
	   /***********************/
		/* Module number error */
	   /***********************/

		DPRINTK("Module number error\n");
		i_ReturnValue = -2;
	}

	return i_ReturnValue;
}