1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: gpibx.cpp 3 // Purpose: 4 // Author: Joachim Buermann 5 // Id: $Id: gpibx.cpp,v 1.1.1.1 2004/11/24 10:30:11 jb Exp $ 6 // Copyright: (c) 2001,2004 Joachim Buermann 7 // Licence: wxWindows licence 8 ///////////////////////////////////////////////////////////////////////////// 9 10 #include "ctb-0.16/gpib.h" 11 #include "ctb-0.16/timer.h" 12 #include <stdio.h> 13 #include <string.h> 14 #ifdef WIN32 15 # include "ctb-0.16/win32/gpib-32.h" 16 #if _MSC_VER < 1900 17 # define snprintf _snprintf 18 #endif 19 #elif __GNUG__ 20 # include <gpib/ib.h> 21 #endif 22 23 namespace ctb { 24 25 const char* GPIB1 = "gpib1"; 26 const char* GPIB2 = "gpib2"; 27 28 struct gpibErr_t { 29 int m_errno; 30 const char* m_notation; 31 const char* m_description; 32 }; 33 34 static gpibErr_t gpibErrors[] = { 35 {0,"EDVR","DOS Error"}, 36 {1,"ECIC","Specified GPIB Interface Board is Not Active Controller"}, 37 {2,"ENOL","No present listing device"}, 38 {3,"EADR","GPIB Board has not been addressed properly"}, 39 {4,"EARG","Invalid argument"}, 40 {5,"ESAC","Specified GPIB Interface Board is not System Controller"}, 41 {6,"EABO","I/O operation aborted (time-out)"}, 42 {7,"ENEB","Non-existent GPIB board"}, 43 {10,"EOIP","Routine not allowed during asynchronous I/O operation"}, 44 {11,"ECAP","No capability for operation"}, 45 {12,"EFSO","File System Error"}, 46 {14,"EBUS","Command byte transfer error"}, 47 {15,"ESTB","Serial poll status byte lost"}, 48 {16,"ESQR","SRQ stuck in ON position"}, 49 {20,"ETAB","Table problem"}, 50 {247,"EINT","No interrupt configured on board"}, 51 {248,"EWMD","Windows is not in Enhanced mode"}, 52 {249,"EVDD","GPIB driver is not installed"}, 53 {250,"EOVR","Buffer Overflow"}, 54 {251,"ESML","Two library calls running simultaneously"}, 55 {252,"ECFG","Board type does not match GPIB.CFG"}, 56 {253,"ETMR","No Windows timers available"}, 57 {254,"ESLC","No Windows selectors available"}, 58 {255,"EBRK","Control-Break pressed"} 59 }; 60 GetSettings()61 char* Gpib_DCS::GetSettings() 62 { 63 const char* to[] = { 64 "None","10us","30us","100us","300us","1ms","3ms","10ms","30ms", 65 "100ms","300ms","1s","3s","10s","30s","100s","300s","1000s" 66 }; 67 memset(m_buf,0,sizeof(m_buf)); 68 snprintf(m_buf,sizeof(m_buf)-1,"Adr: (%i,%i) to:%s", 69 m_address1, 70 m_address2, 71 to[m_timeout]); 72 return m_buf; 73 }; 74 CloseDevice()75 int GpibDevice::CloseDevice() 76 { 77 if(m_hd != -1) { 78 // goto local... 79 ibloc(m_hd); 80 // ...and switch device offline 81 ibonl(m_hd,0); 82 m_hd = -1; 83 m_board = -1; 84 } 85 return 0; 86 }; 87 GetErrorString(int error,bool detailed)88 const char* GpibDevice::GetErrorString(int error,bool detailed) 89 { 90 for(size_t i=0;i<(sizeof(gpibErrors)/sizeof(gpibErr_t));i++) { 91 if(gpibErrors[i].m_errno == error) { 92 if(detailed) { 93 return gpibErrors[i].m_description; 94 } 95 else { 96 return gpibErrors[i].m_notation; 97 } 98 } 99 } 100 return 0; 101 }; 102 103 // This is only for internal usage Ibrd(char * buf,size_t len)104 int GpibDevice::Ibrd(char* buf,size_t len) 105 { 106 return ibrd(m_hd,buf,len); 107 }; 108 109 // This is only for internal usage Ibwrt(char * buf,size_t len)110 int GpibDevice::Ibwrt(char* buf,size_t len) 111 { 112 return ibwrt(m_hd,buf,len); 113 }; 114 Ioctl(int cmd,void * args)115 int GpibDevice::Ioctl(int cmd,void* args) 116 { 117 switch(cmd) { 118 case CTB_RESET: 119 if(m_hd >= 0) { 120 ibclr(m_hd); 121 return 0; 122 } 123 return -1; 124 case CTB_GPIB_GETRSP: { 125 char spr = 0; 126 if(m_hd >= 0) { 127 ibrsp(m_hd,&spr); 128 *(int*)args = (int)spr; 129 return 0; 130 } 131 return 1; } 132 case CTB_GPIB_GETSTA: 133 *(int*)args = m_state; 134 return 0; 135 case CTB_GPIB_GETERR: 136 *(int*)args = m_error; 137 return 0; 138 case CTB_GPIB_GETLINES: { 139 short state = 0; 140 if(m_hd >= 0) { 141 iblines(m_board,&state); 142 *(int*)args = (int)state; 143 return 0; 144 } 145 return -1; } 146 case CTB_GPIB_SETTIMEOUT: { 147 if(m_hd >= 0) { 148 GpibTimeout timeout; 149 unsigned long to = *(unsigned long*)args; 150 // convert the timeout in ms (given by args) into the 151 // traditional NI-488.2 timeout period 152 if(to > 1000000) timeout = GpibTimeout1000s; 153 else if(to >= 300000) timeout = GpibTimeout300s; 154 else if(to >= 100000) timeout = GpibTimeout100s; 155 else if(to >= 30000) timeout = GpibTimeout30s; 156 else if(to >= 10000) timeout = GpibTimeout10s; 157 else if(to >= 3000) timeout = GpibTimeout3s; 158 else if(to >= 1000) timeout = GpibTimeout1s; 159 else if(to >= 300) timeout = GpibTimeout300ms; 160 else if(to >= 100) timeout = GpibTimeout100ms; 161 else if(to >= 30) timeout = GpibTimeout30ms; 162 else if(to >= 10) timeout = GpibTimeout10ms; 163 else if(to >= 3) timeout = GpibTimeout3ms; 164 else if(to >= 1) timeout = GpibTimeout1ms; 165 else timeout = GpibTimeoutNone; 166 ibtmo(m_hd,timeout); 167 return 0; 168 } 169 return -1; } 170 case CTB_GPIB_GTL: 171 // Forces the specified device to go to local program mode 172 if(m_hd >= 0) { 173 ibloc(m_hd); 174 return 0; 175 } 176 return -1; 177 case CTB_GPIB_REN: 178 // This routine can only be used if the specified GPIB 179 // Interface Board is the System Controller. 180 // Remember that even though the REN line is asserted, 181 // the device(s) will not be put into remote state until is 182 // addressed to listen by the Active Controller 183 if(m_hd) { 184 char adr = (char)m_dcs.m_address1; 185 ibsre(m_board,1); 186 ibcmd(m_board,&adr,1); 187 return 0; 188 } 189 return -1; 190 case CTB_GPIB_RESET_BUS: 191 ibsic(m_board); 192 return 0; 193 case CTB_GPIB_GET_EOS_CHAR: 194 if( m_hd ) { 195 *(int*)args = (int)m_dcs.m_eosChar; 196 return 0; 197 } 198 return -1; 199 case CTB_GPIB_SET_EOS_CHAR: 200 #ifdef __GNUG__ 201 // FIXME! 202 // Doesn't work with linux-gpib-3.2.08. All EOS beside 0x00 203 // are blocking during sending data to the device. (Look at 204 // function my_ibwrt in linux-gpib-3.2.08/lib/ibWrt.c 205 if( m_hd ) { 206 m_dcs.m_eosChar = (char)*(int*)args; 207 ibeos(m_hd,(m_dcs.m_eosMode << 8) | m_dcs.m_eosChar); 208 return 0; 209 } 210 #endif 211 return -1; 212 case CTB_GPIB_GET_EOS_MODE: 213 if( m_hd ) { 214 *(int*)args = (int)m_dcs.m_eosMode; 215 return 0; 216 } 217 return -1; 218 case CTB_GPIB_SET_EOS_MODE: 219 if( m_hd ) { 220 m_dcs.m_eosMode = (char)*(int*)args; 221 ibeos(m_hd,(m_dcs.m_eosMode << 8) | m_dcs.m_eosChar); 222 return 0; 223 } 224 return -1; 225 } 226 // error or unknown command 227 return -1; 228 }; 229 FindListeners(int board)230 int GpibDevice::FindListeners(int board) 231 { 232 int listeners = 0; 233 if((unsigned int)board > 1) { 234 return -1; 235 } 236 // reset the GPIB, otherwise no connected device is found (linux) 237 SendIFC(board); 238 // list of primary addresses to searching for. Must be terminated 239 // with NOADDR. 240 Addr4882_t addrlist[31]; 241 // The range of valid addresses is 1...30, 0 is reservated by the 242 // controller, 31 is not valid 243 for(int i = 0;i < 30; i++) addrlist[i] = (Addr4882_t) i + 1; 244 addrlist[30] = NOADDR; 245 // place to store the results 246 Addr4882_t results[31]; 247 memset(results,0,sizeof(results)); 248 FindLstn(board, addrlist, results, 31); 249 if(ibsta & ERR) { 250 return -1; 251 } 252 for(int i=0;i<=30;i++) { 253 if(results[i]) { 254 listeners |= 1 << results[i]; 255 } 256 } 257 return listeners; 258 }; 259 Open(const char * devname,int address)260 int GpibDevice::Open( const char* devname, int address ) 261 { 262 m_dcs.m_address1 = address; 263 264 return OpenDevice( devname, &m_dcs ); 265 } 266 267 OpenDevice(const char * devname,void * dcs)268 int GpibDevice::OpenDevice(const char* devname, void* dcs) 269 { 270 // if dcs isn't NULL, type cast 271 if(dcs) m_dcs = *(Gpib_DCS*)dcs; 272 273 if(strncmp(devname,"gpib1",5) == 0) m_board = 0; 274 else if(strncmp(devname,"gpib2",5) == 0) m_board = 1; 275 if(m_board < 0) { 276 return -1; 277 } 278 // check for a valid timeout 279 if((unsigned int)m_dcs.m_timeout > GpibTimeout1000s) { 280 m_dcs.m_timeout = GpibTimeout10us; 281 } 282 283 m_hd = ibdev(m_board, 284 m_dcs.m_address1, 285 m_dcs.m_address2, 286 m_dcs.m_timeout, 287 m_dcs.m_eot, 288 #ifdef __GNUG__ 289 // FIXME! 290 // linux-gpib-3.2.08 doesn't work with any EOS (blocks). 291 // Because we always has to add an EOS on the message 292 // (independent of the m_eosChar setting), we can ignore it! 293 0 294 #else 295 (m_dcs.m_eosMode << 8) | m_dcs.m_eosChar 296 #endif 297 ); 298 if(m_hd < 0) { 299 // no gpib controller installed (not found) 300 return -2; 301 } 302 // test for a connected listener (device with given address) 303 short int listen = 0; 304 ibln(m_board,m_dcs.m_address1,NO_SAD,&listen); 305 if(!listen) { 306 // no listener at the given address 307 CloseDevice(); 308 return -3; 309 } 310 // reset device 311 ibclr(m_hd); 312 // save state, error and count 313 m_state = ThreadIbsta(); 314 m_count = ThreadIbcnt(); 315 m_error = ThreadIberr(); 316 // no error 317 return 0; 318 }; 319 Read(char * buf,size_t len)320 int GpibDevice::Read(char* buf,size_t len) 321 { 322 // if something is in the fifo, first read that 323 if(m_fifo->items() > 0) { 324 return m_fifo->read(buf,len); 325 } 326 m_state = ibrd(m_hd,buf,len); 327 m_error = ThreadIberr(); 328 m_count = ThreadIbcnt(); 329 return m_count; 330 }; 331 Write(char * buf,size_t len)332 int GpibDevice::Write(char* buf,size_t len) 333 { 334 m_state = ibwrt(m_hd,buf,len); 335 m_error = ThreadIberr(); 336 m_count = ThreadIbcnt(); 337 return m_count; 338 }; 339 340 } // namespace ctb 341