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

📄 daqboard2000.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      //comedi_udelay(2);    }    data[i] = fpga->acqResultsFIFO;    fpga->acqControl = DAQBOARD2000_AdcPacerDisable;    fpga->acqControl = DAQBOARD2000_SeqStopScanList;  }  return i;}static int daqboard2000_ao_insn_read(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){  int i;  int chan = CR_CHAN(insn->chanspec);  for(i=0;i<insn->n;i++){    data[i]=devpriv->ao_readback[chan];  }  return i;}static int daqboard2000_ao_insn_write(comedi_device *dev, comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){  int i;  int chan = CR_CHAN(insn->chanspec);  daqboard2000_hw *fpga = devpriv->daq;  int timeout;  for(i=0;i<insn->n;i++){    /*       * OK, since it works OK without enabling the DAC's, let's keep     * it as simple as possible...     */    //fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; comedi_udelay(1000);    fpga->dacSetting[chan] = data[i];    for (timeout = 0 ; timeout < 20 ; timeout++) {      if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) { break; }      //comedi_udelay(2);    }    devpriv->ao_readback[chan] = data[i];  /*     * Since we never enabled the DAC's, we don't need to disable it...   * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; comedi_udelay(1000);   */  }  return i;}static void daqboard2000_resetLocalBus(comedi_device *dev){  printk("daqboard2000_resetLocalBus\n");  writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);  comedi_udelay(10000);  writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);  comedi_udelay(10000);}static void daqboard2000_reloadPLX(comedi_device *dev){  printk("daqboard2000_reloadPLX\n");  writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);  comedi_udelay(10000);  writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);  comedi_udelay(10000);  writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);  comedi_udelay(10000);}static void daqboard2000_pulseProgPin(comedi_device *dev){  printk("daqboard2000_pulseProgPin 1\n");  writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);  comedi_udelay(10000);  writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);  comedi_udelay(10000); /* Not in the original code, but I like symmetry... */}static int daqboard2000_pollCPLD(comedi_device *dev, int mask) {  int result = 0;  int i;  int cpld;  /* timeout after 50 tries -> 5ms */  for (i = 0 ; i < 50 ; i++) {    cpld = readw(devpriv->daq + 0x1000);    if ((cpld & mask) == mask){      result=1;      break;    }    comedi_udelay(100);  }  comedi_udelay(5);  return result;}static int daqboard2000_writeCPLD(comedi_device *dev, int data){  int result = 0;  comedi_udelay(10);  writew(data, devpriv->daq + 0x1000);  if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==       DAQBOARD2000_CPLD_INIT) {    result = 1;  }  return result;}static int initialize_daqboard2000(comedi_device *dev,	unsigned char *cpld_array,int len){  int result = -EIO;  /* Read the serial EEPROM control register */  int secr;  int retry;  int i;  /* Check to make sure the serial eeprom is present on the board */  secr = readl(devpriv->plx + 0x6c);   if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) {#ifdef DEBUG_EEPROM    printk("no serial eeprom\n");#endif    return -EIO;  }  for (retry = 0 ; retry < 3 ; retry++) {#ifdef DEBUG_EEPROM    printk("Programming EEPROM try %x\n", retry);#endif    daqboard2000_resetLocalBus(dev);    daqboard2000_reloadPLX(dev);    daqboard2000_pulseProgPin(dev);    if(daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {      for (i = 0 ; i < len ; i++) {        if (cpld_array[i] == 0xff && cpld_array[i+1] == 0x20) { #ifdef DEBUG_EEPROM          printk("Preamble found at %d\n", i);#endif	  break; 	}      }      for ( ; i < len ; i += 2) {        int data = (cpld_array[i]<<8) + cpld_array[i+1];	if (!daqboard2000_writeCPLD(dev, data)) {	  break;	}      }      if (i >= len) {#ifdef DEBUG_EEPROM        printk("Programmed\n");#endif	daqboard2000_resetLocalBus(dev);	daqboard2000_reloadPLX(dev);	result = 0;	break;      }    }  }  return result;}static void daqboard2000_adcStopDmaTransfer(comedi_device *dev){/*  printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/}static void daqboard2000_adcDisarm(comedi_device *dev){  daqboard2000_hw *fpga = devpriv->daq;  /* Disable hardware triggers */    comedi_udelay(2);  fpga->trigControl = DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable;  comedi_udelay(2);  fpga->trigControl = DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable;   /* Stop the scan list FIFO from loading the configuration pipe */  comedi_udelay(2);  fpga->acqControl = DAQBOARD2000_SeqStopScanList;  /* Stop the pacer clock */  comedi_udelay(2);  fpga->acqControl = DAQBOARD2000_AdcPacerDisable;      /* Stop the input dma (abort channel 1) */  daqboard2000_adcStopDmaTransfer(dev);}static void daqboard2000_activateReferenceDacs(comedi_device *dev){  daqboard2000_hw *fpga = devpriv->daq;  int timeout;  // Set the + reference dac value in the FPGA  fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect;  for (timeout = 0 ; timeout < 20 ; timeout++) {    if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) { break; }    comedi_udelay(2);  }/*  printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/  // Set the - reference dac value in the FPGA  fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect;  for (timeout = 0 ; timeout < 20 ; timeout++) {    if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) { break; }    comedi_udelay(2);  }/*  printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/}static void daqboard2000_initializeCtrs(comedi_device *dev){/*  printk("Implement: daqboard2000_initializeCtrs\n");*/}static void daqboard2000_initializeTmrs(comedi_device *dev){/*  printk("Implement: daqboard2000_initializeTmrs\n");*/}static void daqboard2000_dacDisarm(comedi_device *dev){/*  printk("Implement: daqboard2000_dacDisarm\n");*/}static void daqboard2000_initializeAdc(comedi_device *dev){  daqboard2000_adcDisarm(dev);  daqboard2000_activateReferenceDacs(dev);  daqboard2000_initializeCtrs(dev);  daqboard2000_initializeTmrs(dev);}static void daqboard2000_initializeDac(comedi_device *dev){  daqboard2000_dacDisarm(dev);}/*The test command, REMOVE!!:rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sbin/comedi_config /dev/comedi0 daqboard/2000 ; tail -40 /var/log/messages*/static int daqboard2000_8255_cb(int dir, int port, int data, unsigned long ioaddr){  int result = 0;  if(dir){    writew(data,ioaddr+port*2);    result = 0;  }else{    result = readw(ioaddr+port*2);  }/*  printk("daqboard2000_8255_cb %x %d %d %2.2x -> %2.2x\n",        arg, dir, port, data, result);*/  return result;}static int daqboard2000_attach(comedi_device *dev, comedi_devconfig *it){  int result = 0;  comedi_subdevice *s;  struct pci_dev *card = NULL;  void *aux_data;  unsigned int aux_len;  printk("comedi%d: daqboard2000:", dev->minor);  if(!pci_present()) {    printk(" PCI bus not present!\n");    result = -EIO;    goto out;  }  /* FIXME: we should handle multiple cards, have to make David decide             how, so we will be consistent among all PCI card drivers... */  card = pci_find_device(0x1616, 0x0409, NULL);  if (!card) {    printk(" no daqboard2000 found\n");    result = -EIO;    goto out;  }  if((result = pci_enable_device(card))<0){    goto out;  }  if (card->hdr_type == PCI_HEADER_TYPE_NORMAL) {    u32 id;    int i;    pci_read_config_dword(card, PCI_SUBSYSTEM_VENDOR_ID, &id);    for(i=0;i<n_boardtypes;i++){      if(boardtypes[i].id==id){	printk(" %s",boardtypes[i].name);	dev->board_ptr=boardtypes+i;      }    }    if(!dev->board_ptr){      printk(" unknown subsystem id %08x (pretend it is an ids2)",id);      dev->board_ptr=boardtypes;    }  }else{    printk(" abnormal pci header type !?!?\n");    result=-EIO;    goto out;  }    result = alloc_private(dev,sizeof(daqboard2000_private));  if(result<0)goto out;  result = alloc_subdevices(dev, 3);  if(result<0)goto out;    devpriv->plx = ioremap(pci_resource_start(card,0), DAQBOARD2000_PLX_SIZE);  devpriv->daq = ioremap(pci_resource_start(card,2), DAQBOARD2000_DAQ_SIZE);  readl(devpriv->plx + 0x6c);   /*    u8 interrupt;    Windows code does restore interrupts, but since we don't use them...    pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);    printk("Interrupt before is: %x\n", interrupt);  */  aux_data = (void *)it->options[COMEDI_DEVCONF_AUX_DATA];  aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];  if(aux_data && aux_len){    result = initialize_daqboard2000(dev, aux_data, aux_len);  }else{    printk("no FPGA initialization code, aborting\n");    result=-EIO;  }  if(result<0)goto out;  daqboard2000_initializeAdc(dev);  daqboard2000_initializeDac(dev);  /*    Windows code does restore interrupts, but since we don't use them...    pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);    printk("Interrupt after is: %x\n", interrupt);  */  dev->iobase = (int)devpriv->daq;      dev->board_name = this_board->name;  s = dev->subdevices + 0;  /* ai subdevice */  s->type = COMEDI_SUBD_AI;  s->subdev_flags = SDF_READABLE|SDF_GROUND;  s->n_chan = 24;  s->maxdata = 0xffff;  s->insn_read = daqboard2000_ai_insn_read;  s->range_table = &range_daqboard2000_ai;  s = dev->subdevices + 1;  /* ao subdevice */  s->type = COMEDI_SUBD_AO;  s->subdev_flags = SDF_WRITABLE;  s->n_chan = 2;  s->maxdata = 0xffff;  s->insn_read = daqboard2000_ao_insn_read;  s->insn_write = daqboard2000_ao_insn_write;  s->range_table = &range_daqboard2000_ao;  s = dev->subdevices + 2;  result = subdev_8255_init(dev,s,daqboard2000_8255_cb,                           (unsigned long)(dev->iobase+0x40));    printk("\n");out:  return result;}static int daqboard2000_detach(comedi_device * dev){  printk("comedi%d: daqboard2000: remove\n", dev->minor);  if(dev->subdevices)    subdev_8255_cleanup(dev,dev->subdevices+2);  if (devpriv && devpriv->daq) {    iounmap(devpriv->daq);  }  if (devpriv && devpriv->plx) {    iounmap(devpriv->plx);  }  if (dev->irq) {    free_irq(dev->irq, dev);  }  return 0;}COMEDI_INITCLEANUP(driver_daqboard2000);

⌨️ 快捷键说明

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