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; }