1import wxctb, sys, re 2 3DCD = wxctb.LinestateDcd 4CTS = wxctb.LinestateCts 5DSR = wxctb.LinestateDsr 6DTR = wxctb.LinestateDtr 7RING = wxctb.LinestateRing 8RTS = wxctb.LinestateRts 9NULL = wxctb.LinestateNull 10 11def abstract(): 12 import inspect 13 caller = inspect.getouterframes(inspect.currentframe())[1][3] 14 raise NotImplementedError(caller + ' must be implemented in subclass') 15 16class IOBase: 17 def __init__(self): 18 self.device = None 19 # set timeout to 1000ms (the default) 20 self.timeout = 1000 21 22 def __del__(self): 23 pass 24 25 def Close(self): 26 if self.device: 27 self.device.Close() 28 29 def GetTimeout(self): 30 """ 31 Returns the internal timeout value in milliseconds 32 """ 33 return self.timeout 34 35 def Ioctl(self,cmd,arg): 36 if self.device: 37 self.device.Ioctl(cmd,arg) 38 39 def Open(self): 40 abstract() 41 42 def PutBack(self,char): 43 return self.device.PutBack(char) 44 45 def Read(self,length): 46 """ 47 Try to read the given count of data (length) and returns the 48 successfully readed number of data. The function never blocks. 49 For example: 50 readed = dev.Read(100) 51 """ 52 buf = "\x00"*(length+1) 53 rd = self.device.Read(buf,length) 54 return buf[0:rd] 55 56 def ReadBinary(self,eos="\n"): 57 """ 58 Special SCPI command. Read the next data coded as a SCPI 59 binary format. 60 A binary data transfer will be startet by '#'. The next byte 61 tells the count of bytes for the binary length header, 62 following by the length bytes. After these the data begins. 63 For example: 64 #500004xxxx 65 The header length covers 5 Byte, the length of the binary 66 data is 4 (x means the binary data bytes) 67 """ 68 try: 69 eoslen = len(eos) 70 b=self.Readv(2) 71 if len(b) == 2: 72 hl = int(b[1]) 73 b = self.Readv(hl) 74 if len(b) == hl: 75 dl = int(b) 76 # don't left over the eos string or character in the 77 # device input buffer 78 data = self.Readv(dl+eoslen) 79 # check, if the binary data block is complete 80 if data[dl] == '#': 81 # not complete, another block is following 82 for c in data[dl:dl+eoslen]: 83 self.PutBack(c) 84 85 data = data[:dl] + self.ReadBinary() 86 return data 87 except: 88 pass 89 return '' 90 91 def ReadUntilEOS(self,eos="\n",quota=0): 92 """ 93 ReadUntilEOS(eosString=\"\\n\",timeout=1000) 94 Reads data until the given eos string was received (default is 95 the linefeed character (0x0a) or the internal timeout 96 (default 1000ms) was reached. 97 ReadUntilEOS returns the result as the following tuple: 98 ['received string',state,readedBytes] 99 If a timeout occurred, state is 0, otherwise 1 100 """ 101 return self.device.ReadUntilEOS("",0,eos,self.timeout,quota) 102 103 def Readv(self,length): 104 """ 105 Try to read the given count of data. Readv blocks until all data 106 was readed successfully or the internal timeout, set with the 107 class member function SetTimeout(timeout), was reached. 108 Returns the readed data. 109 """ 110 buf = "\x00"*length 111 rd = self.device.Readv(buf,length,self.timeout) 112 return buf[0:rd] 113 114 def ResetBus(self): 115 """ 116 If the underlaying interface needs some special reset operations 117 (for instance the GPIB distinguish between a normal device reset 118 and a special bus reset), you can put some code here) 119 """ 120 pass 121 122 def SetTimeout(self,timeout): 123 """ 124 Set the internal timeout value in milliseconds for all blocked 125 operations like ReadUntilEOS, Readv and Writev. 126 """ 127 self.timeout = timeout 128 129 def Write(self,string): 130 """ 131 Writes the given string to the device and returns immediately. 132 Write returns the number of data bytes successfully written or a 133 negativ number if an error occured. For some circumstances, not 134 the complete string was written. 135 So you have to verify the return value to check this out. 136 """ 137 return self.device.Write(string,len(string)) 138 139 def Writev(self,string): 140 """ 141 Writes the given string to the device. The function blocks until 142 the complete string was written or the internal timeout, set with 143 SetTimeout(timeout), was reached. 144 Writev returns the number of data successfully written or a 145 negativ value, if an errors occurred. 146 """ 147 return self.device.Writev(string,len(string),self.timeout) 148 149class SerialPort(IOBase): 150 def __init__(self): 151 IOBase.__init__(self) 152 153 def __del__(self): 154 self.Close() 155 156 def ChangeLineState(self,lineState): 157 """ 158 Change (toggle) the state of each the lines given in the 159 linestate parameter. Possible values are DTR and/or RTS. 160 For example to toggle the RTS line only: 161 dev.ChangeLineState(RTS) 162 """ 163 self.device.ChangeLineState(lineState) 164 165 def ClrLineState(self,lineState): 166 """ 167 Clear the lines given in the linestate parameter. Possible 168 values are DTR and/or RTS. For example to clear only 169 the RTS line: 170 dev.ClrLineState(RTS) 171 """ 172 self.device.ClrLineState(lineState) 173 174 def GetAvailableBytes(self): 175 """ 176 Returns the available bytes in the input queue of the serial 177 driver. 178 """ 179 n = wxctb.new_intp() 180 wxctb.intp_assign(n, 0) 181 self.device.Ioctl(wxctb.CTB_SER_GETINQUE,n) 182 return wxctb.intp_value(n) 183 184 def GetCommErrors(self): 185 """ 186 Get the internal communication errors like breaks, framing, 187 parity or overrun errors. 188 Returns the count of each error as a tuple like this: 189 (b,f,o,p) = dev.GetCommErrors() 190 b: breaks, f: framing errors, o: overruns, p: parity errors 191 """ 192 einfo = wxctb.SerialPort_EINFO() 193 self.device.Ioctl(wxctb.CTB_SER_GETEINFO,einfo) 194 return einfo.brk,einfo.frame,einfo.overrun,einfo.parity 195 196 def GetLineState(self): 197 """ 198 Returns the current linestates of the CTS, DCD, DSR and RING 199 signal line as an integer value with the appropriate bits or 200 -1 on error. 201 For example: 202 lines = dev.GetLineState() 203 if lines & CTS: 204 print \"CTS is on\" 205 """ 206 return self.device.GetLineState() 207 208 def Open(self,devname,baudrate,protocol='8N1',handshake='no_handshake'): 209 """ 210 Open the device devname with the given baudrate, the protocol 211 like '8N1' (default) and the use of the handshake [no_handshake 212 (default), rtscts or xonxoff] 213 For example: 214 At Linux: 215 dev = SerialPort() 216 dev.Open(\"/dev/ttyS0\",115200) 217 or with a datalen of 7 bits, even parity, 2 stopbits and rts/cts 218 handshake: 219 dev.Open(\"/dev/ttyS0\",115200,'7E2',True) 220 At Windows: 221 dev = SerialPort() 222 dev.Open(\"COM1\",115200) 223 dev.Open(\"COM1\",115200,'7E2',True) 224 Returns the handle on success or a negativ value on failure. 225 """ 226 # the following parity values are valid: 227 # N:None, O:Odd, E:Even, M:Mark, S:Space 228 parity = {'N':0,'O':1,'E':2,'M':3,'S':4} 229 # the regular expression ensures a valid value for the datalen 230 # (5...8 bit) and the count of stopbits (1,2) 231 reg=re.compile(r"(?P<w>[8765])"r"(?P<p>[NOEMS])"r"(?P<s>[12])") 232 self.device = wxctb.SerialPort() 233 dcs = wxctb.SerialPort_DCS() 234 dcs.baud = baudrate 235 res = reg.search(protocol) 236 # handle the given protocol 237 if res: 238 dcs.wordlen = int(res.group('w')) 239 dcs.stopbits = int(res.group('s')) 240 dcs.parity = parity[res.group('p')] 241 # valid handshake are no one, rts/cts or xon/xoff 242 if handshake == 'rtscts': 243 dcs.rtscts = True 244 elif handshake == 'xonxoff': 245 dcs.xonxoff = True 246 247 return self.device.Open(devname,dcs) 248 249 def Reset(self): 250 """ 251 Send a break for 0.25s. 252 """ 253 self.device.SendBreak(0) 254 255 def SetBaudrate(self,baudrate): 256 """ 257 Set the baudrate for the device. 258 """ 259 self.device.SetBaudrate(baudrate) 260 261 def SetLineState(self,lineState): 262 """ 263 Set the lines given in the linestate parameter. Possible 264 values are DTR and/or RTS. For example to set both: 265 dev.SetLineState( DTR | RTS) 266 """ 267 self.device.SetLineState(lineState) 268 269 def SetParityBit(self,parity): 270 """ 271 Set the parity bit explicitly to 0 or 1. Use this function, if 272 you would like to simulate a 9 bit wordlen at what the ninth bit 273 was represented by the parity bit value. For example: 274 dev.SetParityBit( 0 ) 275 dev.Write('some data sent with parity 0') 276 dev.SetParityBit( 1 ) 277 dev.Write('another sequence with parity 1') 278 """ 279 return self.device.SetParityBit( parity ) 280 281class GpibDevice(IOBase): 282 """ 283 GPIB class 284 """ 285 def __init__(self): 286 IOBase.__init__(self) 287 288 def __del__(self): 289 self.Close() 290 291 def FindListeners(self,board = 0): 292 """ 293 Returns the address of the connected devices as a list. 294 If no device is listening, the list is empty. If an error 295 occurs an IOError exception raised. For example: 296 g = GPIB() 297 listeners = g.FindListeners() 298 """ 299 listeners = wxctb.GPIB_x_FindListeners(board) 300 if listeners < 0: 301 raise IOError("GPIB board error") 302 result = [] 303 for i in range(1,31): 304 if listeners & (1 << i): 305 result.append(i) 306 return result 307 308 def GetEosChar(self): 309 """ 310 Get the internal EOS termination character (see SetEosChar). 311 For example: 312 g = GPIB() 313 g.Open(\"gpib1\",1) 314 eos = g.GetEosChar() 315 """ 316 eos = wxctb.new_intp() 317 wxctb.intp_assign(eos, 0) 318 self.device.Ioctl(wxctb.CTB_GPIB_GET_EOS_CHAR,eos) 319 return wxctb.intp_value(eos) 320 321 def GetEosMode(self): 322 """ 323 Get the internal EOS mode (see SetEosMode). 324 For example: 325 g = GPIB() 326 g.Open(\"gpib1\",1) 327 eos = g.GetEosMode() 328 """ 329 mode = wxctb.new_intp() 330 wxctb.intp_assign(mode, 0) 331 self.device.Ioctl(wxctb.CTB_GPIB_GET_EOS_MODE,mode) 332 return wxctb.intp_value(mode) 333 334 def GetError(self): 335 errorString = " "*256 336 self.device.GetError(errorString,256) 337 return errorString 338 339 def GetSTB(self): 340 """ 341 Returns the value of the internal GPIB status byte register. 342 """ 343 stb = wxctb.new_intp() 344 wxctb.intp_assign(stb, 0) 345 self.device.Ioctl(wxctb.CTB_GPIB_GETRSP,stb) 346 return wxctb.intp_value(stb) 347 348 # This is only for internal usage!!! 349 def Ibrd(self,length): 350 buf = "\x00"*length 351 state = self.device.Ibrd(buf,length) 352 return state,buf 353 354 # This is only for internal usage!!! 355 def Ibwrt(self,string): 356 return self.device.Ibwrt(string,len(string)) 357 358 def Open(self,devname,adr,eosChar=10,eosMode=0x08|0x04): 359 """ 360 Open(gpibdevice,address,eosChar,eosMode) 361 Opens a connected device at the GPIB bus. gpibdevice means the 362 controller, (mostly \"gpib1\"), address the address of the desired 363 device in the range 1...31. The eosChar defines the EOS character 364 (default is linefeed), eosMode may be a combination of bits ORed 365 together. The following bits can be used: 366 0x04: Terminate read when EOS is detected. 367 0x08: Set EOI (End or identify line) with EOS on write function 368 0x10: Compare all 8 bits of EOS byte rather than low 7 bits 369 (all read and write functions). Default is 0x12 370 For example: 371 dev = GPIB() 372 dev.Open(\"gpib1\",17) 373 Opens the device with the address 17, linefeed as EOS (default) 374 and eos mode with 0x04 and 0x08. 375 Open returns >= 0 or a negativ value, if something going wrong. 376 """ 377 self.device = wxctb.GpibDevice() 378 dcs = wxctb.Gpib_DCS() 379 dcs.m_address1 = adr 380 dcs.m_eosChar = eosChar 381 dcs.m_eosMode = eosMode 382 result = self.device.Open(devname,dcs) 383 return result 384 385 def Reset(self): 386 """ 387 Resets the connected device. In the GPIB definition, the device 388 should be reset to it's initial state, so you can restart a 389 formely lost communication. 390 """ 391 self.device.Ioctl(wxctb.CTB_RESET,None) 392 393 def ResetBus(self): 394 """ 395 The command asserts the GPIB interface clear (IFC) line for 396 ast least 100us if the GPIB board is the system controller. 397 This initializes the GPIB and makes the interface CIC and 398 active controller with ATN asserted. 399 Note! The IFC signal resets only the GPIB interface functions 400 of the bus devices and not the internal device functions. 401 For a device reset you should use the Reset() command above. 402 """ 403 self.device.Ioctl(wxctb.CTB_GPIB_RESET_BUS,None) 404 405 def SetEosChar(self,eos): 406 """ 407 Configure the end-of-string (EOS) termination character. 408 Note! Defining an EOS byte does not cause the driver to 409 automatically send that byte at the end of write I/O 410 operations. The application is responsible for placing the 411 EOS byte at the end of the data strings that it defines. 412 (National Instruments NI-488.2M Function Reference Manual) 413 For example: 414 g = GPIB() 415 g.Open(\"gpib1\",1) 416 eos = g.GetEosChar(0x10) 417 """ 418 intp = wxctb.new_intp() 419 wxctb.intp_assign(intp, eos) 420 return self.device.Ioctl(wxctb.CTB_GPIB_SET_EOS_CHAR,intp) 421 422 def SetEosMode(self,mode): 423 """ 424 Set the EOS mode (handling).m_eosMode may be a combination 425 of bits ORed together. The following bits can be used: 426 0x04: Terminate read when EOS is detected. 427 0x08: Set EOI (End or identify line) with EOS on write function 428 0x10: Compare all 8 bits of EOS byte rather than low 7 bits 429 (all read and write functions). For example: 430 g = GPIB() 431 g.Open(\"gpib1\",1) 432 eos = g.GetEosMode(0x04 | 0x08) 433 """ 434 intp = wxctb.new_intp() 435 wxctb.intp_assign(intp, mode) 436 return self.device.Ioctl(wxctb.CTB_GPIB_SET_EOS_MODE,intp) 437 438def GetKey(): 439 """ 440 Returns the current pressed key or '\0', if no key is pressed. 441 You can simply create a query loop with: 442 while GetKey() == '\0': 443 ... make some stuff ... 444 445 """ 446 return wxctb.GetKey() 447 448def GetVersion(): 449 """ 450 Returns the version of the ctb python module. The numbering 451 has the following format: x.y.z 452 x.y means the version of the underlaying ctb lib, z the version 453 of the python port. 454 """ 455 return "0.16" 456