📄 hwdrv_apci3120.c
字号:
outw(APCI3120_ADD_ON_MWAR_HIGH,devpriv->i_IobaseAddon+0); outw((devpriv->ul_DmaBufferHw[0]/65536),devpriv->i_IobaseAddon+2); //4 // amount of bytes to be transfered set transfer count // used ADDON MWTC register //commented testing outl(devpriv->ui_DmaBufferUsesize[0], devpriv->i_IobaseAddon+AMCC_OP_REG_AMWTC); /**************************/ /* Nbr of acquisition LOW */ /**************************/ outw(APCI3120_ADD_ON_MWTC_LOW,devpriv->i_IobaseAddon + 0); outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF),devpriv->i_IobaseAddon + 2); /***************************/ /* Nbr of acquisition HIGH */ /***************************/ outw(APCI3120_ADD_ON_MWTC_HIGH,devpriv->i_IobaseAddon + 0); outw((devpriv->ui_DmaBufferUsesize[0]/65536),devpriv->i_IobaseAddon + 2); //5 // To configure A2P FIFO // testing outl( FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); /******************/ /* A2P FIFO RESET */ /******************/ // TO VERIFY //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver outl(0x04000000UL, devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR); //END JK 07.05.04: Comparison between WIN32 and Linux driver //6 //ENABLE A2P FIFO WRITE AND ENABLE AMWEN // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver //outw(3,devpriv->i_IobaseAddon + 4); //END JK 07.05.04: Comparison between WIN32 and Linux driver //7 //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) /***************************************************/ /* A2P FIFO CONFIGURATE, END OF DMA INTERRUPT INIT */ /***************************************************/ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver /******************************************/ /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ /******************************************/ outw(3,devpriv->i_IobaseAddon + 4); //END JK 07.05.04: Comparison between WIN32 and Linux driver /******************/ /* A2P FIFO RESET */ /******************/ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver outl(0x04000000UL, devpriv->i_IobaseAmcc+APCI3120_AMCC_OP_MCSR); //END JK 07.05.04: Comparison between WIN32 and Linux driver } if ((devpriv->us_UseDma==APCI3120_DISABLE) && !devpriv->b_AiContinuous) { // set gate 2 to start conversion devpriv->us_OutputRegister = devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); } switch(mode) { case 1: // set gate 0 to start conversion devpriv->us_OutputRegister = devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); break; case 2: // set gate 0 and gate 1 devpriv->us_OutputRegister= devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1; devpriv->us_OutputRegister= devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); break; } return 0;}/*+----------------------------------------------------------------------------+| INTERNAL FUNCTIONS |+----------------------------------------------------------------------------+*//*+----------------------------------------------------------------------------+| Function name : int i_APCI3120_Reset(comedi_device *dev) || || |+----------------------------------------------------------------------------+| Task : Hardware reset function || |+----------------------------------------------------------------------------+| Input Parameters : comedi_device *dev || || |+----------------------------------------------------------------------------+| Return Value : || |+----------------------------------------------------------------------------+*/int i_APCI3120_Reset(comedi_device *dev){ unsigned int i; unsigned short us_TmpValue; devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE; devpriv->b_EocEosInterrupt=APCI3120_DISABLE; devpriv->b_InterruptMode=APCI3120_EOC_MODE; devpriv->ui_EocEosConversionTime=0; // set eoc eos conv time to 0 devpriv->b_OutputMemoryStatus =0; // variables used in timer subdevice devpriv->b_Timer2Mode=0; devpriv->b_Timer2Interrupt=0; devpriv->b_ExttrigEnable=0; // Disable ext trigger /* Disable all interrupts, watchdog for the anolog output */ devpriv->b_ModeSelectRegister=0; outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT); // Disables all counters, ext trigger and clears PA, PR devpriv->us_OutputRegister=0; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); //Code to set the all anolog o/p channel to 0v //8191 is decimal value for zero(0 v)volt in bipolar mode(default) outw(8191|APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 1 outw(8191|APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 2 outw(8191|APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 3 outw(8191|APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 4 outw(8191|APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 5 outw(8191|APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 6 outw(8191|APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 7 outw(8191|APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 8 // Reset digital output to L0W //ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); udelay(10); inw(dev->iobase+0); //make a dummy read inb(dev->iobase+APCI3120_RESET_FIFO); // flush FIFO inw(dev->iobase+APCI3120_RD_STATUS); // flush A/D status register //code to reset the RAM sequence for (i=0;i<16;i++) { us_TmpValue = i<<8; //select the location outw(us_TmpValue,dev->iobase+APCI3120_SEQ_RAM_ADDRESS); } return 0;}/*+----------------------------------------------------------------------------+| Function name : int i_APCI3120_SetupChannelList(comedi_device * dev, || comedi_subdevice * s, int n_chan,unsigned int *chanlist|| ,char check) || |+----------------------------------------------------------------------------+| Task :This function will first check channel list is ok or not||and then initialize the sequence RAM with the polarity, Gain,Channel number ||If the last argument of function "check"is 1 then it only checks the channel||list is ok or not. || |+----------------------------------------------------------------------------+| Input Parameters : comedi_device * dev || comedi_subdevice * s || int n_chan | unsigned int *chanlist char check+----------------------------------------------------------------------------+| Return Value : || |+----------------------------------------------------------------------------+*/int i_APCI3120_SetupChannelList(comedi_device * dev, comedi_subdevice * s, int n_chan, unsigned int *chanlist,char check) { unsigned int i;//, differencial=0, bipolar=0; unsigned int gain; unsigned short us_TmpValue; /* correct channel and range number check itself comedi/range.c */ if (n_chan<1) { if (!check) comedi_error(dev,"range/channel list is empty!"); return 0; } // All is ok, so we can setup channel/range list if (check) return 1; //Code to set the PA and PR...Here it set PA to 0.. devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; devpriv->us_OutputRegister= ((n_chan-1) & 0xf)<<8; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); for (i=0; i<n_chan; i++) { // store range list to card us_TmpValue=CR_CHAN(chanlist[i]); // get channel number; if (CR_RANGE(chanlist[i])<APCI3120_BIPOLAR_RANGES) { us_TmpValue&=((~APCI3120_UNIPOLAR)&0xff); // set bipolar } else { us_TmpValue|=APCI3120_UNIPOLAR; // enable unipolar...... } gain=CR_RANGE(chanlist[i]); // get gain number us_TmpValue|=((gain & 0x03)<<4); //<<4 for G0 and G1 bit in RAM us_TmpValue|= i<<8; //To select the RAM LOCATION.... outw(us_TmpValue,dev->iobase+APCI3120_SEQ_RAM_ADDRESS); printk ("\n Gain = %i", (((unsigned char) CR_RANGE(chanlist[i]) & 0x03) << 2)); printk ("\n Channel = %i", CR_CHAN(chanlist[i])); printk ("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR); } return 1; // we can serve this with scan logic}/*+----------------------------------------------------------------------------+| Function name : int i_APCI3120_ExttrigEnable(comedi_device * dev) || || |+----------------------------------------------------------------------------+| Task : Enable the external trigger || |+----------------------------------------------------------------------------+| Input Parameters : comedi_device * dev || || |+----------------------------------------------------------------------------+| Return Value : 0 || |+----------------------------------------------------------------------------+*/int i_APCI3120_ExttrigEnable(comedi_device * dev){ devpriv->us_OutputRegister|=APCI3120_ENABLE_EXT_TRIGGER; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); return 0;}/*+----------------------------------------------------------------------------+| Function name : int i_APCI3120_ExttrigDisable(comedi_device * dev) || |+----------------------------------------------------------------------------+| Task : Disables the external trigger || |+----------------------------------------------------------------------------+| Input Parameters : comedi_device * dev || || |+----------------------------------------------------------------------------+| Return Value : 0 || |+----------------------------------------------------------------------------+*/int i_APCI3120_ExttrigDisable(comedi_device * dev){ devpriv->us_OutputRegister&=~APCI3120_ENABLE_EXT_TRIGGER; outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS); return 0;}/*+----------------------------------------------------------------------------+| INTERRUPT FUNCTIONS |+----------------------------------------------------------------------------+*//*+----------------------------------------------------------------------------+| Function name : void v_APCI3120_Interrupt(int irq, void *d, | | struct pt_regs *regs) || || |+----------------------------------------------------------------------------+| Task :Interrupt handler for APCI3120 || When interrupt occurs this gets called. || First it finds which interrupt has been generated and | | handles corresponding interrupt || |+----------------------------------------------------------------------------+| Input Parameters : int irq || void *d || struct pt_regs *regs || |+----------------------------------------------------------------------------+| Return Value : void || |+----------------------------------------------------------------------------+*/ void v_APCI3120_Interrupt(int irq, void *d, struct pt_regs *regs) { comedi_device *dev = d; USHORT int_daq; unsigned int int_amcc,ui_Check,i; USHORT us_TmpValue; BYTE b_DummyRead; comedi_subdevice *s = dev->subdevices + 0; ui_Check=1; int_daq=inw(dev->iobase+APCI3120_RD_STATUS) & 0xf000; // get IRQ reasons int_amcc=inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); // get AMCC INT register
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -