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

📄 me_daq.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    printk("comedi%d: Cannot get single value\n", dev->minor);    return -EIO;  }  /* stop any running conversion */  dev_private->control_1 &= 0xFFFC;  writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);  return 1;}// ------------------------------------------------------------------//// HARDWARE TRIGGERED ANALOG INPUT SECTION//// ------------------------------------------------------------------//// Cancel analog input autoscan//static int me_ai_cancel(comedi_device *dev,                        comedi_subdevice *s){  /* disable interrupts */  /* stop any running conversion */  dev_private->control_1 &= 0xFFFC;  writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);  return 0;}//// Test analog input command//static int me_ai_do_cmd_test(comedi_device *dev,                             comedi_subdevice *s,                             comedi_cmd *cmd){  return 0;}//// Analog input command//static int me_ai_do_cmd(comedi_device *dev,                        comedi_subdevice *subdevice){  return 0;}// ------------------------------------------------------------------//// ANALOG OUTPUT SECTION//// ------------------------------------------------------------------//// Analog instant output//static int me_ao_insn_write(comedi_device *dev,                            comedi_subdevice *s,                            comedi_insn *insn,                            lsampl_t *data){  int chan;  int rang;  int i;  /* Enable all DAC */  dev_private->control_2 |= ENABLE_DAC;  writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);  /* and set DAC to "buffered" mode */  dev_private->control_2 |= BUFFERED_DAC;  writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);  /* Set dac-control register */  for (i=0; i < insn->n; i++)  {    chan = CR_CHAN((&insn->chanspec)[i]);    rang = CR_RANGE((&insn->chanspec)[i]);    dev_private->dac_control &= ~(0x0880 >> chan); /* clear bits for this channel */    if (rang == 0)      dev_private->dac_control |= ((DAC_BIPOLAR_A | DAC_GAIN_1_A) >> chan);    else if (rang == 1)      dev_private->dac_control |= ((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);  }  writew(dev_private->dac_control, dev_private->me_regbase + ME_DAC_CONTROL);  /* Update dac-control register */  readw(dev_private->me_regbase + ME_DAC_CONTROL_UPDATE);  /* Set data register */  for (i=0; i < insn->n; i++)  {    chan = CR_CHAN((&insn->chanspec)[i]);    writew((data[0] & s->maxdata), dev_private->me_regbase + ME_DAC_DATA_A + (chan<<1));    dev_private->ao_readback[chan] = (data[0] & s->maxdata);  }  /* Update dac with data registers */  readw(dev_private->me_regbase + ME_DAC_UPDATE);  return i;}//// Analog output readback//static int me_ao_insn_read(comedi_device * dev,                           comedi_subdevice *s,                           comedi_insn *insn,                           lsampl_t *data){  int i;  for (i=0; i < insn->n; i++)  {    data[i] = dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])];  }  return 1;}// ------------------------------------------------------------------//// INITIALISATION SECTION//// ------------------------------------------------------------------//// Xilinx firmware download for card: ME-2600i//static int me2600_xilinx_download(comedi_device *dev, unsigned char	*me2600_firmware, unsigned int length){  unsigned int value;  unsigned int file_length;  unsigned int i;  /* disable irq's on PLX */  writel(0x00, dev_private->plx_regbase + PLX_INTCSR);  /* First, make a dummy read to reset xilinx */  value = readw(dev_private->me_regbase + XILINX_DOWNLOAD_RESET);  /* Wait until reset is over */  sleep(1);  /* Write a dummy value to Xilinx */  writeb(0x00, dev_private->me_regbase + 0x0);  sleep(1);  /*   * Format of the firmware   * Build longs from the byte-wise coded header   * Byte 1-3:   length of the array   * Byte 4-7:   version   * Byte 8-11:  date   * Byte 12-15: reserved   */  if(length<16)return -EINVAL;  file_length =    (((unsigned int)me2600_firmware[0] & 0xff)<<24) +    (((unsigned int)me2600_firmware[1] & 0xff)<<16) +    (((unsigned int)me2600_firmware[2] & 0xff)<< 8) +    ((unsigned int)me2600_firmware[3] & 0xff);  /*   * Loop for writing firmware byte by byte to xilinx   * Firmware data start at offfset 16   */  for(i = 0; i < file_length; i++)  {    writeb((me2600_firmware[16+i] & 0xff), dev_private->me_regbase + 0x0);  }  /* Write 5 dummy values to xilinx */  for(i = 0; i < 5; i++)  {    writeb(0x00, dev_private->me_regbase + 0x0);  }  /* Test if there was an error during download -> INTB was thrown */  value = readl(dev_private->plx_regbase + PLX_INTCSR);  if(value & 0x20)  {    /* Disable interrupt */    writel(0x00, dev_private->plx_regbase + PLX_INTCSR);    printk("comedi%d: Xilinx download failed\n", dev->minor);    return -EIO;  }  /* Wait until the Xilinx is ready for real work */  sleep(1);  /* Enable PLX-Interrupts */  writel(0x43, dev_private->plx_regbase + PLX_INTCSR);  return 0;}//// Reset device//static int me_reset(comedi_device *dev){  /* Reset board */  writew(0x00, dev_private->me_regbase + ME_CONTROL_1);  writew(0x00, dev_private->me_regbase + ME_CONTROL_2);  writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);  writew(0x00, dev_private->me_regbase + ME_DAC_CONTROL);  /* Save values in the board context */  dev_private->dac_control = 0;  dev_private->control_1 = 0;  dev_private->control_2 = 0;  return 0;}//// Attach////  - Register PCI device//  - Declare device driver capability//static int me_attach(comedi_device *dev,comedi_devconfig *it){  struct pci_dev* pci_device;  comedi_subdevice *subdevice;  me_board_struct* board;  unsigned int plx_regbase_tmp;  unsigned int plx_regbase_size_tmp;  unsigned int me_regbase_tmp;  unsigned int me_regbase_size_tmp;  unsigned int swap_regbase_tmp;  unsigned int swap_regbase_size_tmp;  unsigned int regbase_tmp;  int result, error, i;//// Probe the device to determine what device in the series it is.//  pci_for_each_dev(pci_device)  {    if(pci_device->vendor == PCI_VENDOR_ID_MEILHAUS)    {      for(i = 0; i < me_board_nbr; i++)      {        if(me_boards[i].device_id == pci_device->device)        {          // was a particular bus/slot requested?          if((it->options[0] != 0) || (it->options[1] != 0))          {            // are we on the wrong bus/slot?            if(pci_device->bus->number != it->options[0] ||               PCI_SLOT(pci_device->devfn) != it->options[1])            {              continue;            }          }          dev->board_ptr = me_boards + i;          board = (me_board_struct *) dev->board_ptr;          goto found;        }      }    }  }  printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",         dev->minor,it->options[0], it->options[1]);  return -EIO;found:  printk("comedi%d: found %s at PCI bus %d, slot %d\n",         dev->minor, me_boards[i].name,         pci_device->bus->number, PCI_SLOT(pci_device->devfn));  // Allocate private memory  if(alloc_private(dev,sizeof(me_private_data_struct)) < 0)    return -ENOMEM;  // Set data in device structure  dev->board_name = board->name;  dev_private->pci_device = pci_device;  // Read PLX register base address [PCI_BASE_ADDRESS #0].  plx_regbase_tmp = pci_resource_start(pci_device, 0);  plx_regbase_size_tmp = pci_resource_end(pci_device, 0) - plx_regbase_tmp + 1;  if(plx_regbase_tmp & PCI_BASE_ADDRESS_SPACE)  {    printk("comedi%d: PLX space is not MEM\n", dev->minor);    return -EIO;  }  // Read Swap base address [PCI_BASE_ADDRESS #5].  swap_regbase_tmp = pci_resource_start(pci_device, 5);  swap_regbase_size_tmp = pci_resource_end(pci_device, 5) - swap_regbase_tmp + 1;  if(!swap_regbase_tmp)  {    printk("comedi%d: Swap not present\n", dev->minor);  }  /*----------------------------------------------------- Workaround start ---*/  if(plx_regbase_tmp & 0x0080)  {    printk("comedi%d: PLX-Bug detected\n", dev->minor);    if(swap_regbase_tmp)    {      regbase_tmp = plx_regbase_tmp;      plx_regbase_tmp = swap_regbase_tmp;      swap_regbase_tmp = regbase_tmp;      result = pci_write_config_dword(pci_device, PCI_BASE_ADDRESS_0, plx_regbase_tmp);      if(result != PCIBIOS_SUCCESSFUL)        return -EIO;      result = pci_write_config_dword(pci_device, PCI_BASE_ADDRESS_5, swap_regbase_tmp);      if(result != PCIBIOS_SUCCESSFUL)        return -EIO;    }    else    {      plx_regbase_tmp -= 0x80;      result = pci_write_config_dword(pci_device, PCI_BASE_ADDRESS_0, plx_regbase_tmp);      if(result != PCIBIOS_SUCCESSFUL)        return -EIO;    }  }  /*----------------------------------------------------- Workaround end -----*/  plx_regbase_tmp &= PCI_BASE_ADDRESS_MEM_MASK;  dev_private->plx_regbase_size = plx_regbase_size_tmp;  dev_private->plx_regbase = (unsigned int) ioremap(plx_regbase_tmp, plx_regbase_size_tmp);  // Read Meilhaus register base address [PCI_BASE_ADDRESS #2].  me_regbase_tmp = pci_resource_start(pci_device, 2);  me_regbase_size_tmp = pci_resource_end(pci_device, 2) - me_regbase_tmp + 1;  if(me_regbase_tmp & PCI_BASE_ADDRESS_SPACE)  {    printk("comedi%d: Meilhaus space is not MEM\n", dev->minor);    return -EIO;  }  me_regbase_tmp &= PCI_BASE_ADDRESS_MEM_MASK;  dev_private->me_regbase_size = me_regbase_size_tmp;  dev_private->me_regbase = (unsigned int) ioremap(me_regbase_tmp, me_regbase_size_tmp);  // Download firmware and reset card  if(board->device_id == ME2600_DEVICE_ID)  {    unsigned char *aux_data;    int aux_len;    aux_data = (unsigned char *)it->options[COMEDI_DEVCONF_AUX_DATA];    aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];    if(!aux_data || aux_len)return -EINVAL;    me2600_xilinx_download(dev, aux_data, aux_len);  }  me_reset(dev);  // device driver capabilities  if((error = alloc_subdevices(dev, 3)) < 0)    return error;  subdevice = dev->subdevices + 0;  subdevice->type         = COMEDI_SUBD_AI;  subdevice->subdev_flags = SDF_READABLE | SDF_COMMON;  subdevice->n_chan       = board->ai_channel_nbr;  subdevice->maxdata      = board->ai_resolution_mask;  subdevice->len_chanlist = board->ai_channel_nbr;  subdevice->range_table  = board->ai_range_list;  subdevice->cancel       = me_ai_cancel;  subdevice->insn_read    = me_ai_insn_read;  subdevice->do_cmdtest   = me_ai_do_cmd_test;  subdevice->do_cmd       = me_ai_do_cmd;  subdevice = dev->subdevices + 1;  subdevice->type         = COMEDI_SUBD_AO;  subdevice->subdev_flags = SDF_WRITEABLE | SDF_COMMON;  subdevice->n_chan       = board->ao_channel_nbr;  subdevice->maxdata      = board->ao_resolution_mask;  subdevice->len_chanlist = board->ao_channel_nbr;  subdevice->range_table  = board->ao_range_list;  subdevice->insn_read    = me_ao_insn_read;  subdevice->insn_write   = me_ao_insn_write;  subdevice = dev->subdevices + 2;  subdevice->type         = COMEDI_SUBD_DIO;  subdevice->subdev_flags = SDF_READABLE | SDF_WRITEABLE;  subdevice->n_chan       = board->dio_channel_nbr;  subdevice->maxdata      = 1;  subdevice->len_chanlist = board->dio_channel_nbr;  subdevice->range_table  = &range_digital;  subdevice->insn_bits    = me_dio_insn_bits;  subdevice->insn_config  = me_dio_insn_config;  subdevice->io_bits      = 0;  printk("comedi%d: " ME_DRIVER_NAME " attached.\n", dev->minor);  return 0;}//// Detach//static int me_detach(comedi_device *dev){  me_reset(dev);  return 0;}

⌨️ 快捷键说明

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