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: 2005/08/02 21:08:49 $").split(' ')[1] 00026 00027 __version__ = "$Revision: 2.17 $" 00028 __release__ = "$Name: R04-12-00 $" 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 import warnings 00040 00041 ATTR_READ = 0x1 00042 ATTR_WRITE = 0x2 00043 ATTR_READ_ONLY = ATTR_READ 00044 ATTR_WRITE_ONLY = ATTR_WRITE 00045 ATTR_READ_WRITE = ATTR_READ | ATTR_WRITE 00046 ATTR_NO_DIRECT_ACCESS = 0x4 00047 ATTR_COMMAND = 0x8 | ATTR_WRITE 00048 ATTR_DEPRECATED = 0x10 00049 00050 # The following is for backward compatibility only 00051 REG_READ_ONLY = ATTR_READ_ONLY 00052 REG_WRITE_ONLY = ATTR_WRITE_ONLY 00053 REG_READ_WRITE = ATTR_READ_WRITE 00054 REG_NO_DIRECT_ACCESS = ATTR_NO_DIRECT_ACCESS 00055 00056 00057 00058 class Gattr(object): 00059 """\brief Base class which is instantiated once for each attribute kind. 00060 """ 00061 # Set up a single instance of the defaults rather than one per Gattr 00062 defaultRule = GruleBase() 00063 defaultConstraint = GconstraintBase() 00064 defaultEgu = GEGU("") 00065 00066 00067 def __init__(self, name, id, size, flags, rule=None, constraint=None, egu=None): 00068 """Gattr constructor. 00069 00070 \param name The name of the attribute. 00071 \param size Attribute size in bytes. 00072 \param rule Optional. Attribute rule. 00073 \param constraint Optional. Attribute constraint. 00074 \param egu Optional. Attribute EGU 00075 """ 00076 self.__name = name.lower() 00077 self.__id = id 00078 self.__size = size 00079 self.__flags = flags 00080 00081 self.__rule = rule 00082 self.__constraint = constraint 00083 self.__egu = egu 00084 00085 def create(self, node): 00086 return _Attr(node, self, self.__egu) 00087 00088 def set(self, node, value, attr, bypass=0): 00089 raise Exception, "Missing set() implementation" # Revisit status 00090 00091 def get(self, node, attr, bypass=0): 00092 raise Exception, "Missing get() implementation" # Revisit status 00093 00094 def getName(self): 00095 return self.__name 00096 00097 def size(self): 00098 """Method for returning the size of the attribute 00099 00100 \return Attribute size in bytes 00101 """ 00102 return self.__size 00103 00104 def id(self): 00105 return self.__id 00106 00107 def setRule(self, rule): 00108 """Method to attach a rule to a gAttr after the gAttr has been constructed. 00109 00110 \param rule A Grule object instance 00111 """ 00112 self.__rule = rule 00113 00114 def getRule(self): 00115 """Retrieve the rule associated with the gAttr. 00116 """ 00117 return self.__rule 00118 00119 def setConstraint(self, constraint): 00120 """ 00121 Method to attach a constraint to a gAttr after the gAttr has been constructed. 00122 This method will go away once constraints are loaded from a configuration file. 00123 00124 \param constraint A Gconstraint object instance 00125 """ 00126 self.__constraint = constraint 00127 00128 def setEGU(self, egu): 00129 """ 00130 Method to attach a EGU to a gAttr after the gAttr has been constructed. 00131 00132 \param egu A Gegu object instance 00133 """ 00134 self.__egu = egu 00135 00136 def getEGU(self): 00137 """ 00138 Method that returns the gEGU.GEGU class for this gAttr 00139 00140 \return A Gegu object instance 00141 """ 00142 return self.__egu 00143 00144 def getConstraint(self): 00145 """ 00146 Method that returns the gConstraint.Gconstraint class for this gAttr 00147 00148 \return A Gconstraint object instance 00149 """ 00150 return self.__constraint 00151 00152 def flags(self): 00153 return self.__flags 00154 00155 def isReadOnly(self): 00156 """ Returns a boolean value indicating if the attribute is read only or not 00157 00158 \return 1=Read Only, 0=Not Read Only. 00159 """ 00160 return self.__flags == ATTR_READ 00161 00162 def isWriteOnly(self): 00163 """ Returns a boolean value indicating if the attribute is write only or not 00164 00165 \return 1=Write Only, 0=Not Write Only. 00166 """ 00167 return self.__flags == ATTR_WRITE 00168 00169 def isReadWrite(self): 00170 """ Returns a boolean value indicating if the attribute is read write or not 00171 00172 \return 1=Read Write, 0=Not Read Write. 00173 """ 00174 return self.__flags == ATTR_READ_WRITE 00175 00176 def isNoDirectAccess(self): 00177 """ Returns a boolean value indicating if the attribute is no direct access or not 00178 00179 \return 1=No Direct Access, 0=Not No Direct Access. 00180 """ 00181 return self.__flags == ATTR_NO_DIRECT_ACCESS 00182 00183 def isCommand(self): 00184 """Returns a boolean value indicating if the attribute is a dataless command or not 00185 00186 \return 1=Dataless command, 0=Not a dataless command. 00187 """ 00188 return self.__flags & ATTR_COMMAND == ATTR_COMMAND 00189 00190 def isDeprecated(self): 00191 """Returns a boolean value indicating if the attribute is deprecated or not 00192 00193 \return 1=Deprecated, 0=Not deprecated. 00194 """ 00195 return self.__flags & ATTR_DEPRECATED == ATTR_DEPRECATED 00196 00197 00198 class GattrRaw(Gattr): 00199 """\brief Class which is instantiated for each raw register kind 00200 """ 00201 def __init__(self, name, regno, size, flags=ATTR_READ_WRITE): 00202 """GattrRaw constructor 00203 00204 \param name The name of the register 00205 \param regno Register no. 00206 \param size Register size in bytes. 00207 00208 """ 00209 Gattr.__init__(self, name, regno, size, flags) 00210 00211 def set(self, node, val, attr, bypass=0): 00212 """ 00213 Method for setting the value of a register attribute. 00214 Calls the functions in the base class for setting values. 00215 00216 \param val Register value to be set 00217 \param bypass Optional. Flag for bypassing EGU conversion 00218 00219 """ 00220 response = node.load(self.id(), val) 00221 status = response.status() 00222 if status & 0x3: raise LATInterfaceException(status) 00223 return None, response.timestamp() 00224 00225 def get(self, node, attr, bypass=0): 00226 """ 00227 Method for getting the value of a register attribute. 00228 Calls the functions in the node class for getting values. 00229 If bypass=0 (the default), the value will be returned in EU. 00230 If bypass=1, the raw value will be returned. 00231 """ 00232 response = node.read(self.id()) 00233 status = response.status() 00234 if status & 0x3: raise LATInterfaceException(status) 00235 00236 return response.value(), response.timestamp() 00237 00238 00239 class GattrReg(Gattr): 00240 """\brief Class which is instantiated for each register 00241 """ 00242 def __init__(self, name, regno, size, flags=ATTR_READ_WRITE, 00243 rule=Gattr.defaultRule, constraint=Gattr.defaultConstraint, egu=Gattr.defaultEgu): 00244 """GattrReg constructor 00245 00246 \param name The name of the register 00247 \param regno Register no. 00248 \param size Register size in bytes. 00249 \param rule Optional. Register rule. 00250 \param constraint Optional. Register constraint. 00251 \param egu Optional. Register EGU 00252 00253 """ 00254 Gattr.__init__(self, name, regno, size, flags, rule, constraint, egu) 00255 00256 def set(self, node, val, attr, bypass=0): 00257 """\brief Method for setting the value of a register attribute. 00258 00259 Calls the functions in the base class for setting values. 00260 00261 \param node Node this register belongs to 00262 \param val Register value to be set 00263 \param attr _Attr instance 00264 \param bypass Optional. Flag for bypassing EGU conversion 00265 00266 """ 00267 if bypass: 00268 raw = val 00269 else: 00270 (val, rejected) = self._Gattr__constraint.evaluate(val) 00271 if rejected: 00272 return None, None 00273 raw = attr.getEGU().raw(val) 00274 00275 response = node.load(self.id(), raw) 00276 status = response.status() 00277 if status & 0x3: raise LATInterfaceException(status) 00278 return None, response.timestamp() 00279 00280 def get(self, node, attr, bypass=0): 00281 """\brief Method for getting the value of a register attribute. 00282 Calls the functions in the node class for getting values. 00283 00284 \param node Node this register belongs to 00285 \param attr _Attr instance 00286 \param bypass Optional. Flag for bypassing EGU conversion 00287 bypass=0 (the default), the value will be returned in EU. 00288 bypass=1, the raw value will be returned. 00289 00290 \return Register value. 00291 00292 """ 00293 response = node.read(self.id()) 00294 status = response.status() 00295 if status & 0x3: raise LATInterfaceException(status) 00296 00297 raw = response.value() 00298 if bypass: 00299 return raw, response.timestamp() 00300 else: 00301 egu = attr.getEGU().egu(raw) 00302 self._Gattr__rule.evaluate(egu, self, node) 00303 return egu, response.timestamp() 00304 00305 class GattrRegDepr(GattrReg): 00306 def __init__(self, name, regno, size, flags=ATTR_DEPRECATED|ATTR_READ_WRITE, 00307 rule=Gattr.defaultRule, constraint=Gattr.defaultConstraint, egu=Gattr.defaultEgu): 00308 GattrReg.__init__(self, name, regno, size, flags, rule, constraint, egu) 00309 00310 def set(self, node, val, attr, bypass=0): 00311 """ 00312 Method for setting the value of a register attribute. 00313 Calls the functions in the base class for setting values. 00314 00315 \param val Register value to be set 00316 \param bypass Optional. Flag for bypassing EGU conversion 00317 00318 """ 00319 warnings.warn("GattrReg.set: Attribute %s.%s deprecated. Please use the new attribute name" 00320 % (node.getName(), self.getName()) 00321 , DeprecationWarning, stacklevel=2) 00322 return GattrReg.set(self, node, val, attr, bypass) 00323 00324 def get(self, node, attr, bypass=0): 00325 """ 00326 Method for getting the value of a register attribute. 00327 Calls the functions in the node class for getting values. 00328 If bypass=0 (the default), the value will be returned in EU. 00329 If bypass=1, the raw value will be returned. 00330 """ 00331 00332 warnings.warn("GattrReg.get: Attribute %s.%s deprecated. Please use the new attribute name" 00333 % (node.getName(), self.getName()) 00334 , DeprecationWarning, stacklevel=2) 00335 00336 return GattrReg.get(self, node, bypass) 00337 00338 class GattrDlc(Gattr): 00339 """Attribute class for implementing dataless commands""" 00340 def __init__(self, name, cmdNo, size=0, flags=ATTR_COMMAND): 00341 Gattr.__init__(self, name, cmdNo, 0, flags) 00342 self.get = self.set 00343 00344 def set(self, node, *args): 00345 """ 00346 Method for invoking a dataless command. 00347 The value parameter is meaningless for this method and is only supplied to 00348 satisfy the function signature. 00349 """ 00350 response = node.send(self.id()) 00351 status = response.status() 00352 if status & 0x3: raise LATInterfaceException(status) 00353 return None, response.timestamp() 00354 00355 class GattrBF(Gattr): 00356 """\brief Bit field class which is instantiated for each bit field kind 00357 00358 This class allows operation on bit fields of the form (end, start] 00359 in a register specified by the register number (regno). 00360 00361 N.B. This attribute operates on the raw value of the associated register 00362 """ 00363 def __init__(self, name, regno, start, end, flags=ATTR_READ_WRITE): 00364 """GattrBF constructor 00365 00366 \param name The name of the bit field 00367 \param regno Register no. containing the bit field 00368 \param start Bit offset to start (inclusive) of the bit field 00369 \param end Bit offset to the end (exclusive) of the bit field 00370 \param flags Optional flags to govern access to the bit field 00371 00372 """ 00373 Gattr.__init__(self, name, regno, 0, flags) 00374 00375 if end <= start: 00376 raise Exception, "Invalid bit field specification: start %d, end %d" % (start, end) # Revisit 00377 self.__offset = start 00378 self.__mask = long(2**(end - start) - 1) << start 00379 00380 # Find the size of the bitfield in bytes. Required by the register browser -ST 00381 (d,m) = divmod(end-start,8) 00382 self._Gattr__size = d + (m>0) 00383 00384 def set(self, node, val, attr, bypass=0): 00385 """ 00386 Method for setting the value of a bit field. 00387 Calls the functions in the base class for setting values. 00388 00389 \param val bit field value to be set 00390 \param bypass ignored 00391 00392 """ 00393 00394 response = node.read(self.id()) 00395 status = response.status() 00396 if status & 0x3: raise LATInterfaceException(status) 00397 00398 value = ((response.value() & ~self.__mask) | 00399 ((long(val) << self.__offset) & self.__mask)) 00400 00401 response = node.load(self.id(), value) 00402 status = response.status() 00403 if status & 0x3: raise LATInterfaceException(status) 00404 return None, response.timestamp() 00405 00406 def get(self, node, attr, bypass=0): 00407 """ 00408 Method for getting the value of a bit field. 00409 00410 \param val bit field value to be set 00411 \param bypass ignored 00412 """ 00413 response = node.read(self.id()) 00414 status = response.status() 00415 if status & 0x3: raise LATInterfaceException(status) 00416 00417 value = (response.value() & self.__mask) >> self.__offset 00418 00419 return value, response.timestamp() 00420 00421 class _Attr(object): 00422 """Helper class for private use in this file only. 00423 """ 00424 00425 00426 def __init__(self, node, attr, egu): 00427 #print node.getName(), attr 00428 self.__node = node 00429 self.__attr = attr 00430 00431 self.__timestamp = -1L 00432 00433 #print id(self), id(attr), node.getName(), attr.getName(), attr.flags() 00434 if attr.flags() == (ATTR_READ | ATTR_NO_DIRECT_ACCESS): 00435 self.set = self.__badSet 00436 self.get = self.__badGet 00437 else: 00438 self.set = self.__set 00439 self.get = self.__get 00440 00441 if egu is not None and egu is not Gattr.defaultEgu: 00442 self.setEGU(egu) 00443 00444 # Callthroughs to 'parent' class 00445 00446 # This callthrough is only in effect if the _Attr__egu is not instantiated 00447 # getEGU = Gattr.getEGU 00448 00449 # setRule = Gattr.setRule 00450 # setConstraint = Gattr.setConstraint 00451 # getRule = Gattr.getRule 00452 # getConstraint = Gattr.getConstraint 00453 # getName = Gattr.getName 00454 00455 # id = Gattr.id 00456 # size = Gattr.size 00457 # isReadOnly = Gattr.isReadOnly 00458 # isWriteOnly = Gattr.isWriteOnly 00459 # isReadWrite = Gattr.isReadWrite 00460 # isNoDirectAccess = Gattr.isNoDirectAccess 00461 # isCommand = Gattr.isCommand 00462 00463 00464 def getName(self): 00465 return self.__attr.getName() 00466 00467 def size(self): 00468 """Method for returning the size of the attribute 00469 00470 \return Attribute size in bytes 00471 """ 00472 return self.__attr.size() 00473 00474 def id(self): 00475 return self.__attr.id() 00476 00477 def setRule(self, rule): 00478 """Method to attach a rule to a gAttr after the gAttr has been constructed. 00479 00480 \param rule A Grule object instance 00481 """ 00482 return self.__attr.setRule(rule) 00483 00484 def getRule(self): 00485 """Retrieve the rule associated with the gAttr. 00486 """ 00487 return self.__attr.getRule() 00488 00489 def setConstraint(self, constraint): 00490 """ 00491 Method to attach a constraint to a gAttr after the gAttr has been constructed. 00492 This method will go away once constraints are loaded from a configuration file. 00493 00494 \param constraint A Gconstraint object instance 00495 """ 00496 return self.__attr.setConstraint(constraint) 00497 00498 def setEGU(self, egu): 00499 """ 00500 Method to attach a EGU to a gAttr after the gAttr has been constructed. 00501 00502 \param egu A Gegu object instance 00503 """ 00504 self.__egu = egu 00505 00506 def getEGU(self): 00507 """ 00508 Method that returns the gEGU.GEGU class for this gAttr 00509 00510 \return A Gegu object instance 00511 """ 00512 return getattr(self, '_Attr__egu', self.__attr.getEGU()) 00513 00514 def getConstraint(self): 00515 """ 00516 Method that returns the gConstraint.Gconstraint class for this gAttr 00517 00518 \return A Gconstraint object instance 00519 """ 00520 return self.__attr.getConstraint() 00521 00522 def flags(self): 00523 return self.__attr.flags() 00524 00525 def isReadOnly(self): 00526 """ Returns a boolean value indicating if the attribute is read only or not 00527 00528 \return 1=Read Only, 0=Not Read Only. 00529 """ 00530 return self.__attr.isReadOnly() 00531 00532 def isWriteOnly(self): 00533 """ Returns a boolean value indicating if the attribute is write only or not 00534 00535 \return 1=Write Only, 0=Not Write Only. 00536 """ 00537 return self.__attr.isWriteOnly() 00538 00539 def isReadWrite(self): 00540 """ Returns a boolean value indicating if the attribute is read write or not 00541 00542 \return 1=Read Write, 0=Not Read Write. 00543 """ 00544 return self.__attr.isReadWrite() 00545 00546 def isNoDirectAccess(self): 00547 """ Returns a boolean value indicating if the attribute is no direct access or not 00548 00549 \return 1=No Direct Access, 0=Not No Direct Access. 00550 """ 00551 return self.__attr.isNoDirectAccess() 00552 00553 def isCommand(self): 00554 """Returns a boolean value indicating if the attribute is a dataless command or not 00555 00556 \return 1=Dataless command, 0=Not a dataless command. 00557 """ 00558 return self.__attr.isCommand() 00559 00560 def isDeprecated(self): 00561 """Returns a boolean value indicating if the attribute is deprecated or not 00562 00563 \return 1=Deprecated, 0=Not deprecated. 00564 """ 00565 return self.__attr.isDeprecated() 00566 00567 def __set(self, val, bypass=0, node=None): 00568 if node is not None: 00569 junk, self.__timestamp = self.__attr.set(node, val, self, bypass) 00570 else: # For backward compatibility 00571 junk, self.__timestamp = self.__attr.set(self.__node, val, self, bypass) 00572 00573 def __get(self, bypass=0, node=None): 00574 if node is not None: 00575 val, self.__timestamp = self.__attr.get(node, self, bypass) 00576 else: # For backward compatibility 00577 val, self.__timestamp = self.__attr.get(self.__node, self, bypass) 00578 return val 00579 00580 def __badSet(self, node, val, bypass=0): 00581 return -1 # revisit 00582 #raise LATInterfaceException(1) 00583 00584 def __badGet(self, node, val, bypass=0): 00585 return -1 # revisit 00586 #raise LATInterfaceException(1) 00587 00588 def getNode(self): 00589 return self.__node 00590 00591 def setTimeStamp(self, value): 00592 self.__timestamp = value 00593 00594 def getTimeStamp(self): 00595 """ 00596 Method that returns the timestamp at the moment when the register was accessed. 00597 00598 \return Timestamp in seconds as a floating point value 00599 """ 00600 if self.__timestamp == -1: 00601 return self.__timestamp 00602 else: 00603 return ((self.__timestamp >> 32) + 00604 (self.__timestamp & 0xffffffffL) / 1000000000.0)