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

TrgGem.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 __facility__ = "Online"
00011 __abstract__ = "GLAST LAT Coincidence based Trigger System Interface classes"
00012 __author__   = "Jim Panetta <panetta@slac.stanford.edu> SLAC - GLAST I&T"
00013 __date__     = "2/14/04"
00014 __version__  = "$Revision: 2.9 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 """TrgGem: This file implements the hardware register access to the GEM"""
00021 
00022 from TrgGemRegisters      import TrgGemRegisters
00023 from TrgGemCounters       import *
00024 from LATTE.database.gGEM  import GGEM
00025 
00026 class TrgGem(TrgGemRegisters):
00027   """\brief Trigger Global Trigger Electronics Module Interface class definition
00028   This class implements the hardware register access to the GEM
00029   """
00030   __SOLICIT_MASK = 0x40
00031 
00032   def __init__(self):
00033     """\brief TrgGem constructor
00034     """
00035     TrgGemRegisters.__init__(self)
00036 
00037     self.__condValue = None
00038     self.__glt       = None
00039 
00040   def GEM(self, glt = None):
00041     """\brief GEM function
00042     \param glt:  a GGEM object
00043     \return a GGEM object
00044 
00045     This function sets and/or the GGEM hardware implementation used by
00046     TrgGem.
00047     """
00048     if ( glt is not None ):
00049       if ( not isinstance(glt,GGEM) ):
00050         raise AssertionError, "the glt object passed is not a GGEM"
00051       self.__glt = glt
00052       self.__epuaddr = glt.getEPUaddr()
00053     return self.__glt
00054 
00055   def __commit(self):
00056     """\brief Private commit function
00057 
00058     This function commits the configuration defined by this
00059     TrgGem object to the hardware.  It does *all* the registers.
00060     """
00061     gem = self.GEM()
00062 
00063     # set up the counter accesses and reset them
00064     self.__triggerCounters = TrgGemTriggerCounters(gem)
00065     self.__tileCounters    = TrgGemTileCounters(gem)
00066     self.__cnoCounters     = TrgGemCnoCounters(gem)
00067     self.__cmdCounters     = TrgGemCmdCounters(gem)
00068     self.__eventCounter    = TrgGemEventCounter(gem)
00069     self.__ppsTimer        = TrgGemPPSTimer(gem)
00070     self.__triggerCounters.reset()
00071     self.__tileCounters.reset()
00072     self.__cnoCounters.reset()
00073     self.__cmdCounters.reset()
00074     self.__eventCounter.reset()
00075 
00076     # Pass the GEM to TrgGemSequence and TrgGemPeriodicCondition objects
00077     self.sequence()._TrgGemSequence__setGEM(gem)
00078     self.periodicCondition()._TrgGemPeriodicCondition__setGEM(gem)
00079 
00080     # set all engine destination addresses.
00081     # Because engines can't have a real HW dependence, this is done by cheating:
00082     #   replace each instance of the TrgEngineRequest.destination function
00083     #   with a local private function.
00084     for engineNo in range(TrgObject.ENGINE_NUMBER_MAX + 1):
00085       self.engines().engine(engineNo).request().destination = self.__getDestinationFromEPU
00086 
00087     gemw = gem.downGEMW()
00088     gemw.WINDOW_OPEN_MASK = 0               # all disabled at startup by default
00089 
00090     # print "setting command registers"
00091     # Command registers (GEMC)
00092     gemc = gem.downGEMC()
00093     gemc.CONFIGURATION         = self.configurationRegister()
00094     # NEVER EVER touch the ADDRESS register.  Ever.  Really.
00095     gemc.PERIODIC_MODE         = self.periodicModeRegister()
00096     gemc.PERIODIC_LIMITS       = self.periodicLimitRegister()
00097     gemc.PERIODIC_RATE         = self.periodicRateRegister()
00098     # gemc.SEQUENCE              = self.sequenceRegister()   # commented out to set sequence in rcStartRun
00099     gemc.CR_STATISTICS         = 0    # Always reset statistics
00100     gemc.EVENT_STATISTICS      = 0    # Always reset statistics
00101 
00102     # print "setting TAM"
00103     # TAM generator (GEMMG)
00104     gemmg = gem.downGEMMG()
00105     if gemmg is None:
00106       raise RuntimeError, "GEM has no GEMMG"
00107     regList = gemmg.regs.values()           # get the list of registers
00108     for reg in regList:
00109       if reg.size() > 0 and not reg.isDeprecated():
00110         reg.set(self.templateRegister(reg.id()))
00111 
00112     # print "setting statistics"
00113     # Statistics registers (GEMST)
00114     gemst = gem.downGEMST()
00115     if gemst is None:
00116       raise RuntimeError, "GEM has no GEMST"
00117     regList = gemst.regs.values()           # get the list of registers
00118     for reg in regList:
00119       if reg.size() > 0 and not reg.isDeprecated():
00120         reg.set(0)                            # Reset all to zero
00121 
00122     # print "setting scheduler"
00123     # Scheduler Registers (GEMSC)
00124     gemsc = gem.downGEMSC()
00125     if gemsc is None:
00126       raise RuntimeError, "GEM has no GEMSC"
00127     regList = gemsc.regs.values()           # get the list of registers
00128     for reg in regList:
00129       if reg.size() > 0 and not reg.isDeprecated():
00130         reg.set(self.lookupTableRegister(reg.id()))
00131 
00132     # print "setting roi"
00133     # ROI Registers (GEMVG)
00134     gemvg = gem.downGEMVG()
00135     if gemvg is None:
00136       raise RuntimeError, "GEM has no GEMVG"
00137     regList = gemvg.regs.values()           # get the list of registers
00138     for reg in regList:
00139       if reg.size() > 0 and not reg.isDeprecated():
00140         reg.set(self.roiRegister(reg.id()))
00141 
00142     # print "setting input enables"
00143     # Input Enable Registers (GEMIE)
00144     gemie = gem.downGEMIE()
00145     if gemie is None:
00146       raise RuntimeError, "GEM has no GEMIE"
00147     #ST 6/14/05
00148     #regList = gemie.regs.values()           # get the list of registers
00149     #for reg in regList:
00150 
00151     # The above two lines have been replaced by the following line to support
00152     # the older GASUs. This is outlined in JIRA OACD-3 which dictates that to
00153     # avoid overwriting the TILES_000_013 register, the EXTERNAL register has to
00154     # be written first. In order for this to happen, a new method attrIter has
00155     # been added to the Gdb class which allows iterating the attributes in the
00156     # same order as they are declared in the node's __attrs member. The EXTERNAL
00157     # register has now been specified as the first register in this list so it
00158     # is guaranteed to be modified first.
00159     for reg in gemie.attrIter():
00160       if reg.size() > 0 and not reg.isDeprecated():
00161         setting = self.__ieRegister(reg.id())  # private function below
00162         if setting is not None:
00163           reg.set(setting)
00164 
00165     # print "setting windowing"
00166     # Window Registers (GEMW)
00167     gemw = gem.downGEMW()
00168     if gemw is None:
00169       raise RuntimeError, "GEM has no GEMW"
00170     gemw.WINDOW_WIDTH = self.width()
00171     gemw.WINDOW_OPEN_MASK = 0               # all disabled at startup by default
00172 
00173   def __getDestinationFromEPU(self):
00174     return self.__epuaddr
00175 
00176   def __ieRegister(self, registerNumber):
00177     # routine that maps the input-enable registers to the register functions
00178     # 18 input enable registers.
00179     # 0-3 Tower Inputs
00180     # 4 acdCNO
00181     # 5-16 ACD veto enables
00182     # 17 Tower_busy enable
00183     if 0 <= registerNumber <= 3:
00184       return self.towerEnableRegister(registerNumber)
00185     if 4 == registerNumber:
00186       return self.cnoEnableRegister()
00187     if 5 <= registerNumber <= 16:
00188       return self.tileEnableRegister(registerNumber - 5)
00189     if 17 == registerNumber:
00190       try:  # special try block to allow Run Control to override register
00191         return self.towerBusyEnableRegister()
00192       except NotImplementedError:
00193         return None
00194     if 18 == registerNumber:
00195       return self.externalEnableRegister()
00196     # shouldn't get here
00197     raise IndexError, "registerNumber out of range 0..18"
00198 
00199   ############### Pure virtual function implementation
00200   def version(self):
00201     cfg = self.GEM().GEMC.CONFIGURATION
00202     return ( ( cfg >> 16 ) & 0xffff )
00203 
00204   def solicit(self):
00205     # transmit the GEM's TRIGGER dataless command
00206     self.GEM().downGEMC().CMD_TRIGGER = 1
00207 
00208   def enable(self, mask=None):
00209     if mask is not None:
00210       outMask = mask
00211     elif self.conditions() is not None:
00212       outMask = self.conditions().value()
00213     else:
00214       raise AssertionError, "Attempting to enable a TrgConditionsValue of None"
00215     self.GEM().downGEMW().WINDOW_OPEN_MASK = outMask
00216 
00217   def disable(self):
00218     self.GEM().downGEMW().WINDOW_OPEN_MASK = 0
00219 
00220   def triggerCounters(self):
00221     return self.__triggerCounters
00222 
00223   def tileCounters(self):
00224     return self.__tileCounters
00225 
00226   def cnoCounters(self):
00227     return self.__cnoCounters
00228 
00229   def cmdCounters(self):
00230     return self.__cmdCounters
00231 
00232   def eventCounter(self):
00233     return self.__eventCounter
00234 
00235   def ppsTimer(self):
00236     return self.__ppsTimer
00237 
00238   def shut(self, marker):
00239     """Implementation of the shut function.
00240     """
00241     gemw  = self.GEM().GEMW
00242     gemmg = self.GEM().GEMMG
00243     gemsc = self.GEM().GEMSC
00244 
00245     #0) disable triggers
00246     self.disable()
00247 
00248     #1) Replace engine 0 with a marker engine
00249     from TrgEngine import TrgInjectMarker
00250     newEngine = TrgInjectMarker(marker)
00251     newTAM = self._TrgGemRegisters__parseEngine(newEngine)
00252     oldTAM = gemmg.ENGINE_0
00253     gemmg.ENGINE_0 = newTAM
00254 
00255     #2) replace contents of all schedulers with solicited with (Engine) 0
00256     scheduler = ( 0x00000000L )               # Everything's 0!
00257     regList = gemsc.regs.values()
00258     oldSched = {}    # dictionary keyed on register names
00259     for reg in regList:
00260       oldSched[reg.getName()] = reg.get()
00261       reg.set(scheduler)
00262 
00263     #3) Change conditions to be solicit only, solicit a trigger and disable
00264     gemw.WINDOW_OPEN_MASK = TrgGem.__SOLICIT_MASK
00265     self.solicit()
00266     self.disable()
00267 
00268     #4) Put the original contents of scheduler 0x40 back, and put the TAM back
00269     for reg in regList:
00270       reg.set(oldSched[reg.getName()])
00271 
00272     gemmg.ENGINE_0 = oldTAM
00273 
00274     #5) Put the trigger conditions back
00275     self.enable()
00276 

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