Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

gTEM.py

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 __facility__ = "Online"
00012 __abstract__ = "GLAST TEM functional block hierarchy"
00013 __author__  = "Selim Tuvi <stuvi@slac.stanford.edu> SLAC - GLAST LAT I&T/Online"
00014 __date__     = ("$Date: 2005/10/20 02:35:43 $").split(' ')[1]
00015 __version__ = "$Revision: 2.27 $"
00016 __release__  = "$Name: R04-12-00 $"
00017 __credits__ = "SLAC"
00018 
00019 import LATTE.copyright_SLAC
00020 
00021 import struct
00022 import time
00023 import gDb
00024 import gAttr
00025 import LATTE.client.gRegister  as gRegister
00026 import LATTE.client.gException as gException
00027 
00028 #  TEM{}
00029 #   |
00030 #   |----------------
00031 #   |       |       |
00032 #  TIC     CCC{}   TCC{}
00033 #           |       |
00034 #          CRC{}   TRC{}
00035 #           |       |
00036 #          CFE{}   TFE{}
00037 
00038 
00039 class GTEM(gDb.Gdb):
00040   """\brief TEM node Record
00041 
00042   Valid Registers:
00043   - \c configuration
00044   - \c data_masks
00045   - \c status
00046   - \c command_response
00047   - \c tkr_trgseq
00048   - \c cal_trgseq
00049   - \c address
00050 
00051   Dataless Commands:
00052   - \c cmd_reset
00053   - \c cmd_look_at_me
00054 
00055   """
00056   __attrs = [
00057     # Registers
00058     gAttr.GattrRaw('configuration',     0, 4),
00059     gAttr.GattrRaw('data_masks',        1, 4),
00060     gAttr.GattrRaw('status',            2, 4),
00061     gAttr.GattrRaw('command_response',  3, 4),
00062     gAttr.GattrRaw('tkr_trgseq',        4, 4),
00063     gAttr.GattrRaw('cal_trgseq',        5, 4),
00064     gAttr.GattrRaw('address',           6, 4),
00065     # Dataless Commands
00066     gAttr.GattrDlc('cmd_reset',         1),
00067     gAttr.GattrDlc('cmd_look_at_me',    9)
00068     ]
00069 
00070   def __init__(self, client, parent, id):
00071     """\brief Initialize valid registers as Gattrs.
00072 
00073     Assign default values to members
00074     """
00075 
00076     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00077     # is dangerous therefore if the parent TEM is a broadcast node
00078     # the read and send methods are redefined so that we loop
00079     # over each TEM defined in the schema
00080     if id == gDb.Children.BCASTID:
00081       self.read = None
00082       self.load = self.__bcast_load
00083       self.send = self.__bcast_send
00084 
00085     if id < gDb.Lem.NTEMS:
00086       addr = gDb.Lem.ADDR_TEM_BASE+id
00087     elif id == gDb.Children.BCASTID:
00088       addr = gDb.Lem.ADDR_SLV_BCAST
00089     else:
00090       raise KeyError("*** gTEM: GTEM id %d is invalid" %(id))
00091     self.CCC = gDb.Children(self, GCCC)
00092     self.TCC = gDb.Children(self, GTCC)
00093     self.TIC = None
00094     flags = {'CmdrspFabric': 'On',
00095              'EventFabric' : 'On',
00096              'UsePdu1'     : False}
00097     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr, flags)
00098 
00099   def read(self, reg):
00100     return self.cmdrsp('TEM_read', self.addr(), reg, '!I')
00101 
00102   def load(self, reg, value):
00103     # If you modify this method, change __bcast_load as well
00104     return self.cmdrsp('TEM_load', self.addr(), reg, value)
00105 
00106   def send(self, cmd):
00107     # If you modify this method, change __bcast_send as well
00108     if cmd == 9:
00109       return self.cmdrsp('LookAtMe', self.addr())
00110     else:
00111       return self.cmdrsp('TEM_cmd', self.addr(), cmd)
00112 
00113   def __bcast_load(self, reg, value):
00114     for temId in self.up().TEM:
00115       rsp = self.cmdrsp('TEM_load', gDb.Lem.ADDR_TEM_BASE+temId, reg, value)
00116       if rsp.status() != 0: break
00117     return rsp
00118 
00119   def __bcast_send(self, cmd):
00120     for temId in self.up().TEM:
00121       if cmd == 9:
00122         rsp = self.cmdrsp('LookAtMe', gDb.Lem.ADDR_TEM_BASE+temId)
00123       else:
00124         rsp = self.cmdrsp('TEM_cmd', gDb.Lem.ADDR_TEM_BASE+temId, cmd)
00125       if rsp.status() != 0: break
00126     return rsp
00127 
00128   def downCCC(self, childId):
00129     """\brief Navigate to the GCCC indicated by \a childId
00130 
00131     \param  childId The id of the child GCCC
00132 
00133     \return         A GCCC object instance
00134     """
00135     return self.CCC.down(childId)
00136 
00137   def downTCC(self, childId):
00138     """\brief Navigate to the GTCC indicated by \a childId
00139 
00140     \param  childId The id of the child GTCC
00141 
00142     \return         A GTCC object instance
00143     """
00144     return self.TCC.down(childId)
00145 
00146   def allCCC(self):
00147     """\brief Navigate to the broadcast GCCC
00148 
00149     \return         The broadcast GCCC object instance
00150     """
00151     return self.CCC.all()
00152 
00153   def allTCC(self):
00154     """\brief Navigate to the broadcast GTCC
00155 
00156     \return         The broadcast GTCC object instance
00157     """
00158     return self.TCC.all()
00159 
00160   def CCCcnt(self):
00161     """\brief Return the GCCC count
00162 
00163     \return Current GCCC count
00164     """
00165     return len(self.CCC)
00166 
00167   def TCCcnt(self):
00168     """\brief Return the GTCC count
00169 
00170     \return Current GTCC count
00171     """
00172     return len(self.TCC)
00173 
00174   def downTIC(self):
00175     """\brief Navigate to the GTIC node
00176 
00177     \return         The GTIC object instance
00178     """
00179     return self.TIC
00180 
00181   def existsTIC(self):
00182     """\brief Check if the GTIC instance exists in the schema.
00183 
00184     \return       1 if it exists, 0 if it doesn't.
00185     """
00186     return self.TIC != None
00187 
00188   def existsCCC(self, cccId):
00189     """\brief Check if the GCCC instance with the id
00190     \a cccId exists in the schema.
00191 
00192     \param  cccId Calorimeter cable controller id
00193 
00194     \return       1 if it exists, 0 if it doesn't.
00195     """
00196     return self.CCC.exists(cccId)
00197 
00198   def existsTCC(self, tccId):
00199     """\brief Check if the GTCC instance with the id
00200     \a tccId exists in the schema.
00201 
00202     \param  tccId Tracker cable controller id
00203 
00204     \return       1 if it exists, 0 if it doesn't.
00205     """
00206     return self.TCC.exists(tccId)
00207 
00208 
00209 ## private:
00210   def __removeCCC(self, cccId):
00211     self.CCC.remove(cccId)
00212 
00213   def __addCCC(self, cccId):
00214     return self.CCC.add(cccId)
00215 
00216   def __removeTCC(self, tccId):
00217     self.TCC.remove(tccId)
00218 
00219   def __addTCC(self, tccId):
00220     return self.TCC.add(tccId)
00221 
00222   def __removeTIC(self):
00223     self.TIC = None
00224 
00225   def __addTIC(self):
00226     self.TIC = GTIC(self.client(), self)
00227     return self.TIC
00228 
00229 
00230 class GCCC(gDb.Gdb):
00231   """\brief Calorimeter Cable Controller node Record.
00232 
00233   Has GCCC specific registers and dataless commands.
00234 
00235   Valid Registers:
00236   - \c configuration
00237   - \c layer_mask_0
00238   - \c layer_mask_1
00239   - \c fifo_status
00240   - \c latched_status
00241   - \c event_timeouts
00242   - \c trg_alignment
00243 
00244   Dataless Commands:
00245   - \c cmd_nop
00246   - \c cmd_reset
00247 
00248   """
00249   __attrs = [
00250     # Registers
00251     gAttr.GattrRaw('configuration',   0, 4),
00252     gAttr.GattrRaw('layer_mask_0',    1, 4),
00253     gAttr.GattrRaw('layer_mask_1',    2, 4),
00254     gAttr.GattrRaw('fifo_status',     3, 4),
00255     gAttr.GattrRaw('latched_status',  4, 4),
00256     gAttr.GattrRaw('event_timeouts',  5, 4),
00257     gAttr.GattrRaw('trg_alignment',   6, 4),
00258     # Dataless Commands
00259     gAttr.GattrDlc('cmd_nop',         0, 0),
00260     gAttr.GattrDlc('cmd_reset',       1, 0)
00261     ]
00262 
00263   def __init__(self, client, parent, id):
00264     """\brief Initialize valid registers as Gattrs.
00265 
00266     Assign default values to members
00267     """
00268 
00269     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00270     # is dangerous therefore if the parent TEM is a broadcast node
00271     # the read and send methods are redefined so that we loop
00272     # over each TEM defined in the schema
00273     if parent.id() == gDb.Children.BCASTID:
00274       self.read = None
00275       self.load = self.__bcast_load
00276       self.send = self.__bcast_send
00277 
00278     if id < gDb.Lem.NCCCS:
00279       addr = id
00280     elif id == gDb.Children.BCASTID:
00281       addr = gDb.Lem.CCCBCAST
00282     else:
00283       raise KeyError("*** gTEM: GCCC id %d is invalid" %(id))
00284     self.CRC = gDb.Children(self, GCRC)
00285     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr)
00286 
00287   def read(self, reg):
00288     return self.cmdrsp('CCC_read', self.up().addr(), self.addr(), reg, '!I')
00289 
00290   def load(self, reg, value):
00291     # If you modify this method, change __bcast_load as well
00292     return self.cmdrsp('CCC_load', self.up().addr(), self.addr(), reg, value)
00293 
00294   def send(self, cmd):
00295     # If you modify this method, change __bcast_send as well
00296     return self.cmdrsp('CCC_cmd', self.up().addr(), self.addr(), cmd)
00297 
00298   def __bcast_load(self, reg, value):
00299     for temId in self.up().up().TEM:
00300       rsp = self.cmdrsp('CCC_load', gDb.Lem.ADDR_TEM_BASE+temId, self.addr(), reg, value)
00301       if rsp.status() != 0: break
00302     return rsp
00303 
00304   def __bcast_send(self, cmd):
00305     for temId in self.up().up().TEM:
00306       rsp = self.cmdrsp('CCC_cmd', gDb.Lem.ADDR_TEM_BASE+temId, self.addr(), cmd)
00307       if rsp.status() != 0: break
00308     return rsp
00309 
00310   def downCRC(self, childId):
00311     """\brief Navigate to the GCRC indicated by \a childId
00312 
00313     \param  childId The id of the child GCRC
00314 
00315     \return         A GCRC object instance
00316     """
00317     return self.CRC.down(childId)
00318 
00319   def allCRC(self):
00320     """\brief Navigate to the broadcast GCRC
00321 
00322     \return The broadcast GCRC object instance
00323     """
00324     return self.CRC.all()
00325 
00326   def existsCRC(self, crcId):
00327     """\brief Check if the GCRC instance with the id
00328     \a crcId exists in the schema.
00329 
00330     \param  crcId Calorimeter readout controller id
00331 
00332     \return       1 if it exists, 0 if it doesn't.
00333     """
00334     return self.CRC.exists(crcId)
00335 
00336 ## private:
00337   def __removeCRC(self, rcrId):
00338     self.CRC.remove(rcrId)
00339 
00340   def __addCRC(self, rcrId):
00341     return self.CRC.add(rcrId)
00342 
00343 
00344 class GCRC(gDb.Gdb):
00345   """\brief Calorimeter Readout Controller node Record.
00346 
00347   Has GCRC specific registers and dataless commands.
00348 
00349   Valid Registers:
00350   - \c csr
00351   - \c last_cmd
00352   - \c delay_1
00353   - \c delay_2
00354   - \c delay_3
00355   - \c dac
00356   - \c config
00357 
00358   Dataless Commands:
00359   - \c cmd_nop
00360   - \c cmd_reset
00361   - \c cmd_calstrobe
00362                  ]
00363 
00364   """
00365   __attrs = [
00366     # Registers
00367     gAttr.GattrRaw('csr',              0, 2),
00368     gAttr.GattrRaw('last_cmd',         1, 2),
00369     gAttr.GattrRaw('delay_1',          3, 2),
00370     gAttr.GattrRaw('delay_2',          4, 2),
00371     gAttr.GattrRaw('delay_3',          5, 2),
00372     gAttr.GattrRaw('dac',              6, 2),
00373     gAttr.GattrRaw('config',           7, 2),
00374     # Dataless Commands
00375     gAttr.GattrDlc('cmd_nop',          0, 0),
00376     gAttr.GattrDlc('cmd_reset',        1, 0),
00377     gAttr.GattrDlc('cmd_calstrobe',    3, 0)
00378     ]
00379 
00380   def __init__(self, client, parent, id):
00381     """\brief Initialize valid registers as Gattrs.
00382 
00383     Assign default values to members
00384     """
00385 
00386     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00387     # is dangerous therefore if the parent TEM is a broadcast node
00388     # the read and send methods are redefined so that we loop
00389     # over each TEM defined in the schema
00390     if parent.up().id() == gDb.Children.BCASTID:
00391       self.read = None
00392       self.load = self.__bcast_load
00393       self.send = self.__bcast_send
00394 
00395     if id < gDb.Lem.NCRCS:
00396       addr = id
00397     elif id == gDb.Children.BCASTID:
00398       addr = gDb.Lem.CRCBCAST
00399     else:
00400       raise KeyError("*** gTEM: GCRC id %d is invalid" %(id))
00401     self.CFE = gDb.Children(self, GCFE)
00402     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr)
00403 
00404   def read(self, reg):
00405     return self.cmdrsp('CRC_read', self.up().up().addr(), self.up().addr(), self.addr(), reg, '!I')
00406 
00407   def load(self, reg, value):
00408     # If you modify this method, change __bcast_load as well
00409     return self.cmdrsp('CRC_load', self.up().up().addr(), self.up().addr(), self.addr(), reg, value)
00410 
00411   def send(self, cmd):
00412     # If you modify this method, change __bcast_send as well
00413     return self.cmdrsp('CRC_cmd', self.up().up().addr(), self.up().addr(), self.addr(), cmd)
00414 
00415   def __bcast_load(self, reg, value):
00416     for temId in self.up().up().up().TEM:
00417       rsp = self.cmdrsp('CRC_load', gDb.Lem.ADDR_TEM_BASE+temId, self.up().addr(), self.addr(), reg, value)
00418       if rsp.status() != 0: break
00419     return rsp
00420 
00421   def __bcast_send(self, cmd):
00422     for temId in self.up().up().up().TEM:
00423       rsp = self.cmdrsp('CRC_cmd', gDb.Lem.ADDR_TEM_BASE+temId, self.up().addr(), self.addr(), cmd)
00424       if rsp.status() != 0: break
00425     return rsp
00426 
00427   def downCFE(self, childId):
00428     """\brief Navigate to the GCFE indicated by \a childId
00429 
00430     \param  childId The id of the child GCFE
00431 
00432     \return         A GCFE object instance
00433     """
00434     return self.CFE.down(childId)
00435 
00436   def allCFE(self):
00437     """\brief Navigate to the broadcast GCFE
00438 
00439     \return The broadcast GCFE object instance
00440     """
00441     return self.CFE.all()
00442 
00443   def existsCFE(self, cfeId):
00444     """\brief Check if the GCFE instance with the id
00445     \a cfeId exists in the schema.
00446 
00447     \param  cfeId Calorimeter front-end id
00448 
00449     \return       1 if it exists, 0 if it doesn't.
00450     """
00451     return self.CFE.exists(cfeId)
00452 
00453 ## private:
00454 
00455   def __removeCFE(self, cfeId):
00456     self.CFE.remove(cfeId)
00457 
00458   def __addCFE(self, cfeId):
00459     return self.CFE.add(cfeId)
00460 
00461 
00462 class GCFE(gDb.Gdb):
00463   """\brief Calorimeter Front End node Record.
00464 
00465   Has GCFE specific registers and dataless commands.
00466 
00467   Valid Registers:
00468   - \c config_0
00469   - \c config_1
00470   - \c fle_dac
00471   - \c fhe_dac
00472   - \c log_acpt
00473   - \c rng_uld_dac
00474   - \c ref_dac
00475 
00476   Dataless Commands:
00477   - \c cmd_nop
00478 
00479   """
00480   __attrs = [
00481     # Registers
00482     gAttr.GattrRaw('config_0',    0, 2),
00483     gAttr.GattrRaw('config_1',    1, 2),
00484     gAttr.GattrRaw('fle_dac',     2, 2),
00485     gAttr.GattrRaw('fhe_dac',     3, 2),
00486     gAttr.GattrRaw('log_acpt',    4, 2),
00487     gAttr.GattrRaw('rng_uld_dac', 5, 2),
00488     gAttr.GattrRaw('ref_dac',     6, 2),
00489     # Dataless Commands
00490     gAttr.GattrDlc('cmd_nop',     0, 0)
00491     ]
00492 
00493   def __init__(self, client, parent, id):
00494     """\brief Initialize valid registers as Gattrs
00495 
00496     """
00497 
00498     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00499     # is dangerous therefore if the parent TEM is a broadcast node
00500     # the read and send methods are redefined so that we loop
00501     # over each TEM defined in the schema
00502     if parent.up().up().id() == gDb.Children.BCASTID:
00503       self.read = None
00504       self.load = self.__bcast_load
00505       self.send = self.__bcast_send
00506 
00507     if id < gDb.Lem.NCFES:
00508       addr = id
00509     elif id == gDb.Children.BCASTID:
00510       addr = gDb.Lem.CFEBCAST
00511     else:
00512       raise KeyError("*** gTEM: GCFE id %d is invalid" %(id))
00513     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr)
00514 
00515   def read(self, reg):
00516     return self.cmdrsp('CFE_read', self.up().up().up().addr(), self.up().up().addr(), self.up().addr(), self.addr(), reg, '!I')
00517 
00518   def load(self, reg, value):
00519     # If you modify this method, change __bcast_load as well
00520     return self.cmdrsp('CFE_load', self.up().up().up().addr(), self.up().up().addr(), self.up().addr(), self.addr(), reg, value)
00521 
00522   def send(self, cmd):
00523     # If you modify this method, change __bcast_send as well
00524     return self.cmdrsp('CFE_cmd', self.up().up().up().addr(), self.up().up().addr(), self.up().addr(), self.addr(), cmd)
00525 
00526   def __bcast_load(self, reg, value):
00527     for temId in self.up().up().up().up().TEM:
00528       rsp = self.cmdrsp('CFE_load', gDb.Lem.ADDR_TEM_BASE+temId, self.up().up().addr(), self.up().addr(), self.addr(), reg, value)
00529       if rsp.status() != 0: break
00530     return rsp
00531 
00532   def __bcast_send(self, cmd):
00533     for temId in self.up().up().up().up().TEM:
00534       rsp = self.cmdrsp('CFE_cmd', gDb.Lem.ADDR_TEM_BASE+temId, self.up().up().addr(), self.up().addr(), self.addr(), cmd)
00535       if rsp.status() != 0: break
00536     return rsp
00537 
00538 class GTCC(gDb.Gdb):
00539   """\brief Tracker Cable Controller node record.
00540 
00541   Has GTCC specific registers and dataless commands.
00542 
00543   Valid Registers:
00544   - \c configuration
00545   - \c input_mask
00546   - \c fifo_status
00547   - \c latched_status
00548   - \c event_timeouts
00549   - \c trg_alignment
00550 
00551   Dataless Commands:
00552   - \c cmd_nop
00553   - \c cmd_reset
00554 
00555   """
00556   __attrs = [
00557     # Registers
00558     gAttr.GattrRaw('configuration',   0, 4),
00559     gAttr.GattrRaw('input_mask',      1, 4),
00560     gAttr.GattrRaw('fifo_status',     2, 4),
00561     gAttr.GattrRaw('latched_status',  3, 4),
00562     gAttr.GattrRaw('event_timeouts',  4, 4),
00563     gAttr.GattrRaw('trg_alignment',   5, 4),
00564     # Dataless Commands
00565     gAttr.GattrDlc('cmd_nop',         0, 0, gAttr.REG_WRITE_ONLY),
00566     gAttr.GattrDlc('cmd_reset',       1, 0, gAttr.REG_WRITE_ONLY)
00567     ]
00568 
00569   def __init__(self, client, parent, id):
00570     """\brif Initialize valid registers as Gattrs.
00571 
00572     Assign default values to members
00573     """
00574 
00575     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00576     # is dangerous therefore if the parent TEM is a broadcast node
00577     # the read and send methods are redefined so that we loop
00578     # over each TEM defined in the schema
00579     if parent.id() == gDb.Children.BCASTID:
00580       self.read = None
00581       self.load = self.__bcast_load
00582       self.send = self.__bcast_send
00583 
00584     if id < gDb.Lem.NTCCS:
00585       addr = id
00586     elif id == gDb.Children.BCASTID:
00587       addr = gDb.Lem.TCCBCAST
00588     else:
00589       raise KeyError("*** gTEM: GTCC id %d is invalid" %(id))
00590     self.TRC = gDb.Children(self, GTRC)
00591     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr)
00592 
00593   def read(self, reg):
00594     return self.cmdrsp('TCC_read', self.up().addr(), self.addr(), reg, '!I')
00595 
00596   def load(self, reg, value):
00597     # If you modify this method, change __bcast_load as well
00598     return self.cmdrsp('TCC_load', self.up().addr(), self.addr(), reg, value)
00599 
00600   def send(self, cmd):
00601     # If you modify this method, change __bcast_send as well
00602     return self.cmdrsp('TCC_cmd', self.up().addr(), self.addr(), cmd)
00603 
00604   def __bcast_load(self, reg, value):
00605     for temId in self.up().up().TEM:
00606       rsp = self.cmdrsp('TCC_load', gDb.Lem.ADDR_TEM_BASE+temId, self.addr(), reg, value)
00607       if rsp.status() != 0: break
00608     return rsp
00609 
00610   def __bcast_send(self, cmd):
00611     for temId in self.up().up().TEM:
00612       rsp = self.cmdrsp('TCC_cmd', gDb.Lem.ADDR_TEM_BASE+temId, self.addr(), cmd)
00613       if rsp.status() != 0: break
00614     return rsp
00615 
00616   def downTRC(self, childId):
00617     """\brief Navigate to the GTRC indicated by \a childId
00618 
00619     \param  childId The id of the child GTRC
00620 
00621     \return         A GTRC object instance
00622     """
00623     return self.TRC.down(childId)
00624 
00625   def allTRC(self):
00626     """\brief Navigate to the broadcast GTRC
00627 
00628     \return The broadcast GTRC object instance
00629     """
00630     return self.TRC.all()
00631 
00632   def existsTRC(self, trcId):
00633     """\brief Check if the GTRC instance with the id
00634     \a trcId exists in the schema.
00635 
00636     \param  trcId Tracker readout controller id
00637 
00638     \return       1 if it exists, 0 if it doesn't.
00639     """
00640     return self.TRC.exists(trcId)
00641 
00642 ## private:
00643 
00644   def __removeTRC(self, trcId):
00645     self.TRC.remove(trcId)
00646 
00647   def __addTRC(self, trcId):
00648     return self.TRC.add(trcId)
00649 
00650 
00651 class GTRC(gDb.Gdb):
00652   """\brief Tracker Readout Controller node Record.
00653 
00654   Has GTRC specific registers and dataless commands.
00655 
00656   Valid Registers:
00657   - \c csr
00658   - \c sync
00659 
00660   Dataless Commands:
00661   - \c cmd_nop
00662   - \c cmd_reset
00663 
00664   """
00665   __attrs = [
00666     # Registers
00667     gAttr.GattrRaw('csr',       0, 8),
00668     gAttr.GattrRaw('sync',      1, 8),
00669     # Dataless Commands
00670     gAttr.GattrDlc('cmd_nop',   0, 0),
00671     gAttr.GattrDlc('cmd_reset', 1, 0)
00672     ]
00673 
00674   def __init__(self, client, parent, id):
00675     """\brief Initialize valid registers as Gattrs.
00676 
00677     Assign default values to members
00678     """
00679 
00680     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00681     # is dangerous therefore if the parent TEM is a broadcast node
00682     # the read and send methods are redefined so that we loop
00683     # over each TEM defined in the schema
00684     if parent.up().id() == gDb.Children.BCASTID:
00685       self.read = None
00686       self.load = self.__bcast_load
00687       self.send = self.__bcast_send
00688 
00689     if id < gDb.Lem.NTRCS:
00690       addr = id
00691     elif id == gDb.Children.BCASTID:
00692       addr = gDb.Lem.TRCBCAST
00693     else:
00694       raise KeyError("*** gTEM: GTRC id %d is invalid" %(id))
00695     self.TFE = gDb.Children(self, GTFE)
00696     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr)
00697 
00698   def read(self, reg):
00699     rsp = self.cmdrsp('TRC_read', self.up().up().addr(), self.up().addr(), self.addr(), reg, '!I', '!I')
00700     timestamp = rsp.timestamp()
00701     status    = rsp.status()
00702     payloads  = (rsp.payloads()[1], rsp.payloads()[0])
00703     return gRegister.Register(timestamp, status, payloads, 'II')
00704 
00705   def load(self, reg, value):
00706     # If you modify this method, change __bcast_load as well
00707     [lower, upper] = struct.unpack('II', struct.pack('Q', value))
00708     return self.cmdrsp('TRC_load', self.up().up().addr(), self.up().addr(), self.addr(), reg, upper, lower)
00709 
00710   def send(self, cmd):
00711     # If you modify this method, change __bcast_send as well
00712     return self.cmdrsp('TRC_cmd', self.up().up().addr(), self.up().addr(), self.addr(), cmd)
00713 
00714   def __bcast_load(self, reg, value):
00715     [lower, upper] = struct.unpack('II', struct.pack('Q', value))
00716     for temId in self.up().up().up().TEM:
00717       rsp = self.cmdrsp('TRC_load', gDb.Lem.ADDR_TEM_BASE+temId, self.up().addr(), self.addr(), reg, upper, lower)
00718       if rsp.status() != 0: break
00719     return rsp
00720 
00721   def __bcast_send(self, cmd):
00722     for temId in self.up().up().up().TEM:
00723       rsp = self.cmdrsp('TRC_cmd', gDb.Lem.ADDR_TEM_BASE+temId, self.up().addr(), self.addr(), cmd)
00724       if rsp.status() != 0: break
00725     return rsp
00726 
00727   def downTFE(self, childId):
00728     """\brief Navigate to the GTFE indicated by \a childId
00729 
00730     \param  childId The id of the child GTFE
00731 
00732     \return         A GTFE object instance
00733     """
00734     return self.TFE.down(childId)
00735 
00736   def allTFE(self):
00737     """\brief Navigate to the broadcast GTFE
00738 
00739     \return The broadcast GTFE object instance
00740     """
00741     return self.TFE.all()
00742 
00743   def existsTFE(self, tfeId):
00744     """\brief Check if the GTFE instance with the id
00745     \a tfeId exists in the schema.
00746 
00747     \param  tfeId Tracker front-end id
00748 
00749     \return       1 if it exists, 0 if it doesn't.
00750     """
00751     return self.TFE.exists(tfeId)
00752 
00753   def getNoisyChannelsByMask(self, mask, feId=None):
00754     """\brief Get the noisy channels for this RC or for a specific FE
00755     belonging to this RC based on the mask provided.
00756 
00757     \param  mask  A string containing one of 'calib', 'data' or 'trig'
00758     \param  feId  Front-end id.
00759 
00760     \return      If \a feId is None return a list of noisy channels.
00761                  If \a feId is not None return a bitmap of noisy channels.
00762     """
00763     LAYER_CC_PAIRS = {0:(0,1), 1:(0,1), 2:(3,2), 3:(3,2), 4:(5,4),
00764                       5:(5,4), 6:(6,7), 7:(6,7)
00765                      }
00766     tcc = self.up()
00767     tem = tcc.up()
00768     lat = tem.up()
00769     key = (tem.id(),LAYER_CC_PAIRS[tcc.id()]+(self.id(),))
00770     if key in lat._GLAT__noisyChannels[mask]:
00771       chList = lat._GLAT__noisyChannels[mask][key].getOnBits()
00772       if feId is not None:
00773         mask = 0L
00774         for ch in chList:
00775           chFE = ch / 64
00776           if chFE == feId:
00777             mask |= 1L << (ch % 64)
00778         return mask
00779       else:
00780         return chList
00781     else:
00782       if feId is not None:
00783         return 0L
00784       else:
00785         return []
00786 
00787 
00788   def getNoisyChannels(self, feId=None, calib=True, data=True, trig=True):
00789     """\brief Get the noisy channels for this RC or for a specific FE
00790     belonging to this RC.
00791 
00792     \param  feId  Front-end id.
00793     \param  calib Flag indicating whether calib mask noisy channels
00794                   should be included.
00795     \param  data  Flag indicating whether data mask noisy channels
00796                   should be included.
00797     \param  trig  Flag indicating whether trigger mask noisy channels
00798                   should be included.
00799 
00800     \return      If \a feId is None return a list of noisy channels.
00801                  If \a feId is not None return a bitmap of noisy channels.
00802     """
00803     if feId is None:
00804       calibChan = []
00805       dataChan  = []
00806       trigChan  = []
00807     else:
00808       calibChan = 0L
00809       dataChan  = 0L
00810       trigChan  = 0L
00811 
00812     if calib:
00813       calibChan = self.getNoisyChannelsByMask('calib', feId)
00814     if data:
00815       dataChan  = self.getNoisyChannelsByMask( 'data', feId)
00816     if trig:
00817       trigChan  = self.getNoisyChannelsByMask( 'trig', feId)
00818 
00819     if feId is None:
00820       chanList = []
00821       for maskList in (calibChan, dataChan, trigChan):
00822         for chan in maskList:
00823           if chan not in chanList:
00824             chanList.append(chan)
00825       return chanList
00826     else:
00827       return calibChan | dataChan | trigChan
00828 
00829   def getDeadChannelsByMask(self, mask, feId=None):
00830     """\brief Get the dead channels for this RC or for a specific FE
00831     belonging to this RC based on the mask provided.
00832 
00833     \param  mask  A string containing one of 'calib', 'data' or 'trig'
00834     \param  feId  Front-end id.
00835 
00836     \return      If \a feId is None return a list of dead channels.
00837                  If \a feId is not None return a bitmap of dead channels.
00838     """
00839     LAYER_CC_PAIRS = {0:(0,1), 1:(0,1), 2:(3,2), 3:(3,2), 4:(5,4),
00840                       5:(5,4), 6:(6,7), 7:(6,7)
00841                      }
00842     tcc = self.up()
00843     tem = tcc.up()
00844     lat = tem.up()
00845     key = (tem.id(),LAYER_CC_PAIRS[tcc.id()]+(self.id(),))
00846     if key in lat._GLAT__deadChannels[mask]:
00847       chList = lat._GLAT__deadChannels[mask][key].getOnBits()
00848       if feId is not None:
00849         mask = 0L
00850         for ch in chList:
00851           chFE = ch / 64
00852           if chFE == feId:
00853             mask |= 1L << (ch % 64)
00854         return mask
00855       else:
00856         return chList
00857     else:
00858       if feId is not None:
00859         return 0L
00860       else:
00861         return []
00862 
00863 
00864   def getDeadChannels(self, feId=None, calib=True, data=True, trig=True):
00865     """\brief Get the dead channels for this RC or for a specific FE
00866     belonging to this RC.
00867 
00868     \param  feId Front-end id.
00869     \param  calib Flag indicating whether calib mask noisy channels
00870                   should be included.
00871     \param  data  Flag indicating whether data mask noisy channels
00872                   should be included.
00873     \param  trig  Flag indicating whether trigger mask noisy channels
00874                   should be included.
00875 
00876     \return      If \a feId is None return a list of dead channels.
00877                  If \a feId is not None return a bitmap of dead channels.
00878     """
00879     if feId is None:
00880       calibChan = []
00881       dataChan  = []
00882       trigChan  = []
00883     else:
00884       calibChan = 0L
00885       dataChan  = 0L
00886       trigChan  = 0L
00887 
00888     if calib:
00889       calibChan = self.getDeadChannelsByMask('calib', feId)
00890     if data:
00891       dataChan  = self.getDeadChannelsByMask( 'data', feId)
00892     if trig:
00893       trigChan  = self.getDeadChannelsByMask( 'trig', feId)
00894 
00895     if feId is None:
00896       chanList = []
00897       for maskList in (calibChan, dataChan, trigChan):
00898         for chan in maskList:
00899           if chan not in chanList:
00900             chanList.append(chan)
00901       return chanList
00902     else:
00903       return calibChan | dataChan | trigChan
00904 
00905 
00906 ## private:
00907 
00908   def __removeTFE(self, tfeId):
00909     self.TFE.remove(tfeId)
00910 
00911   def __addTFE(self, tfeId):
00912     return self.TFE.add(tfeId)
00913 
00914 
00915 class GTFE(gDb.Gdb):
00916   """\brief Tracker Front-End node Record.
00917 
00918   Has GTFE specific registers and dataless commands.
00919 
00920   Valid Registers:
00921   - \c data_mask
00922   - \c calib_mask
00923   - \c trig_mask
00924   - \c dac
00925   - \c mode
00926 
00927   Dataless Commands:
00928   - \c cmd_nop
00929   - \c cmd_reset
00930   - \c cmd_calstrobe
00931   - \c cmd_readevent
00932 
00933   """
00934   __attrs = [# Registers
00935     gAttr.GattrRaw('data_mask',       0, 8),
00936     gAttr.GattrRaw('calib_mask',      1, 8),
00937     gAttr.GattrRaw('trig_mask',       2, 8),
00938     gAttr.GattrRaw('dac',             3, 8),
00939     gAttr.GattrRaw('mode',            4, 8),
00940     # Dataless Commands
00941     gAttr.GattrDlc('cmd_nop',         0, 0),
00942     gAttr.GattrDlc('cmd_reset',       2, 0),
00943     gAttr.GattrDlc('cmd_calstrobe',   3, 0),
00944     gAttr.GattrDlc('cmd_readevent',   4, 0)
00945     ]
00946 
00947   def __init__(self, client, parent, id):
00948     """\brief Initialize valid registers as Gattrs.
00949 
00950     Assign default values to members
00951     """
00952 
00953     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
00954     # is dangerous therefore if the parent TEM is a broadcast node
00955     # the read and send methods are redefined so that we loop
00956     # over each TEM defined in the schema
00957     if parent.up().up().id() == gDb.Children.BCASTID:
00958       self.read = None
00959       self.load = self.__bcast_load
00960       self.send = self.__bcast_send
00961 
00962     if id < gDb.Lem.NTFES:
00963       addr = id
00964     elif id == gDb.Children.BCASTID:
00965       addr = gDb.Lem.TFEBCAST
00966     else:
00967       raise KeyError("*** gTEM: GTFE id %d is invalid" %(id))
00968     gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr)
00969 
00970   def read(self, reg):
00971     rsp = self.cmdrsp('TFE_read', self.up().up().up().addr(), self.up().up().addr(), self.up().addr(), self.addr(), reg, '!I', '!I')
00972     timestamp = rsp.timestamp()
00973     status    = rsp.status()
00974     payloads  = (rsp.payloads()[1], rsp.payloads()[0])
00975     return gRegister.Register(timestamp, status, payloads, 'II')
00976 
00977   def load(self, reg, value):
00978     # If you modify this method, change __bcast_load as well
00979     [lower, upper] = struct.unpack('II', struct.pack('Q', value))
00980     return self.cmdrsp('TFE_load', self.up().up().up().addr(), self.up().up().addr(), self.up().addr(), self.addr(), reg, upper, lower)
00981 
00982   def send(self, cmd):
00983     # If you modify this method, change __bcast_send as well
00984     return self.cmdrsp('TFE_cmd', self.up().up().up().addr(), self.up().up().addr(), self.up().addr(), self.addr(), cmd)
00985 
00986   def __bcast_load(self, reg, value):
00987     [lower, upper] = struct.unpack('II', struct.pack('Q', value))
00988     for temId in self.up().up().up().up().TEM:
00989       rsp = self.cmdrsp('TFE_load', gDb.Lem.ADDR_TEM_BASE+temId, self.up().up().addr(), self.up().addr(), self.addr(), reg, upper, lower)
00990       if rsp.status() != 0: break
00991     return rsp
00992 
00993   def __bcast_send(self, cmd):
00994     for temId in self.up().up().up().up().TEM:
00995       rsp = self.cmdrsp('TFE_cmd', gDb.Lem.ADDR_TEM_BASE+temId, self.up().up().addr(), self.up().addr(), self.addr(), cmd)
00996       if rsp.status() != 0: break
00997     return rsp
00998 
00999 
01000 class GTIC(gDb.Gdb):
01001   """\brief Trigger Interface Controller.
01002 
01003   Has GTIC specific registers and dataless commands.
01004 
01005   Valid Registers:
01006   - \c power_supply
01007   - \c status
01008   - \c cal_in_mask
01009   - \c cal_lrs_mask
01010   - \c cal_lrs_counters
01011   - \c tkr_layer_enable_0
01012   - \c tkr_layer_enable_1
01013   - \c tkr_out_mask
01014   - \c tkr_out_lrs_mask
01015   - \c tkr_lrs_counter_0
01016   - \c tkr_lrs_counter_1
01017   - \c busy_lrs_mask
01018   - \c busy_lrs_counter
01019   - \c adcs
01020   - \c mux_config
01021   - \c tkr_biasdac
01022   - \c cal_biasdac
01023   - \c adc_tkr_digital_2_5v
01024   - \c adc_tkr_digital_2_5i
01025   - \c adc_tkr_analog_a_1_5v
01026   - \c adc_tkr_analog_a_1_5i
01027   - \c adc_tkr_analog_b_2_5v
01028   - \c adc_tkr_analog_b_2_5i
01029   - \c adc_tkr_bias_v
01030   - \c adc_tkr_bias_v0
01031   - \c adc_tkr_bias_i
01032   - \c adc_cal_digital_3_3v
01033   - \c adc_cal_digital_3_3i
01034   - \c adc_tkr_bias_v1
01035   - \c adc_cal_analog_3_3v
01036   - \c adc_cal_analog_3_3i
01037   - \c adc_cal_bias_v1
01038   - \c adc_cal_bias_v
01039   - \c adc_cal_bias_v0
01040   - \c adc_cal_bias_i
01041   - \c adc_28_v0
01042   - \c adc_tem_digital_3_3v
01043   - \c adc_tem_digital_3_3i
01044   - \c adc_28_v1
01045   - \c adc_afee0_t0
01046   - \c adc_afee0_t1
01047   - \c adc_afee1_t0
01048   - \c adc_afee1_t1
01049   - \c adc_afee2_t0
01050   - \c adc_afee2_t1
01051   - \c adc_afee3_t0
01052   - \c adc_afee3_t1
01053   - \c adc_tkr_c0_t0
01054   - \c adc_tkr_c0_t1
01055   - \c adc_tkr_c1_t0
01056   - \c adc_tkr_c1_t1
01057   - \c adc_tkr_c2_t0
01058   - \c adc_tkr_c2_t1
01059   - \c adc_tkr_c3_t0
01060   - \c adc_tkr_c3_t1
01061   - \c adc_tkr_c4_t0
01062   - \c adc_tkr_c4_t1
01063   - \c adc_tkr_c5_t0
01064   - \c adc_tkr_c5_t1
01065   - \c adc_tkr_c6_t0
01066   - \c adc_tkr_c6_t1
01067   - \c adc_tkr_c7_t0
01068   - \c adc_tkr_c7_t1
01069 
01070   Deadtime Counters:
01071   - \c sat_cal_lrs_ctr_0
01072   - \c sat_cal_lrs_ctr_1
01073   - \c sat_tkr_lrs_ctr_0
01074   - \c sat_tkr_lrs_ctr_1
01075   - \c sat_tkr_lrs_ctr_2
01076   - \c sat_tkr_lrs_ctr_3
01077   - \c sat_deadtime_lrs_ctr
01078 
01079   Pseudo Registers:
01080   - \c psd_tkr_bias_i
01081   - \c psd_cal_bias_i
01082   - \c psd_tem_i
01083 
01084   Dataless Commands:
01085   - \c cmd_nop
01086   - \c cmd_reset
01087 
01088   """
01089   __attrs = [
01090     # Registers
01091     gAttr.GattrReg('power_supply',           0,  4),
01092     gAttr.GattrReg('status',                 1,  4),
01093     gAttr.GattrReg('cal_in_mask',            2,  4),
01094     gAttr.GattrReg('cal_lrs_mask',           3,  4),
01095     gAttr.GattrReg('cal_lrs_counters',       4,  4),
01096     gAttr.GattrReg('tkr_layer_enable_0',     5,  4),
01097     gAttr.GattrReg('tkr_layer_enable_1',     6,  4),
01098     gAttr.GattrReg('tkr_out_mask',           7,  2),
01099     gAttr.GattrReg('tkr_out_lrs_mask',       8,  2),
01100     gAttr.GattrReg('tkr_lrs_counter_0',     10,  4),
01101     gAttr.GattrReg('tkr_lrs_counter_1',     11,  4),
01102     gAttr.GattrReg('busy_lrs_mask',         12,  2),
01103     gAttr.GattrReg('busy_lrs_counter',      13,  4),
01104     gAttr.GattrReg('adcs',                  14, 16),
01105     gAttr.GattrReg('mux_config',            15,  4),
01106     gAttr.GattrReg('tkr_biasdac',           16,  4),
01107     gAttr.GattrReg('cal_biasdac',           17,  4),
01108     gAttr.GattrReg('adc_tkr_digital_2_5v',  18,  2, gAttr.REG_READ_ONLY),
01109     gAttr.GattrReg('adc_tkr_digital_2_5i',  19,  2, gAttr.REG_READ_ONLY),
01110     gAttr.GattrReg('adc_tkr_analog_a_1_5v', 20,  2, gAttr.REG_READ_ONLY),
01111     gAttr.GattrReg('adc_tkr_analog_a_1_5i', 21,  2, gAttr.REG_READ_ONLY),
01112     gAttr.GattrReg('adc_tkr_analog_b_2_5v', 22,  2, gAttr.REG_READ_ONLY),
01113     gAttr.GattrReg('adc_tkr_analog_b_2_5i', 23,  2, gAttr.REG_READ_ONLY),
01114     gAttr.GattrReg('adc_tkr_bias_v',        24,  2, gAttr.REG_READ_ONLY),
01115     gAttr.GattrReg('adc_tkr_bias_v0',       24,  2, gAttr.REG_READ_ONLY),
01116     gAttr.GattrReg('adc_tkr_bias_i',        25,  2, gAttr.REG_READ_ONLY),
01117     gAttr.GattrReg('adc_cal_digital_3_3v',  26,  2, gAttr.REG_READ_ONLY),
01118     gAttr.GattrReg('adc_cal_digital_3_3i',  27,  2, gAttr.REG_READ_ONLY),
01119     gAttr.GattrReg('adc_tkr_bias_v1',       27,  2, gAttr.REG_READ_ONLY),
01120     gAttr.GattrReg('adc_cal_analog_3_3v',   28,  2, gAttr.REG_READ_ONLY),
01121     gAttr.GattrReg('adc_cal_analog_3_3i',   29,  2, gAttr.REG_READ_ONLY),
01122     gAttr.GattrReg('adc_cal_bias_v1',       29,  2, gAttr.REG_READ_ONLY),
01123     gAttr.GattrReg('adc_cal_bias_v',        30,  2, gAttr.REG_READ_ONLY),
01124     gAttr.GattrReg('adc_cal_bias_v0',       30,  2, gAttr.REG_READ_ONLY),
01125     gAttr.GattrReg('adc_cal_bias_i',        31,  2, gAttr.REG_READ_ONLY),
01126     gAttr.GattrReg('adc_28_v0',             31,  2, gAttr.REG_READ_ONLY),
01127     gAttr.GattrReg('adc_tem_digital_3_3v',  32,  2, gAttr.REG_READ_ONLY),
01128     gAttr.GattrReg('adc_tem_digital_3_3i',  33,  2, gAttr.REG_READ_ONLY),
01129     gAttr.GattrReg('adc_28_v1',             33,  2, gAttr.REG_READ_ONLY),
01130     gAttr.GattrReg('adc_afee0_t0',          34,  2, gAttr.REG_READ_ONLY),
01131     gAttr.GattrReg('adc_afee0_t1',          35,  2, gAttr.REG_READ_ONLY),
01132     gAttr.GattrReg('adc_afee1_t0',          36,  2, gAttr.REG_READ_ONLY),
01133     gAttr.GattrReg('adc_afee1_t1',          37,  2, gAttr.REG_READ_ONLY),
01134     gAttr.GattrReg('adc_afee2_t0',          38,  2, gAttr.REG_READ_ONLY),
01135     gAttr.GattrReg('adc_afee2_t1',          39,  2, gAttr.REG_READ_ONLY),
01136     gAttr.GattrReg('adc_afee3_t0',          40,  2, gAttr.REG_READ_ONLY),
01137     gAttr.GattrReg('adc_afee3_t1',          41,  2, gAttr.REG_READ_ONLY),
01138     gAttr.GattrReg('adc_tkr_c0_t0',         42,  2, gAttr.REG_READ_ONLY),
01139     gAttr.GattrReg('adc_tkr_c0_t1',         43,  2, gAttr.REG_READ_ONLY),
01140     gAttr.GattrReg('adc_tkr_c1_t0',         44,  2, gAttr.REG_READ_ONLY),
01141     gAttr.GattrReg('adc_tkr_c1_t1',         45,  2, gAttr.REG_READ_ONLY),
01142     gAttr.GattrReg('adc_tkr_c2_t0',         46,  2, gAttr.REG_READ_ONLY),
01143     gAttr.GattrReg('adc_tkr_c2_t1',         47,  2, gAttr.REG_READ_ONLY),
01144     gAttr.GattrReg('adc_tkr_c3_t0',         48,  2, gAttr.REG_READ_ONLY),
01145     gAttr.GattrReg('adc_tkr_c3_t1',         49,  2, gAttr.REG_READ_ONLY),
01146     gAttr.GattrReg('adc_tkr_c4_t0',         50,  2, gAttr.REG_READ_ONLY),
01147     gAttr.GattrReg('adc_tkr_c4_t1',         51,  2, gAttr.REG_READ_ONLY),
01148     gAttr.GattrReg('adc_tkr_c5_t0',         52,  2, gAttr.REG_READ_ONLY),
01149     gAttr.GattrReg('adc_tkr_c5_t1',         53,  2, gAttr.REG_READ_ONLY),
01150     gAttr.GattrReg('adc_tkr_c6_t0',         54,  2, gAttr.REG_READ_ONLY),
01151     gAttr.GattrReg('adc_tkr_c6_t1',         55,  2, gAttr.REG_READ_ONLY),
01152     gAttr.GattrReg('adc_tkr_c7_t0',         56,  2, gAttr.REG_READ_ONLY),
01153     gAttr.GattrReg('adc_tkr_c7_t1',         57,  2, gAttr.REG_READ_ONLY),
01154     # Low Rate Science Counters
01155     gAttr.GattrReg('sat_cal_lrs_ctr_0',     58,  4, gAttr.REG_READ_ONLY),
01156     gAttr.GattrReg('sat_cal_lrs_ctr_1',     59,  4, gAttr.REG_READ_ONLY),
01157     gAttr.GattrReg('sat_tkr_lrs_ctr_0',     60,  4, gAttr.REG_READ_ONLY),
01158     gAttr.GattrReg('sat_tkr_lrs_ctr_1',     61,  4, gAttr.REG_READ_ONLY),
01159     gAttr.GattrReg('sat_tkr_lrs_ctr_2',     62,  4, gAttr.REG_READ_ONLY),
01160     gAttr.GattrReg('sat_tkr_lrs_ctr_3',     63,  4, gAttr.REG_READ_ONLY),
01161     gAttr.GattrReg('sat_deadtime_lrs_ctr',  64,  4, gAttr.REG_READ_ONLY),
01162     # Pseudo-registers
01163     gAttr.GattrReg('psd_tkr_bias_i',        65,  4, gAttr.REG_READ_ONLY),
01164     gAttr.GattrReg('psd_cal_bias_i',        66,  4, gAttr.REG_READ_ONLY),
01165     gAttr.GattrReg('psd_tem_i',             67,  4, gAttr.REG_READ_ONLY),
01166     # Dataless Commands
01167     gAttr.GattrDlc('cmd_nop',                0,  0),
01168     gAttr.GattrDlc('cmd_reset',              1,  0)
01169     ]
01170   __ADCS                 = 14
01171   __MUX_CONFIG           = 15
01172   __CAL_BIASDAC          = 17
01173   __ADC_TKR_DIGITAL_2_5V = 18
01174   __ADC_TKR_BIAS_V0      = 24
01175   __ADC_TKR_BIAS_V1      = 27
01176   __ADC_CAL_BIAS_V0      = 30
01177   __ADC_CAL_BIAS_V1      = 29
01178   __ADC_28_V0            = 31
01179   __ADC_28_V1            = 33
01180   __SAT_CAL_LRS_CTR_0    = 58
01181   __PSD_TKR_BIAS_I       = 65
01182   __PSD_CAL_BIAS_I       = 66
01183   __PSD_TEM_I            = 67
01184   __STALE_TMO = 1.0     # Timeout in seconds before considering adcs value stale
01185 
01186   def __init__(self, client, parent):
01187     """\brief Initialize valid registers as Gattrs.
01188 
01189     """
01190 
01191     # As stated in LTE-322, using ADDR_SLV_BCAST for a TEM broadcast
01192     # is dangerous therefore if the parent TEM is a broadcast node
01193     # the read and send methods are redefined so that we loop
01194     # over each TEM defined in the schema
01195     if parent.id() == gDb.Children.BCASTID:
01196       self.read = None
01197       self.load = self.__bcast_load
01198       self.send = self.__bcast_send
01199 
01200     self.__adcs = 5*[(None, 0)]           # [gRegister.Register, time.time()]
01201     gDb.Gdb.__init__(self, client, parent, 0, self.__attrs)
01202 
01203   def satCtrEnable(self, reg):
01204     """\brief Enable the specified saturation counter.
01205     By default all saturation counters are disabled.
01206 
01207     \param reg Register id of the saturation counter.
01208                Can be retrieved by calling tic.regs['regname'].id().
01209     \return A Response object
01210     """
01211     return self.cmdrsp('TEM_GTIC_sat_enable', self.up().addr(), reg)
01212 
01213   def satCtrDisable(self, reg):
01214     """\brief Disable the specified saturation counter.
01215     By default all saturation counters are disabled.
01216 
01217     \param reg Register id of the saturation counter.
01218                Can be retrieved by calling tic.regs['regname'].id().
01219     \return A Response object
01220     """
01221     return self.cmdrsp('TEM_GTIC_sat_disable', self.up().addr(), reg)
01222 
01223   def satCtrLoopEnable(self):
01224     """\brief Enable the update loop that updates all
01225     saturation counter pseudoregisters.
01226 
01227     \return A Response object
01228     """
01229     return self.cmdrsp('TEM_GTIC_sat_loop_enable')
01230 
01231   def satCtrLoopDisable(self):
01232     """\brief Disable the update loop that updates all
01233     saturation counter pseudoregisters.
01234 
01235     \return A Response object
01236     """
01237     return self.cmdrsp('TEM_GTIC_sat_loop_disable')
01238 
01239   def satCtrSetLoopDelay(self, delay):
01240     """\brief Set the update loop interval for
01241     saturation counter pseudoregisters.
01242 
01243     \param Set the saturation counter update loop delay
01244            in 1/60 second ticks. The default is 30 (2 Hz).
01245 
01246     \return A Response object
01247     """
01248     return self.cmdrsp('TEM_GTIC_sat_loop_delay', delay)
01249 
01250   def read(self, reg):
01251     if (reg != GTIC.__ADCS) and (reg <= GTIC.__CAL_BIASDAC):
01252       return self.cmdrsp('TIC_read', self.up().addr(), reg, '!I')
01253     elif (reg == GTIC.__ADCS):
01254       rsp = self.cmdrsp('TIC_ENV_read', self.up().addr(), '!HHHHHHHH', '!H', '!H')
01255       payloads = rsp.payloads()
01256       payload = [ payloads[0]         +
01257                  (payloads[1] << 12L) +
01258                  (payloads[2] << 24L) +
01259                  (payloads[3] << 36L) +
01260                  (payloads[4] << 48L) +
01261                  (payloads[5] << 60L) +
01262                  (payloads[6] << 72L) +
01263                  (payloads[7] << 84L) +
01264                  (payloads[8] << 96L) +
01265                  (payloads[9] << 99L)
01266                 ]
01267       return gRegister.Register(rsp.timestamp(), rsp.status(), payload, 'H')
01268     elif (reg < GTIC.__SAT_CAL_LRS_CTR_0):
01269       return self.__fetchReg(reg)
01270     elif (reg < GTIC.__PSD_TKR_BIAS_I):
01271       return self.cmdrsp('TEM_GTIC_read_sat', self.up().addr(), reg, '!I', '!Q')
01272     elif (reg == GTIC.__PSD_TKR_BIAS_I):
01273       return self.__diffReg(GTIC.__ADC_TKR_BIAS_V0, GTIC.__ADC_TKR_BIAS_V1)
01274     elif (reg == GTIC.__PSD_CAL_BIAS_I):
01275       return self.__diffReg(GTIC.__ADC_CAL_BIAS_V0, GTIC.__ADC_CAL_BIAS_V1)
01276     elif (reg == GTIC.__PSD_TEM_I):
01277       return self.__diffReg(GTIC.__ADC_28_V0, GTIC.__ADC_28_V1)
01278     else:
01279       raise Exception, "Invalid GTIC register %d" % (reg)
01280 
01281   def load(self, reg, value):
01282     # If you modify this method, change __bcast_load as well
01283     if (reg < GTIC.__SAT_CAL_LRS_CTR_0):
01284       return self.cmdrsp('TIC_load', self.up().addr(), reg, value)
01285     elif (reg < GTIC.__PSD_TKR_BIAS_I):
01286       return self.cmdrsp('TEM_GTIC_sat_clear', self.up().addr(), reg)
01287     else:
01288       raise Exception, "Invalid GTIC register %d" % (reg)
01289 
01290   def send(self, cmd):
01291     # If you modify this method, change __bcast_send as well
01292     return self.cmdrsp('TIC_cmd', self.up().addr(), cmd)
01293 
01294   def __bcast_load(self, reg, value):
01295     for temId in self.up().up().TEM:
01296       if (reg < GTIC.__SAT_CAL_LRS_CTR_0):
01297         rsp = self.cmdrsp('TIC_load', gDb.Lem.ADDR_TEM_BASE+temId, reg, value)
01298         if rsp.status() != 0: break
01299       elif (reg < GTIC.__PSD_TKR_BIAS_I):
01300         rsp = self.cmdrsp('TEM_GTIC_sat_clear', gDb.Lem.ADDR_TEM_BASE+temId, reg)
01301         if rsp.status() != 0: break
01302       else:
01303         raise Exception, "Invalid GTIC register %d" % (reg)
01304     return rsp
01305 
01306   def __bcast_send(self, cmd):
01307     for temId in self.up().up().TEM:
01308       rsp = self.cmdrsp('TIC_cmd', gDb.Lem.ADDR_TEM_BASE+temId, cmd)
01309       if rsp.status() != 0: break
01310     return rsp
01311 
01312   def __fetchReg(self, reg):
01313     """\brief Fetch the value of an item from the ADC conversion data block,
01314     updating the block if it is deemed to be stale.
01315     \param reg - The item in the ADC conversion block to fetch
01316     \return A gRegister object containing the requested item
01317     """
01318     mux   = (reg - 18) / 8
01319     which = (reg - 18) % 8
01320     now = time.time()
01321     (rsp, rt) = self.__adcs[mux]
01322     if ((rsp is None) or (now - rt) > GTIC.__STALE_TMO):
01323       rsp = self.cmdrsp('TIC_ENV_acquire', self.up().addr(), mux, '!HHHHHHHH', '!H', '!H')
01324       channel = rsp.payloads()[8]
01325       valid   = rsp.payloads()[9]
01326       if not valid:
01327         status = gException.LATInterfaceStatus.status('OCS_BDADC')
01328         raise gException.LATInterfaceException(status)
01329       if channel != mux:
01330         status = gException.LATInterfaceStatus.status('OCS_GRPADC')
01331         raise gException.LATInterfaceException(status)
01332       self.__adcs[mux] = (rsp, now)
01333     timestamp = rsp.timestamp()
01334     status    = rsp.status()
01335     payloads  = rsp.payloads()[which:which+1]
01336     return gRegister.Register(timestamp, status, payloads, 'H')
01337 
01338   def __diffReg(self, reg1, reg2):
01339     """\brief Calculate the difference between two registers to form a
01340     pseudo-register result.  Order is result = reg2 - reg1.
01341     \param reg1 - First register
01342     \param reg2 - Second register
01343     \return A gRegister object containing reg2 - reg1
01344     """
01345     rsp1 = self.__fetchReg(reg1)
01346     rsp2 = self.__fetchReg(reg2)
01347     timestamp = rsp2.timestamp()
01348     payloads  = [rsp2.value() - rsp1.value()]
01349     status    = rsp2.status()
01350     if status == 0:  status = rsp1.status()
01351     return gRegister.Register(timestamp, status, payloads, 'H')

Generated on Fri Jul 21 13:26:29 2006 for LATTE R04-12-00 by doxygen 1.4.3