00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2003 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__ = "Test application for inducing and detecting event errors" 00012 __author__ = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = "2005/03/22" 00014 __version__ = "$Revision: 1.1 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import threading 00020 import logging as log 00021 00022 from LATTE.runcontrol.rcTransitions import rcTransitions 00023 from LATTE.runcontrol.ArgumentImpl import ArgumentImpl 00024 00025 from support.SimpleGasuExample import * 00026 from support.MiniGLTExample import * 00027 00028 00029 # Example application implementation. 00030 # Note that the name of the class must be userApplication. 00031 # Look at rcTransitions for names of other transition methods that can be used. 00032 class userApplication(rcTransitions): 00033 "Implmentation class for a user application" 00034 def __init__(self, gui, userId, debug): 00035 rcTransitions.__init__(self, gui, userId, debug) 00036 log.debug("userApplication.__init__()") 00037 self.__eventSem = threading.Semaphore(0) 00038 self.__cmdSynchSem = threading.Semaphore(0) 00039 self.__tpe = 0 00040 self.__pkte = 0 00041 00042 def getName(self): 00043 return __name__ 00044 00045 def setup(self): 00046 log.debug("userApplication.setup()") 00047 00048 # Get a TEM instance 00049 if self.lat.TEMcnt() == 1: 00050 tem = self.lat.TEM[self.lat.TEM.keys()[0]] 00051 elif self.lat.TEMcnt() > 1: 00052 tem = self.lat.TEM.all() 00053 else: 00054 log.fatal("No TEM(s) found in the schema") 00055 return -1 00056 00057 # reset the TEM since we are going to modify DATA_MASKS 00058 tem.CMD_RESET = 1 00059 00060 # clear TEM stats reg 00061 tem.COMMAND_RESPONSE = 0 00062 00063 # clear TEM status reg 00064 tem.STATUS = 0 00065 00066 # enable CAL, disable TKR, no diag # 0x10FF for diag 00067 tem.DATA_MASKS = 0x00FF 00068 00069 # TEM config reg # set TEM timeout 00070 tem.CONFIGURATION = 0 00071 00072 #status = gTEMread( __GT, temId, TEM_REG_CONFIGURATION, &payload); 00073 #printf("tem config reg = 0x%08x\n", payload); 00074 00075 # enable output in our GCCCs 00076 # broadcast load of GCCC_REG_CONFIGURATION 00077 00078 bcast_ccc = tem.allCCC() 00079 bcast_ccc.CONFIGURATION = 0x80000000L 00080 00081 # disable all GCRCs in all GCCCs via broadcast # GCCC_REG_LAYER_MASK_0, GCCC_REG_LAYER_MASK_1 00082 bcast_ccc.LAYER_MASK_0 = 0xFFFFFFFFL 00083 bcast_ccc.LAYER_MASK_1 = 0xFFFFFFFFL 00084 ccc2 = tem.downCCC(2) # O$GCCC_02 00085 ccc2.LAYER_MASK_1 = 0x3BFD3FFF 00086 00087 # large timeouts for all GCCCs 00088 # broadcast load of GCCC_REG_EVENT_TIMEOUTS 00089 bcast_ccc.EVENT_TIMEOUTS = 0x0 00090 #status = gGCCCread( __GT, temId, 1, GCCC_REG_EVENT_TIMEOUTS, &payload); 00091 #printf("gccc register event timeouts = 0x%08x\n", payload); 00092 00093 # Two choices for the trigger, GEM and MiniGLT 00094 if self.lat.existsGEM(): 00095 self.trigger( SimpleGasuExample() ) 00096 else: 00097 self.trigger( MiniGLTExample() ) 00098 00099 # A state transition can be rejected by not returning None 00100 return None 00101 00102 def startRun(self): 00103 log.debug("userApplication.startRun()") 00104 00105 self.__cnt = 5 00106 00107 # Spawn a thread to synchronize commands with events 00108 # This must happen after triggers are enabled 00109 self.__cmdSynchQuit = False 00110 00111 # reset internal variables 00112 self.__tpe = 0 00113 self.__pkte = 0 00114 00115 # A state transition can be rejected by not returning None 00116 return None 00117 00118 def stopRun(self): 00119 00120 # Success is defined if we found one and only one trigger parity error 00121 # and one and only one packet error 00122 if self.__tpe == 1 & self.__pkte == 1: 00123 log.info("Setting completion status = SUCCESS") 00124 self.setCompletionStatus(self.COMPL_STATUS_SUCCESS) 00125 else: 00126 log.info("Setting completion status = FAILED") 00127 self.setCompletionStatus(self.COMPL_STATUS_FAILED) 00128 self.__cmdSynchQuit = True 00129 self.__eventSem.release() 00130 00131 # The STOP_RUN transition can not be rejected 00132 00133 def resume(self): 00134 # Issue self trigger to make up for the one that was lost during PAUSE 00135 self.trigger().solicit() 00136 00137 return None 00138 00139 def stop(self): 00140 return self.stopRun() 00141 00142 def process(self, (status, buffer)): 00143 "Method called back for each data event taken" 00144 ###log.debug("userApplication.process()") 00145 00146 evtCli = self.evtCli 00147 00148 if status != 0: 00149 if evtCli.isGGLTStatus(): 00150 log.error("GGLT_STATUS=%d %s" % (evtCli.getGGLTStatus(), evtCli.getGGLTStatusStr())) 00151 elif not evtCli.checkOnlineStatus(status, self.evtCli.PLAYBACK_ERROR): 00152 log.error("EVENT ERROR= 0x%x %s" % (status, evtCli.getOnlineStatusStr())) 00153 self.__eventSem.release() 00154 return 00155 00156 try: 00157 # In the future this event may contain additional data 00158 if evtCli.isSweepEvent(): return 00159 except: 00160 # Event summary word inaccessible, handle the bad event here 00161 import gutil 00162 gutil.logException() 00163 return 00164 00165 if evtCli.isTrgParityErrorEvent(): 00166 log.debug( "Found a trigger parity error") 00167 self.__tpe += 1 00168 elif evtCli.isPacketErrorEvent(): 00169 log.debug( "Found a packet error") 00170 self.__pkte += 1 00171 else: 00172 log.debug( "Found a normal event") 00173 # Get next event triggered 00174 self.__eventSem.release() 00175 00176 def commandSynch(self): 00177 "Method called by the command synchronization task" 00178 import time 00179 trigger = self.trigger() 00180 eventSem = self.__eventSem 00181 00182 # Drain the semaphore release count 00183 # Handles the case when the stop run release collided with a trigger release 00184 while eventSem.acquire(0): pass 00185 00186 t0 = time.time() 00187 00188 # Compensate for the extra CMD_SELF_TRIGGER below 00189 cnt = 1 00190 count = self.__cnt 00191 00192 # bitmask in GEM config to cause trigger parity error 00193 TPE = 0x20 00194 # bitmask in GEM config to cause packet error (suppress bit) 00195 PKTE = 0x40 00196 00197 # Wait for START_RUN to enable triggers 00198 trigger.waitForMaskEnable() 00199 00200 # take one normal event 00201 trigger.solicit() # Issue an internal trigger 00202 eventSem.acquire() # Wait for the event to be processed 00203 00204 # Cause a trigger parity error for GEM event 00205 trigger.disable() 00206 gemc = trigger.GEM().GEMC 00207 gemcfg = gemc.CONFIGURATION 00208 gemcfg |= TPE 00209 gemc.configuration = gemcfg 00210 trigger.enable() 00211 00212 trigger.solicit() # Issue an internal trigger 00213 eventSem.acquire() # Wait for the event to be processed 00214 00215 # Reset the GEM to remove the trigger parity error bit. 00216 trigger.disable() 00217 gemc = trigger.GEM().GEMC 00218 gemcfg = gemc.CONFIGURATION 00219 gemcfg &= ~TPE 00220 gemc.configuration = gemcfg 00221 trigger.enable() 00222 00223 # Cause a packet error for GEM event 00224 trigger.disable() 00225 gemc = trigger.GEM().GEMC 00226 gemcfg = gemc.CONFIGURATION 00227 gemcfg |= PKTE 00228 gemc.configuration = gemcfg 00229 trigger.enable() 00230 00231 trigger.solicit() # Issue an internal trigger 00232 eventSem.acquire() # Wait for the event to be processed 00233 00234 # Reset the GEM to remove the suppression bit. 00235 trigger.disable() 00236 gemc = trigger.GEM().GEMC 00237 gemcfg = gemc.CONFIGURATION 00238 gemcfg &= ~PKTE 00239 gemc.configuration = gemcfg 00240 trigger.enable() 00241 00242 # take one normal event 00243 trigger.solicit() # Issue an internal trigger 00244 eventSem.acquire() # Wait for the event to be processed 00245 00246 # Get out of waiting when in standalone mode 00247 self.sync() 00248 00249 # execute the GUI functions for stopRun, just in case 00250 if not self.__cmdSynchQuit and not self.isRunFromSuite(): 00251 if self.gui is not None: 00252 self.gui.doStopRun() 00253 00254 def wait(self): 00255 self.__cmdSynchSem.acquire() 00256 00257 def sync(self): 00258 if __name__ == "__main__" or self.isRunFromSuite(): 00259 self.__cmdSynchSem.release() 00260 00261 00262 # Standalone mode: 00263 if __name__ == "__main__": 00264 import os 00265 log.basicConfig() 00266 log.getLogger("").setLevel(log.DEBUG) 00267 ua = userApplication(None, 321, 1) 00268 ua.rcSetup(os.path.join(os.environ['ONLINE_ROOT'], 'repos/simpleTemSchema.xml')) 00269 ua.rcStartRun() 00270 ua.wait() 00271 ua.rcStopRun() 00272 ua.rcTeardown() 00273