00001 #!/usr/local/bin/python
00002 #
00003 # Copyright 2004
00004 # by
00005 # The Board of Trustees of the
00006 # Leland Stanford Junior University.
00007 # All rights reserved.
00008 #
00009
00010
00011 ## \namespace gAttr
00012 ##
00013 ## \brief GLAST LAT record attribute definitions.
00014 ##
00015 ## \b Contents:
00016 ##
00017 ## GLAST LAT functional block hierarchy representation in Python
00018 ## See <a href="http://www-glast.slac.stanford.edu/IntegrationTest/ONLINE/docs/TEM.pdf">
00019 ## The Tower Electronics Module (TEM) - Programming ICD specification (LAT-TD-00605-D1)</a>
00020 ## for more info
00021
00022 __facility__ = "Online"
00023 __abstract__ = "GLAST LAT record attribute definitions"
00024 __author__ = "Selim Tuvi <stuvi@slac.stanford.edu> SLAC - GLAST LAT I&T/Online"
00025 __date__ = ("$Date: 2004/09/25 01:50:42 $").split(' ')[1]
00026
00027 __version__ = "$Revision: 2.14 $"
00028 __release__ = "$Name: P04-06-05 $"
00029 __credits__ = "SLAC"
00030
00031 import LATTE.copyright_SLAC
00032
00033 from LATTE.client.gException import LATInterfaceException
00034
00035 from gRule import GruleBase
00036 from gConstraint import GconstraintBase
00037 from gEGU import GEGU
00038
00039 ATTR_READ = 0x1
00040 ATTR_WRITE = 0x2
00041 ATTR_READ_ONLY = ATTR_READ
00042 ATTR_WRITE_ONLY = ATTR_WRITE
00043 ATTR_READ_WRITE = ATTR_READ | ATTR_WRITE
00044 ATTR_NO_DIRECT_ACCESS = 0x4
00045 ATTR_COMMAND = 0x8 | ATTR_WRITE
00046
00047 # The following is for backward compatibility only
00048 REG_READ_ONLY = ATTR_READ_ONLY
00049 REG_WRITE_ONLY = ATTR_WRITE_ONLY
00050 REG_READ_WRITE = ATTR_READ_WRITE
00051 REG_NO_DIRECT_ACCESS = ATTR_NO_DIRECT_ACCESS
00052
00053
00054
00055 class Gattr(object):
00056 """\brief Base class which is instantiated once for each attribute kind.
00057 """
00058 # Set up a single instance of the defaults rather than one per Gattr
00059 defaultRule = GruleBase()
00060 defaultConstraint = GconstraintBase()
00061 defaultEgu = GEGU("")
00062
00063
00064 def __init__(self, name, id, size, flags, rule=None, constraint=None, egu=None):
00065 """Gattr constructor.
00066
00067 \param name The name of the attribute.
00068 \param size Attribute size in bytes.
00069 \param rule Optional. Attribute rule.
00070 \param constraint Optional. Attribute constraint.
00071 \param egu Optional. Attribute EGU
00072 """
00073 self.__name = name.lower()
00074 self.__id = id
00075 self.__size = size
00076 self.__flags = flags
00077
00078 self.__rule = rule
00079 self.__constraint = constraint
00080 self.__egu = egu
00081
00082 def create(self, node):
00083 return _Attr(node, self)
00084
00085 def set(self, node, value, bypass=0):
00086 raise Exception, "Missing set() implementation" # Revisit status
00087
00088 def get(self, node, bypass=0):
00089 raise Exception, "Missing get() implementation" # Revisit status
00090
00091 def getName(self):
00092 return self.__name
00093
00094 def size(self):
00095 """Method for returning the size of the attribute
00096
00097 \return Attribute size in bytes
00098 """
00099 return self.__size
00100
00101 def id(self):
00102 return self.__id
00103
00104 def setRule(self, rule):
00105 """Method to attach a rule to a gAttr after the gAttr has been constructed.
00106
00107 \param rule A Grule object instance
00108 """
00109 self.__rule = rule
00110
00111 def getRule(self):
00112 """Retrieve the rule associated with the gAttr.
00113 """
00114 return self.__rule
00115
00116 def setConstraint(self, constraint):
00117 """
00118 Method to attach a constraint to a gAttr after the gAttr has been constructed.
00119 This method will go away once constraints are loaded from a configuration file.
00120
00121 \param constraint A Gconstraint object instance
00122 """
00123 self.__constraint = constraint
00124
00125 def setEGU(self, egu):
00126 """
00127 Method to attach a EGU to a gAttr after the gAttr has been constructed.
00128
00129 \param egu A Gegu object instance
00130 """
00131 self.__egu = egu
00132
00133 def getEGU(self):
00134 """
00135 Method that returns the gEGU.GEGU class for this gAttr
00136
00137 \return A Gegu object instance
00138 """
00139 return self.__egu
00140
00141 def getConstraint(self):
00142 """
00143 Method that returns the gConstraint.Gconstraint class for this gAttr
00144
00145 \return A Gconstraint object instance
00146 """
00147 return self.__constraint
00148
00149 def flags(self):
00150 return self.__flags
00151
00152 def isReadOnly(self):
00153 """ Returns a boolean value indicating if the attribute is read only or not
00154
00155 \return 1=Read Only, 0=Not Read Only.
00156 """
00157 return self.__flags == ATTR_READ
00158
00159 def isWriteOnly(self):
00160 """ Returns a boolean value indicating if the attribute is write only or not
00161
00162 \return 1=Write Only, 0=Not Write Only.
00163 """
00164 return self.__flags == ATTR_WRITE
00165
00166 def isReadWrite(self):
00167 """ Returns a boolean value indicating if the attribute is read write or not
00168
00169 \return 1=Read Write, 0=Not Read Write.
00170 """
00171 return self.__flags == ATTR_READ_WRITE
00172
00173 def isNoDirectAccess(self):
00174 """ Returns a boolean value indicating if the attribute is no direct access or not
00175
00176 \return 1=No Direct Access, 0=Not No Direct Access.
00177 """
00178 return self.__flags == ATTR_NO_DIRECT_ACCESS
00179
00180 def isCommand(self):
00181 """
00182 """
00183 return self.__flags & ATTR_COMMAND == ATTR_COMMAND
00184
00185
00186
00187
00188 class GattrRaw(Gattr):
00189 """\brief Class which is instantiated for each raw register kind
00190 """
00191 def __init__(self, name, regno, size, flags=ATTR_READ_WRITE):
00192 """GattrRaw constructor
00193
00194 \param name The name of the register
00195 \param regno Register no.
00196 \param size Register size in bytes.
00197
00198 """
00199 Gattr.__init__(self, name, regno, size, flags)
00200
00201 def set(self, node, val, bypass=0):
00202 """
00203 Method for setting the value of a register attribute.
00204 Calls the functions in the base class for setting values.
00205
00206 \param val Register value to be set
00207 \param bypass Optional. Flag for bypassing EGU conversion
00208
00209 """
00210 response = node.load(self.id(), val)
00211 status = response.status()
00212 if status & 0x3: raise LATInterfaceException(status)
00213 return None, response.timestamp()
00214
00215 def get(self, node, bypass=0):
00216 """
00217 Method for getting the value of a register attribute.
00218 Calls the functions in the node class for getting values.
00219 If bypass=0 (the default), the value will be returned in EU.
00220 If bypass=1, the raw value will be returned.
00221 """
00222 response = node.read(self.id())
00223 status = response.status()
00224 if status & 0x3: raise LATInterfaceException(status)
00225
00226 return response.value(), response.timestamp()
00227
00228
00229 class GattrReg(Gattr):
00230 """\brief Class which is instantiated for each register
00231 """
00232 def __init__(self, name, regno, size, flags=ATTR_READ_WRITE,
00233 rule=Gattr.defaultRule, constraint=Gattr.defaultConstraint, egu=Gattr.defaultEgu):
00234 """GattrReg constructor
00235
00236 \param name The name of the register
00237 \param regno Register no.
00238 \param size Register size in bytes.
00239 \param rule Optional. Register rule.
00240 \param constraint Optional. Register constraint.
00241 \param egu Optional. Register EGU
00242
00243 """
00244 Gattr.__init__(self, name, regno, size, flags, rule, constraint, egu)
00245
00246 def set(self, node, val, bypass=0):
00247 """
00248 Method for setting the value of a register attribute.
00249 Calls the functions in the base class for setting values.
00250
00251 \param val Register value to be set
00252 \param bypass Optional. Flag for bypassing EGU conversion
00253
00254 """
00255 if bypass:
00256 raw = val
00257 else:
00258 (val, rejected) = self._Gattr__constraint.evaluate(val)
00259 if rejected:
00260 return None, None
00261 raw = self._Gattr__egu.raw(val)
00262
00263 response = node.load(self.id(), raw)
00264 status = response.status()
00265 if status & 0x3: raise LATInterfaceException(status)
00266 return None, response.timestamp()
00267
00268 def get(self, node, bypass=0):
00269 """
00270 Method for getting the value of a register attribute.
00271 Calls the functions in the node class for getting values.
00272 If bypass=0 (the default), the value will be returned in EU.
00273 If bypass=1, the raw value will be returned.
00274 """
00275 response = node.read(self.id())
00276 status = response.status()
00277 if status & 0x3: raise LATInterfaceException(status)
00278
00279 raw = response.value()
00280 if bypass:
00281 return raw, response.timestamp()
00282 else:
00283 egu = self._Gattr__egu.egu(raw)
00284 self._Gattr__rule.evaluate(egu, self, node)
00285 return egu, response.timestamp()
00286
00287
00288 class GattrDlc(Gattr):
00289 """Attribute class for implementing dataless commands"""
00290 def __init__(self, name, cmdNo, size=0, flags=ATTR_COMMAND):
00291 Gattr.__init__(self, name, cmdNo, 0, flags)
00292 self.get = self.set
00293
00294 def set(self, node, *args):
00295 """
00296 Method for invoking a dataless command.
00297 The value parameter is meaningless for this method and is only supplied to
00298 satisfy the function signature.
00299 """
00300 response = node.send(self.id())
00301 status = response.status()
00302 if status & 0x3: raise LATInterfaceException(status)
00303 return None, response.timestamp()
00304
00305 class GattrBF(Gattr):
00306 """\brief Bit field class which is instantiated for each bit field kind
00307
00308 This class allows operation on bit fields of the form (end, start]
00309 in a register specified by the register number (regno).
00310
00311 N.B. This attribute operates on the raw value of the associated register
00312 """
00313 def __init__(self, name, regno, start, end, flags=ATTR_READ_WRITE):
00314 """GattrBF constructor
00315
00316 \param name The name of the bit field
00317 \param regno Register no. containing the bit field
00318 \param start Bit offset to start (inclusive) of the bit field
00319 \param end Bit offset to the end (exclusive) of the bit field
00320 \param flags Optional flags to govern access to the bit field
00321
00322 """
00323 Gattr.__init__(self, name, regno, 0, flags)
00324
00325 if end <= start:
00326 raise Exception, "Invalid bit field specification: start %d, end %d" % (start, end) # Revisit
00327 self.__offset = start
00328 self.__mask = long(2**(end - start) - 1) << start
00329
00330 def set(self, node, val, bypass=0):
00331 """
00332 Method for setting the value of a bit field.
00333 Calls the functions in the base class for setting values.
00334
00335 \param val bit field value to be set
00336 \param bypass ignored
00337
00338 """
00339
00340 response = node.read(self.id())
00341 status = response.status()
00342 if status & 0x3: raise LATInterfaceException(status)
00343
00344 value = ((response.value() & ~self.__mask) |
00345 ((long(val) << self.__offset) & self.__mask))
00346
00347 response = node.load(self.id(), value)
00348 status = response.status()
00349 if status & 0x3: raise LATInterfaceException(status)
00350 return None, response.timestamp()
00351
00352 def get(self, node, bypass=0):
00353 """
00354 Method for getting the value of a bit field.
00355
00356 \param val bit field value to be set
00357 \param bypass ignored
00358 """
00359 response = node.read(self.id())
00360 status = response.status()
00361 if status & 0x3: raise LATInterfaceException(status)
00362
00363 value = (response.value() & self.__mask) >> self.__offset
00364
00365 return value, response.timestamp()
00366
00367 class _Attr(object):
00368 """Helper class for private use in this file only.
00369 """
00370
00371
00372 def __init__(self, node, attr):
00373 #print node.getName(), attr
00374 self.__node = node
00375 self.__attr = attr
00376
00377 self.__timestamp = -1L
00378
00379 #print id(self), id(attr), node.getName(), attr.getName(), attr.flags()
00380 if attr.flags() == (ATTR_READ | ATTR_NO_DIRECT_ACCESS):
00381 self.set = self.__badSet
00382 self.get = self.__badGet
00383 else:
00384 self.set = self.__set
00385 self.get = self.__get
00386
00387 # Callthroughs to 'parent' class
00388 # setRule = Gattr.setRule
00389 # setConstraint = Gattr.setConstraint
00390 # getEGU = Gattr.getEGU
00391 # getRule = Gattr.getRule
00392 # getConstraint = Gattr.getConstraint
00393 # getName = Gattr.getName
00394
00395 # id = Gattr.id
00396 # size = Gattr.size
00397 # isReadOnly = Gattr.isReadOnly
00398 # isWriteOnly = Gattr.isWriteOnly
00399 # isReadWrite = Gattr.isReadWrite
00400 # isNoDirectAccess = Gattr.isNoDirectAccess
00401 # isCommand = Gattr.isCommand
00402
00403
00404 def getName(self):
00405 return self.__attr.getName()
00406
00407 def size(self):
00408 """Method for returning the size of the attribute
00409
00410 \return Attribute size in bytes
00411 """
00412 return self.__attr.size()
00413
00414 def id(self):
00415 return self.__attr.id()
00416
00417 def setRule(self, rule):
00418 """Method to attach a rule to a gAttr after the gAttr has been constructed.
00419
00420 \param rule A Grule object instance
00421 """
00422 return self.__attr.setRule(rule)
00423
00424 def getRule(self):
00425 """Retrieve the rule associated with the gAttr.
00426 """
00427 return self.__attr.getRule()
00428
00429 def setConstraint(self, constraint):
00430 """
00431 Method to attach a constraint to a gAttr after the gAttr has been constructed.
00432 This method will go away once constraints are loaded from a configuration file.
00433
00434 \param constraint A Gconstraint object instance
00435 """
00436 return self.__attr.setConstraint(constraint)
00437
00438 def setEGU(self, egu):
00439 """
00440 Method to attach a EGU to a gAttr after the gAttr has been constructed.
00441
00442 \param egu A Gegu object instance
00443 """
00444 return self.__attr.setEGU(egu)
00445
00446 def getEGU(self):
00447 """
00448 Method that returns the gEGU.GEGU class for this gAttr
00449
00450 \return A Gegu object instance
00451 """
00452 return self.__attr.getEGU()
00453
00454 def getConstraint(self):
00455 """
00456 Method that returns the gConstraint.Gconstraint class for this gAttr
00457
00458 \return A Gconstraint object instance
00459 """
00460 return self.__attr.getConstraint()
00461
00462 def flags(self):
00463 return self.__attr.flags()
00464
00465 def isReadOnly(self):
00466 """ Returns a boolean value indicating if the attribute is read only or not
00467
00468 \return 1=Read Only, 0=Not Read Only.
00469 """
00470 return self.__attr.isReadOnly()
00471
00472 def isWriteOnly(self):
00473 """ Returns a boolean value indicating if the attribute is write only or not
00474
00475 \return 1=Write Only, 0=Not Write Only.
00476 """
00477 return self.__attr.isWriteOnly()
00478
00479 def isReadWrite(self):
00480 """ Returns a boolean value indicating if the attribute is read write or not
00481
00482 \return 1=Read Write, 0=Not Read Write.
00483 """
00484 return self.__attr.isReadWrite()
00485
00486 def isNoDirectAccess(self):
00487 """ Returns a boolean value indicating if the attribute is no direct access or not
00488
00489 \return 1=No Direct Access, 0=Not No Direct Access.
00490 """
00491 return self.__attr.isNoDirectAccess()
00492
00493 def isCommand(self):
00494 """
00495 """
00496 return self.__attr.isCommand()
00497
00498
00499 def __set(self, val, bypass=0, node=None):
00500 if node is not None:
00501 junk, self.__timestamp = self.__attr.set(node, val, bypass)
00502 else: # For backward compatibility
00503 junk, self.__timestamp = self.__attr.set(self.__node, val, bypass)
00504
00505 def __get(self, bypass=0, node=None):
00506 if node is not None:
00507 val, self.__timestamp = self.__attr.get(node, bypass)
00508 else: # For backward compatibility
00509 val, self.__timestamp = self.__attr.get(self.__node, bypass)
00510 return val
00511
00512 def __badSet(self, node, val, bypass=0):
00513 return -1 # revisit
00514 #raise LATInterfaceException(1)
00515
00516 def __badGet(self, node, val, bypass=0):
00517 return -1 # revisit
00518 #raise LATInterfaceException(1)
00519
00520 def getNode(self):
00521 return self.__node
00522
00523 def setTimeStamp(self, value):
00524 self.__timestamp = value
00525
00526 def getTimeStamp(self):
00527 """
00528 Method that returns the timestamp at the moment when the register was accessed.
00529
00530 \return Timestamp in seconds as a floating point value
00531 """
00532 if self.__timestamp == -1:
00533 return self.__timestamp
00534 else:
00535 return ((self.__timestamp >> 32) +
00536 (self.__timestamp & 0xffffffffL) / 1000000000.0)