![]() |
RTXI 1.3
|
00001 /* 00002 Copyright (C) 2011 Georgia Institute of Technology, University of Utah, Weill Cornell Medical College 00003 00004 This program is free software: you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation, either version 3 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 00017 */ 00018 00019 #include <ni_device.h> 00020 #include <ni_devices.h> 00021 #include <ni_driver.h> 00022 #include <debug.h> 00023 00024 #include <fcntl.h> 00025 #include <fstream> 00026 #include <sstream> 00027 00028 extern "C" Plugin::Object *createRTXIPlugin(void) 00029 { 00030 return new NIDriver(); 00031 } 00032 00033 NIDriver::~NIDriver(void) { 00034 for(std::list<NIDevice *>::iterator i = deviceList.begin();i != deviceList.end();++i) 00035 delete *i; 00036 } 00037 00038 DAQ::Device *NIDriver::createDevice(const std::list<std::string> &args) { 00039 int bus = -1; 00040 float dev; 00041 00042 sscanf(args.front().c_str(),"PCI::%d::%f",&bus,&dev); 00043 00044 if(bus < 0) { 00045 u32 bus_id = (u32)-1; 00046 u32 pci_id; 00047 char buffer[512]; 00048 std::ifstream file("/proc/bus/pci/devices"); 00049 00050 while(!file.eof()) { 00051 file.getline(buffer,sizeof(buffer)); 00052 sscanf(buffer,"%x %x %*s",&bus_id,&pci_id); 00053 00054 if((pci_id >> 16) == 0x1093) 00055 break; 00056 } 00057 00058 if(bus_id == (u32)-1) { 00059 ERROR_MSG("NIDriver::createDevice : scan for NI devices failed, no devices detected.\n"); 00060 return 0; 00061 } 00062 00063 bus = (bus_id & 0x0000FF00) >> 8; 00064 dev = (bus_id & 0x000000F8) >> 3; 00065 } 00066 00067 //printf("%s -> BUS : %d DEVICE : %f\n",args.front().c_str(),bus,dev); 00068 //printf("filename : /proc/bus/pci/%02d/%04.1f\n",bus,dev); 00069 00070 ni_device_t *device_info = 0; 00071 struct { 00072 u16 vendor_id; 00073 u16 device_id; 00074 u32 junk[3]; 00075 u32 bar[2]; 00076 } pci_info; 00077 00078 char filename[256]; 00079 sprintf(filename,"/proc/bus/pci/%02d/%04.1f",bus,dev); 00080 00081 int fd; 00082 if((fd = open(filename,O_RDONLY)) < 0) { 00083 ERROR_MSG("NIDriver::createDevice : failed to open %s for reading to acquire device information.\n"); 00084 return 0; 00085 } 00086 read(fd,&pci_info,sizeof(pci_info)); 00087 00088 for(size_t i=0;i<ni_devices_size;++i) 00089 if(ni_devices[i].deviceID == pci_info.device_id) { 00090 device_info = ni_devices+i; 00091 break; 00092 } 00093 00094 if(!device_info) { 00095 ERROR_MSG("NIDriver::createDevice : device (%X) isn't currently supported by this driver.\n",pci_info.device_id); 00096 return 0; 00097 } 00098 00099 int offset; 00100 size_t dio_count = device_info->dio_count > 32 ? 32 : device_info->dio_count; 00101 size_t num_channels = device_info->ai_count+device_info->ao_count+2*dio_count; 00102 IO::channel_t channels[device_info->ai_count+device_info->ao_count+2*dio_count]; 00103 00104 offset = 0; 00105 for(int i=offset;i<device_info->ai_count+offset;++i) { 00106 std::ostringstream name; 00107 name << "Analog Input " << i-offset;; 00108 channels[i].name = name.str(); 00109 channels[i].description = ""; 00110 channels[i].flags = IO::OUTPUT; 00111 } 00112 offset += device_info->ai_count; 00113 for(int i=offset;i<device_info->ao_count+offset;++i) { 00114 std::ostringstream name; 00115 name << "Analog Output " << i-offset; 00116 channels[i].name = name.str(); 00117 channels[i].description = ""; 00118 channels[i].flags = IO::INPUT; 00119 } 00120 offset += device_info->ao_count; 00121 for(int i=offset;i<dio_count+offset;++i) { 00122 std::ostringstream name; 00123 name << "Digital Input/Output " << i-offset; 00124 channels[i].name = name.str(); 00125 channels[i].description = ""; 00126 channels[i].flags = IO::OUTPUT; 00127 } 00128 offset += dio_count; 00129 for(int i=offset;i<dio_count+offset;++i) { 00130 std::ostringstream name; 00131 name << "Digital Input/Output " << i-offset; 00132 channels[i].name = name.str(); 00133 channels[i].description = ""; 00134 channels[i].flags = IO::INPUT; 00135 } 00136 00137 NIDevice *device = new NIDevice(channels,num_channels,args.front().c_str(),device_info,pci_info.bar,sizeof(pci_info.bar)/sizeof(pci_info.bar[0])); 00138 deviceList.push_back(device); 00139 return device; 00140 } 00141 00142 void NIDriver::doLoad(const Settings::Object::State &s) { 00143 for(size_t i = 0, end = s.loadInteger("Num Devices");i < end;++i) { 00144 std::list<std::string> args; 00145 args.push_back(s.loadString(QString::number(i))); 00146 DAQ::Device *device = createDevice(args); 00147 if(device) 00148 device->load(s.loadState(QString::number(i))); 00149 } 00150 } 00151 00152 void NIDriver::doSave(Settings::Object::State &s) const { 00153 s.saveInteger("Num Devices",deviceList.size()); 00154 size_t n = 0; 00155 for(std::list<NIDevice *>::const_iterator i = deviceList.begin(),end = deviceList.end();i != end; ++i) { 00156 std::ostringstream str; 00157 str << n++; 00158 s.saveString(str.str(),(*i)->getDeviceName()); 00159 s.saveState(str.str(),(*i)->save()); 00160 } 00161 }