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')