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

📄 libvme.cpp

📁 linux下vme总线驱动代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------  //title: VMEBus Library for Universe Driver//version: Linux 1.1//date: April 1999//designer: Michael Wyrick                                                      //programmer: Michael Wyrick                                                    //company: Umbra System Inc.//platform: Linux 2.2.x, 2.4.x                                    //language: GCC 2.95, 3.0//module: //------------------------------------------------------------------------------  //  Purpose:                                                                    //  Docs:                                                                       //------------------------------------------------------------------------------  #include <stdio.h>#include <ctype.h>#include <fcntl.h>#include <unistd.h>#include <sys/ioctl.h>#include "universe.h"#include "libvme.h"// Internal constants only to libvme#define VME_CYCLE	      0x10#define VME_SIZE 	      0x60#define MODE_PROGRAMMED 0x01#define MODE_DMA        0x02#define VME_SUP_USR	    0x08#define VME_PRG_DATA    0x04#define MODE_PROGRAMMED 0x01#define MODE_DMA	      0x02#define DEBUG#undef DEBUG//-----------------------------------------------------------------------------// Function   : SwapEndian// Inputs     : any MultiByte type// Outputs    : a MultiByte type with the Bytes swapped// Description: Flip the Endianess of any Multibyte Type// Remarks    :// History    ://-----------------------------------------------------------------------------template<class T>T SwapEndian(T in){  T out;  int s = sizeof(T);  char *pin  = reinterpret_cast<char *>(&in);  char *pout = reinterpret_cast<char *>(&out);    for (int x=0;x<s;x++)    pout[x] = pin[(s-1)-x];  return out;}//-----------------------------------------------------------------------------// Function   : VMEBus construstor// Inputs     ://   addr      = VME Base Address to map//   count     = Size of mapping window//   space     = which VME address space the memory is in (i.e. user/data etc.)//   which_img = which of the four universe images to use// Outputs    :// Description://   Add a space description here//   if which_img is -1 then scan for and pick the next free image,//   only image 3 can be used for SUPERVISOR mappings// Remarks    :// History    ://-----------------------------------------------------------------------------VMEBus::VMEBus(unsigned int addr, int count, char space, int which_img){  int to   = 0;  int am   = 0;  int size = 0;  iSwapEndian = 1;  ctl = 0x00800000;  if (space & VME_SUPERVISOR)     // Only image can use supervisor space    which_img = 3;   if (which_img == -1) {  // Auto Image    if ((vme_handle = open("//dev//vme_m0",O_RDWR,0)) > 0) {      pci_base_addr  = 0xC0000000;    } else {      if ((vme_handle = open("//dev//vme_m1",O_RDWR,0)) > 0) {        pci_base_addr  = 0xC4000000;      } else {        if ((vme_handle = open("//dev//vme_m2",O_RDWR,0)) > 0) {          pci_base_addr  = 0xC8000000;        } else {          if ((vme_handle = open("//dev//vme_m3",O_RDWR,0)) > 0) {            pci_base_addr  = 0xCD000000;          }        }      }    }  } else {     switch (which_img) {  // Force Selected image      case 0 :        vme_handle = open("//dev//vme_m0",O_RDWR,0);        pci_base_addr  = 0xC0000000;        break;      case 1 :        vme_handle = open("//dev//vme_m1",O_RDWR,0);        pci_base_addr  = 0xC4000000;        break;      case 2 :        vme_handle = open("//dev//vme_m2",O_RDWR,0);        pci_base_addr  = 0xC8000000;        break;      case 3 :        vme_handle = open("//dev//vme_m3",O_RDWR,0);        pci_base_addr  = 0xCC000000;        break;    }  }  uni_handle = open("//dev//vme_ctl",O_RDWR,0);    if (vme_handle < 0) {    throw VME_DriverBusy();  }    if (uni_handle < 0) {    throw VME_DriverBusy();  }  size = space & VME_SIZE;    switch (size) {    case VME_SIZE_DO8:      ctl &= ~CTL_VDW;      ctl |= CTL_VDW_8;      break;      case VME_SIZE_D16:      ctl &= ~CTL_VDW;      ctl |= CTL_VDW_16;      break;      case VME_SIZE_D32:      ctl &= ~CTL_VDW;      ctl |= CTL_VDW_32;      break;      case VME_SIZE_D64:      ctl &= ~CTL_VDW;      ctl |= CTL_VDW_64;      break;    }    am = space & 0x03;	       if (space & VME_PRG_DATA) {    ctl |= CTL_PGM;  } else {    ctl &= ~CTL_PGM;  }		      if (space & VME_SUP_USR) {    ctl |= CTL_SUPER;  } else {    ctl &= ~CTL_SUPER;  }  if (space & VME_CYCLE) {    ctl |= CTL_VCT;  } else {    ctl &= ~CTL_VCT;  }  if (am == VME_A16) {    vme_space = am;    ctl &= ~CTL_VAS;    ctl |= CTL_VAS_A16;  } else if (am == VME_A24) {    vme_space = am;    ctl &= ~CTL_VAS;    ctl |= CTL_VAS_A24;  } else if (am == VME_A32) {    vme_space = am;    ctl &= ~CTL_VAS;    ctl |= CTL_VAS_A32;  } else if (am == VME_CR_CSR) {    vme_space = am;    ctl &= ~CTL_VAS;    ctl |= CTL_VAS_CR_CSR;  } else {    throw VME_InvalidMapping();  }  pci_bound_addr = pci_base_addr + (((count-1) / 0x10000)+1)*0x10000;  vme_base_addr  = addr;  to = -pci_base_addr + vme_base_addr;  ctl &= ~CTL_EN;    // Disable Slave  ioctl(vme_handle,IOCTL_SET_CTL,ctl);    ioctl(vme_handle,IOCTL_SET_TO,to);  ioctl(vme_handle,IOCTL_SET_BD,pci_bound_addr);  ioctl(vme_handle,IOCTL_SET_BS,pci_base_addr);  // Must set this after BD  ctl |= CTL_EN;     // Enable Slave  ioctl(vme_handle,IOCTL_SET_CTL,ctl);  if (space & VME_DMA_MODE)    ioctl(vme_handle,IOCTL_SET_MODE,MODE_DMA);    else    ioctl(vme_handle,IOCTL_SET_MODE,MODE_PROGRAMMED);}//-----------------------------------------------------------------------------// Function   : ~VMEBus// Inputs     : // Outputs    :// Description: Close handles to Universe Driver// Remarks    :// History    ://-----------------------------------------------------------------------------VMEBus::~VMEBus(){  close(vme_handle);  close(uni_handle);}//-----------------------------------------------------------------------------// Function   : ReadUniReg// Inputs     : //   int reg - Universe Register address to read// Outputs    : value of universe register// Description:// Remarks    : See Universe ca91c042 documentation for registers// History    ://-----------------------------------------------------------------------------unsigned int VMEBus::ReadUniReg(int reg){  unsigned int v;    lseek(uni_handle,reg,SEEK_SET);  read(uni_handle,&v,4);  return v;}//-----------------------------------------------------------------------------// Function   : WriteUniReg// Inputs     : //   int reg - Universe Register address to read//   uint v  - value to write to the register// Outputs    :// Description: Write a value to the universe register// Remarks    : See Universe ca91c042 documentation for registers// History    ://-----------------------------------------------------------------------------void VMEBus::WriteUniReg(int reg, unsigned int v){  lseek(uni_handle,reg,SEEK_SET);  write(uni_handle,&v,4);}//-----------------------------------------------------------------------------// Function   : ReadByte// Inputs     : //   int addr - VME byte Address to Read the byte from// Outputs    : the byte that was read// Description: Read a byte from the VME Bus// Remarks    : Will throw a BusError execption if there is an error// History    ://-----------------------------------------------------------------------------unsigned char VMEBus::ReadByte(int addr){    int c;  unsigned char v[4];    lseek(vme_handle,addr,SEEK_SET);  c = read(vme_handle,v,1);#ifdef DEBUG  printf("<libvme:ReadByte> addr=%08X v=%02X s=%01X\n", addr, *v, c);#endif  if (c != 1) {    lasterror = -1;    throw VME_BusError(addr + c, c, VME_TYPE_READ);  } else    lasterror = 0;  return v[0];}//-----------------------------------------------------------------------------// Function   : ReadWord// Inputs     : //   int addr - VME byte Address to Read the word from// Outputs    : the value of the word// Description: Read a word from the VME Bus// Remarks    : Will throw a BusError execption if there is an error// History    ://-----------------------------------------------------------------------------unsigned short VMEBus::ReadWord(int addr){        int c;  unsigned short v[2];	   lseek(vme_handle,addr,SEEK_SET);  c = read(vme_handle,&v,2);#ifdef DEBUG  printf("<libvme:ReadWord> addr=%08X v=%02X s=%01X\n", addr, *v, c);#endif  if (c != 2) {    lasterror = -1;    throw VME_BusError(addr + c, c, VME_TYPE_READ);  } else    lasterror = 0;    if (iSwapEndian)    return SwapEndian(v[0]);  else    return v[0]; }//-----------------------------------------------------------------------------// Function   : ReadLong

⌨️ 快捷键说明

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