~jordens/gpib-devices/trunk

« back to all changes in this revision

Viewing changes to gpib/utils.py

  • Committer: tailor at dyndns
  • Date: 2007-06-03 12:22:02 UTC
  • Revision ID: tailor@gustav.jordens.dyndns.org-20070603122202-50d801c75560d219
Tailorization
Import of the upstream sources from
 Repository: /home/rj/work/uni/projects/gpib/gpib-devices-darcs
       Kind: darcs
   Revision: pending changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004 Robert Jordens <jordens@debian.org>
 
2
#
 
3
# This library is free software; you can redistribute it and/or
 
4
# modify it under the terms of the GNU Lesser General Public
 
5
# License as published by the Free Software Foundation; either
 
6
# version 2.1 of the License, or (at your option) any later version.
 
7
#
 
8
# This library is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
# Lesser General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU Lesser General Public
 
14
# License along with this library; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 
16
# USA
 
17
#
 
18
# arch-tag: generic GPIB utility stuff
 
19
#
 
20
 
 
21
"""
 
22
"""
 
23
 
 
24
import math
 
25
from constants import *
 
26
 
 
27
 
 
28
def timeOutBelow(seconds):
 
29
  """
 
30
  return the name of the timeout below or at seconds
 
31
  @param seconds: number of seconds of the desired timeout
 
32
  @return: the name of the timeout below seconds
 
33
  """
 
34
  l = int(math.floor(math.log(seconds)/math.log(10)))
 
35
  if l < -3: p='u'; r=6
 
36
  elif l < 0: p='m'; r=3
 
37
  else: p=''; r=0
 
38
  if seconds < (3.0*(10.0**l)): m='1'
 
39
  else: m='3'
 
40
  return "T"+m+("0"*(l+r))+p+'s'
 
41
 
 
42
 
 
43
def isGPIBAddress(addr):
 
44
  """
 
45
  Check a GPIB address for validity.
 
46
 
 
47
  @param addr: a string of board, pad, sad, separated by '.' or ':', 
 
48
  or a tuple of values
 
49
  @return: True if valid
 
50
  @rtype: boolean
 
51
  """
 
52
  try:
 
53
    addr = makeGPIBTuple(addr)
 
54
    if len(addr) is not 3:
 
55
      return False
 
56
    if not (0<=addr[0]<=31) or not (0<=addr[1]<=31):
 
57
      return False
 
58
    if not (addr[2] in [0,-1]) or (addr[2] in range(0x60, 0x7e)):
 
59
      return False
 
60
    return True
 
61
  except:
 
62
    return False
 
63
 
 
64
 
 
65
def makeGPIBTuple(addr):
 
66
  """
 
67
  Make a tuple of board, pad, sad out pf pretty much anything
 
68
  @return: board, pad, sad tuple
 
69
  @param addr: a string of board, pad, sad, separated by '.' or ':', 
 
70
  or a tuple of values
 
71
  """
 
72
  if type(addr) is str:
 
73
    addr = addr.split('.')
 
74
    addr = reduce(lambda a,b: a+b, map(lambda p: p.split(':'), addr))
 
75
  if type(addr[0]) is not int:
 
76
    addr = tuple(map(int, addr))
 
77
  return addr
 
78
 
 
79
def make4882Addr(addr):
 
80
  pass
 
81
 
 
82
class GPIBAddress(object):
 
83
  #__implements__ = interfaces.IAddress,
 
84
  def __init__(self, address):
 
85
    if not isGPIBAddress(address):
 
86
      raise ValueError, '%s is not a valid GPIBAddress' % str(address)
 
87
    self.address = makeGPIBTuple(address)
 
88
    self.board = self.address[0]
 
89
    self.pad = self.address[1]
 
90
    self.sad = self.address[1]
 
91
 
 
92
  def __eq__(self, other):
 
93
    if isinstance(other, tuple):
 
94
      return tuple(self) == other
 
95
    elif isinstance(other, GPIBAddress):
 
96
      return self.address == other.address
 
97
 
 
98
  def __str__(self):
 
99
    return 'GPIBAddress(board %d, pad %d, sad %d)' % self.address
 
100
 
 
101
 
 
102
 
 
103
 
 
104
def DBG(*str,**kstr):
 
105
  """
 
106
  Print a debugging message if the L{debug} flag is M{True}.
 
107
 
 
108
  @param str: tuple of objects to pe printed
 
109
  @param kstr: dictionary of objects to be printed
 
110
  """
 
111
  if debug:
 
112
    print "DBG:", repr(str)[:100], repr(kstr)[:100]
 
113
  return str
 
114
 
 
115
 
 
116
class GpibError(Exception):
 
117
  """
 
118
  Base L{Exception} class for all gpib related errors.
 
119
  """
 
120
  def __init__(self,err=None,note=None,fn=__name__):
 
121
    """
 
122
    @param err: the iberr byte
 
123
    @param fn: the name of the gpib object related to the exception
 
124
    @param note: an explanatory note that is appended to the string
 
125
    representation of the exception
 
126
    """
 
127
    self._err = err
 
128
    self._note = note
 
129
    self._fn = fn
 
130
    self.args = (err,note,fn)
 
131
 
 
132
  def __str__(self):
 
133
    """
 
134
    Textual representation of the GpibError.
 
135
    
 
136
    @return: A descriptive string
 
137
    """
 
138
    string = 'GpibError '
 
139
    if self._fn is not None: 
 
140
      string = string + "in %s" % self._fn
 
141
    if self._note is not None: 
 
142
      string = string + ", %s" % self._note
 
143
    if self._err is not None:
 
144
      names = self.decode_err()
 
145
      string = string + (", iberr: %s" % 
 
146
        " ".join(names))
 
147
    return string
 
148
 
 
149
  def describe(self):
 
150
    """
 
151
    Describe the bits set in the error byte by their descriprions.
 
152
 
 
153
    @return: A list of strings of the form "<errorname>:
 
154
    <error-description>"
 
155
    """
 
156
    names = self.decode_err()
 
157
    return ["%s: %s" % (name, errDescr[name]) for name in names]
 
158
 
 
159
  def decode_err(self):
 
160
    """
 
161
    Makes a list of error names out of the error byte.
 
162
 
 
163
    @return: A list off error names
 
164
    """
 
165
    assert hasattr(self, '_err')
 
166
    if self._err == None:
 
167
      err = 0
 
168
    else:
 
169
      err = self._err
 
170
    return filter(lambda errName: err & errBits[errName], errNames)
 
171
 
 
172
 
 
173
class ConfigProperties(type):
 
174
  """
 
175
  A Metaclass that adds properties for all names from klass.configs
 
176
  calling class.ask, class.config respectively.
 
177
  """
 
178
  def __init__(klass, name, bases, attrs):
 
179
    """
 
180
    We have to pass conf to lambdas namespace here. nested_scopes?
 
181
    """
 
182
    type.__init__(klass, name, bases, attrs)
 
183
    for conf in klass.configs:
 
184
      setattr(klass, conf, property(
 
185
        fget=lambda self, conf=conf: self.ask(conf),
 
186
        fset=lambda self, v, conf=conf: self.config(conf, v),
 
187
        doc=configOptionsDescr[conf]))
 
188
        
 
189
 
 
190