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 ACD functional block hierarchy" 00013 __author__ = "Selim Tuvi <stuvi@slac.stanford.edu> SLAC - GLAST LAT I&T/Online" 00014 __date__ = ("$Date: 2004/08/25 04:18:27 $").split(' ')[1] 00015 __version__ = "$Revision: 2.9 $" 00016 __release__ = "$Name: P04-06-05 $" 00017 __credits__ = "SLAC" 00018 00019 import LATTE.copyright_SLAC 00020 00021 import time 00022 import gDb 00023 import gAttr 00024 import LATTE.client.gRegister as gRegister 00025 00026 class GAEM(gDb.Gdb): 00027 """\brief ACD Common Controller. 00028 00029 Has GAEM specific registers and dataless commands. 00030 00031 Valid Registers: 00032 - \c configuration 00033 - \c common_status 00034 - \c freeboard_status 00035 - \c command_response 00036 - \c trgseq 00037 - \c power_status 00038 - \c address 00039 - \c timeout 00040 - \c relocation 00041 - \c response_timeout 00042 - \c power_up 00043 - \c power_down 00044 00045 Dataless Commands: 00046 - \c cmd_reset 00047 00048 """ 00049 __attrs = [ 00050 gAttr.GattrReg('configuration', 0, 4), 00051 gAttr.GattrReg('common_status', 1, 4), 00052 gAttr.GattrReg('freeboard_status', 2, 4), 00053 gAttr.GattrReg('command_response', 3, 4), 00054 gAttr.GattrReg('trgseq', 4, 4), 00055 gAttr.GattrReg('power_status', 5, 4), 00056 gAttr.GattrReg('address', 6, 4), 00057 gAttr.GattrReg('timeout', 7, 4), 00058 gAttr.GattrReg('relocation', 8, 4), 00059 gAttr.GattrReg('response_timeout', 9, 4), 00060 gAttr.GattrReg('power_up', 10, 4), 00061 gAttr.GattrReg('power_down', 11, 4), 00062 gAttr.GattrDlc('cmd_reset', 1, 0), 00063 ] 00064 00065 def __init__(self, client, parent): 00066 """\brief Initialize valid registers as Gattrs. 00067 00068 Assign default values to members 00069 """ 00070 self.ARC = gDb.Children(self, GARC) 00071 self.AEQ = None 00072 gDb.Gdb.__init__(self, client, parent, 0, self.__attrs) 00073 00074 def read(self, reg): 00075 return self.cmdrsp('AEM_CC_read_sync', 'slh', 'LADR_AEM', reg, '!I') 00076 00077 def load(self, reg, value): 00078 return self.cmdrsp('AEM_CC_load_sync', 'slh', 'LADR_AEM', reg, value) 00079 00080 def send(self, cmd): 00081 return self.cmdrsp('AEM_CC_cmd_sync', 'slh', 'LADR_AEM', cmd) 00082 00083 def downARC(self, arcId): 00084 """\brief Navigate to the GARC indicated by \a childId 00085 00086 \param childId The id of the child GARC 00087 00088 \return A GARC object instance 00089 """ 00090 return self.ARC.down(arcId) 00091 00092 def allARC(self): 00093 """\brief Navigate to the broadcast GARC 00094 00095 \return The broadcast GARC object instance 00096 """ 00097 return self.ARC.all() 00098 00099 def existsARC(self, arcId): 00100 """\brief Check if the GARC instance with the id 00101 \a arcId exists in the schema. 00102 00103 \param arcId ACD readout controller id 00104 00105 \return 1 if it exists, 0 if it doesn't. 00106 """ 00107 return self.ARC.exists(arcId) 00108 00109 def downAEQ(self): 00110 """\brief Navigate to the GAEQ 00111 00112 \return The GAEQ object instance 00113 """ 00114 return self.AEQ 00115 00116 def existsAEQ(self): 00117 """\brief Check if the GAEQ instance exists in the schema. 00118 00119 \return 1 if it exists, 0 if it doesn't. 00120 """ 00121 return self.AEQ != None 00122 00123 ## private: 00124 def __removeARC(self, arcId): 00125 self.ARC.remove(arcId) 00126 00127 def __addARC(self, arcId): 00128 return self.ARC.add(arcId) 00129 00130 def __removeAEQ(self): 00131 self.AEQ = None 00132 00133 def __addAEQ(self): 00134 self.AEQ = GAEQ(self.client(), self) 00135 return self.AEQ 00136 00137 class GAEQ(gDb.Gdb): 00138 """\brief ACD Environmental Monitors. 00139 00140 Has GAEQ specific registers and dataless commands. 00141 00142 Valid Registers: 00143 - \c env_free_1la 00144 - \c env_free_1rb 00145 - \c env_free_2la 00146 - \c env_free_2lb 00147 - \c env_free_2ra 00148 - \c env_free_2rb 00149 - \c env_free_3la 00150 - \c env_free_3rb 00151 - \c env_free_4la 00152 - \c env_free_4lb 00153 - \c env_free_4ra 00154 - \c env_free_4rb 00155 - \c env_daq 00156 00157 Pseudo registers: 00158 - \c env_vdd_xxx 00159 - \c env_temp_xxx 00160 - \c env_hv1_xxx 00161 - \c env_hv2_xxx 00162 - \c env_dac_digital_3_3i 00163 - \c env_dac_temp 00164 - \c env_dac_hv_i 00165 - \c env_dac_v 00166 00167 """ 00168 __attrs = [ 00169 # Registers 00170 gAttr.GattrReg('env_free_1la', 0, 8), 00171 gAttr.GattrReg('env_free_1rb', 1, 8), 00172 gAttr.GattrReg('env_free_2la', 2, 8), 00173 gAttr.GattrReg('env_free_2lb', 3, 8), 00174 gAttr.GattrReg('env_free_2ra', 4, 8), 00175 gAttr.GattrReg('env_free_2rb', 5, 8), 00176 gAttr.GattrReg('env_free_3la', 6, 8), 00177 gAttr.GattrReg('env_free_3rb', 7, 8), 00178 gAttr.GattrReg('env_free_4la', 8, 8), 00179 gAttr.GattrReg('env_free_4lb', 9, 8), 00180 gAttr.GattrReg('env_free_4ra', 10, 8), 00181 gAttr.GattrReg('env_free_4rb', 11, 8), 00182 gAttr.GattrReg('env_daq', 12, 8), 00183 ] 00184 __STALE_TMO = 1.0 # Timeout in seconds before considering adcs value stale 00185 __GAEQ_ENV_VDD_1LA = 20 00186 __ADCS_BASE = 20 00187 00188 i = __ADCS_BASE 00189 for env in ('1la','1rb','2la','2lb','2ra','2rb', 00190 '3la','3rb','4la','4lb','4ra','4rb'): 00191 __attrs.append(gAttr.GattrReg('env_vdd_'+env, i, 2)) 00192 i+=1 00193 __attrs.append(gAttr.GattrReg('env_temp_'+env, i, 2)) 00194 i+=1 00195 __attrs.append(gAttr.GattrReg('env_hv1_'+env, i, 2)) 00196 i+=1 00197 __attrs.append(gAttr.GattrReg('env_hv2_'+env, i, 2)) 00198 i+=1 00199 __attrs.append(gAttr.GattrReg('env_dac_digital_3_3i', 68, 2)) 00200 __attrs.append(gAttr.GattrReg('env_dac_temp', 69, 2)) 00201 __attrs.append(gAttr.GattrReg('env_dac_hv_i', 70, 2)) 00202 __attrs.append(gAttr.GattrReg('env_dac_v', 71, 2)) 00203 00204 def __init__(self, client, parent): 00205 """\brief Initialize valid registers as Gattrs. 00206 00207 Assign default values to members 00208 """ 00209 self.__envs = 13*[(None, 0)] # [gRegister.Register, time.time()] 00210 gDb.Gdb.__init__(self, client, parent, 0, self.__attrs) 00211 00212 def read(self, reg): 00213 if reg < GAEQ.__ADCS_BASE: 00214 return self.cmdrsp('AEM_AENV_read_sync', 'slh', 'LADR_AEM', reg, '!Q') 00215 else: 00216 return self.__fetchReg(reg) 00217 00218 def load(self, reg, value): 00219 return self.cmdrsp('AEM_AENV_load_sync', 'slh', 'LADR_AEM', reg, value) 00220 00221 def __fetchReg(self, reg): 00222 mux = (reg - GAEQ.__ADCS_BASE) / 4 00223 which = (reg - GAEQ.__ADCS_BASE) % 4 00224 now = time.time() 00225 (rsp, rt) = self.__envs[mux] 00226 if ((rsp is None) or (now - rt) > GAEQ.__STALE_TMO): 00227 # Set the mux and cause the ADCs to convert 00228 self.cmdrsp('AEM_AENV_load_sync', 'slh', 'LADR_AEM', mux, 0) 00229 # Read the values and timeout information 00230 rsp = self.cmdrsp('AEM_AENV_read_sync', 'slh', 'LADR_AEM', mux, '!Q') 00231 self.__envs[mux] = (rsp, now) 00232 timestamp = rsp.timestamp() 00233 status = rsp.status() 00234 payloads = [(rsp.value() >> (16 * which)) & 0x0fff] 00235 return gRegister.Register(timestamp, status, payloads, 'H') 00236 00237 class GARC(gDb.Gdb): 00238 """\brief ACD Readout Controller. 00239 00240 Has GARC specific registers and dataless commands. 00241 00242 Valid Registers: 00243 - function block 0 00244 - \c veto_delay 00245 - \c hvbs 00246 - \c saa 00247 - \c use_hv_normal 00248 - \c use_hv_saa 00249 - \c hold_delay 00250 - \c veto_width 00251 - \c hitmap_width 00252 - \c hitmap_deadtime 00253 - function block 1 00254 - \c look_at_me 00255 - \c hitmap_delay 00256 - \c pha_en_0 00257 - \c veto_en_0 00258 - \c hld_en_0 00259 - \c pha_en_1 00260 - \c veto_en_1 00261 - \c hld_en_1 00262 - \c max_pha 00263 - function block 2 00264 - \c mode 00265 - \c status 00266 - \c last_cmd 00267 - \c diagnostic 00268 - \c cmd_reject 00269 - \c free_id 00270 - \c garc_version 00271 - function block 3 00272 - \c pha_threshold_0 00273 - \c pha_threshold_1 00274 - \c pha_threshold_2 00275 - \c pha_threshold_3 00276 - \c pha_threshold_4 00277 - \c pha_threshold_5 00278 - \c pha_threshold_6 00279 - function block 4 00280 - \c pha_threshold_7 00281 - \c pha_threshold_8 00282 - \c pha_threshold_9 00283 - \c pha_threshold_10 00284 - \c pha_threshold_11 00285 - \c pha_threshold_12 00286 - \c pha_threshold_13 00287 - function block 5 00288 - \c pha_threshold_14 00289 - \c pha_threshold_15 00290 - \c pha_threshold_16 00291 - \c pha_threshold_17 00292 - \c adc_tacq 00293 00294 \deprecated 00295 - \c \b rqst_hvbs Use 'hvbs' instead 00296 - \c \b rqst_hvsaa Use 'saa' instead 00297 - \c \b hvbs Use 'use_hv_normal' instead 00298 - \c \b hvsaa Use 'use_hv_saa' instead 00299 </table> 00300 00301 Dataless Commands 00302 - \c cmd_reset 00303 - \c cmd_calstrobe 00304 - \c cmd_set_hvbs 00305 - \c cmd_set_hvsaa 00306 00307 """ 00308 __attrs = [ 00309 # Registers 00310 # function block 0 00311 gAttr.GattrReg('veto_delay', 2, 2), 00312 gAttr.GattrReg('hvbs', 8, 2), 00313 gAttr.GattrReg('saa', 9, 2), 00314 gAttr.GattrReg('use_hv_normal', 10, 2), 00315 gAttr.GattrReg('use_hv_saa', 11, 2), 00316 gAttr.GattrReg('hold_delay', 12, 2), 00317 gAttr.GattrReg('veto_width', 13, 2), 00318 gAttr.GattrReg('hitmap_width', 14, 2), 00319 gAttr.GattrReg('hitmap_deadtime', 15, 2), 00320 # function block 1 00321 gAttr.GattrReg('look_at_me', 20, 2), 00322 gAttr.GattrReg('hitmap_delay', 24, 2), 00323 gAttr.GattrReg('pha_en_0', 25, 2), 00324 gAttr.GattrReg('veto_en_0', 26, 2), 00325 gAttr.GattrReg('pha_en_1', 28, 2), 00326 gAttr.GattrReg('veto_en_1', 29, 2), 00327 gAttr.GattrReg('max_pha', 31, 2), 00328 # function block 2 00329 gAttr.GattrReg('mode', 40, 2), 00330 gAttr.GattrReg('status', 41, 2), 00331 gAttr.GattrReg('last_cmd', 42, 2), 00332 gAttr.GattrReg('diagnostic', 43, 2), 00333 gAttr.GattrReg('cmd_reject', 44, 2), 00334 gAttr.GattrReg('free_id', 45, 2), 00335 gAttr.GattrReg('garc_version', 46, 2), 00336 # function block 3 00337 gAttr.GattrReg('pha_threshold_0', 56, 2), 00338 gAttr.GattrReg('pha_threshold_1', 57, 2), 00339 gAttr.GattrReg('pha_threshold_2', 58, 2), 00340 gAttr.GattrReg('pha_threshold_3', 59, 2), 00341 gAttr.GattrReg('pha_threshold_4', 60, 2), 00342 gAttr.GattrReg('pha_threshold_5', 61, 2), 00343 gAttr.GattrReg('pha_threshold_6', 62, 2), 00344 # function block 4 00345 gAttr.GattrReg('pha_threshold_7', 72, 2), 00346 gAttr.GattrReg('pha_threshold_8', 73, 2), 00347 gAttr.GattrReg('pha_threshold_9', 74, 2), 00348 gAttr.GattrReg('pha_threshold_10', 75, 2), 00349 gAttr.GattrReg('pha_threshold_11', 76, 2), 00350 gAttr.GattrReg('pha_threshold_12', 77, 2), 00351 gAttr.GattrReg('pha_threshold_13', 78, 2), 00352 # function block 5 00353 gAttr.GattrReg('pha_threshold_14', 88, 2), 00354 gAttr.GattrReg('pha_threshold_15', 89, 2), 00355 gAttr.GattrReg('pha_threshold_16', 90, 2), 00356 gAttr.GattrReg('pha_threshold_17', 91, 2), 00357 gAttr.GattrReg('adc_tacq', 92, 2), 00358 # Dataless Commands 00359 gAttr.GattrReg('cmd_reset', 1, 0), 00360 gAttr.GattrReg('cmd_calstrobe', 3, 0), 00361 gAttr.GattrReg('cmd_set_hvbs', 10, 0), 00362 gAttr.GattrReg('cmd_set_hvsaa', 11, 0) 00363 ] 00364 00365 BCASTADDR = 0x1f 00366 NARCS = 12 00367 00368 def __init__(self, client, parent, id): 00369 """\brief Initialize valid registers as Gattrs. 00370 00371 Assign default values to members 00372 """ 00373 if id < GARC.NARCS: 00374 addr = id 00375 elif id == gDb.Children.BCASTID: 00376 addr = GARC.BCASTADDR 00377 else: 00378 raise KeyError("*** gAEM: GARC id %d is invalid" %(id)) 00379 self.AFE = gDb.Children(self, GAFE) 00380 gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr) 00381 00382 def read(self, reg): 00383 return self.cmdrsp('AEM_GARC_read_sync', 'slh', 'LADR_AEM', self.addr(), reg, '!I') 00384 00385 def load(self, reg, value): 00386 return self.cmdrsp('AEM_GARC_load_sync', 'slh', 'LADR_AEM', self.addr(), reg, value) 00387 00388 def send(self, cmd): 00389 return self.cmdrsp('AEM_GARC_cmd_sync', 'slh', 'LADR_AEM', self.addr(), cmd) 00390 def downAFE(self, afeId): 00391 """\brief Navigate to the GAFE indicated by \a childId 00392 00393 \param childId The id of the child GAFE 00394 00395 \return A GAFE object instance 00396 """ 00397 return self.AFE.down(afeId) 00398 00399 def allAFE(self): 00400 """\brief Navigate to the broadcast GAFE 00401 00402 \return The broadcast GAFE object instance 00403 """ 00404 return self.AFE.all() 00405 00406 def existsAFE(self, afeId): 00407 """\brief Check if the GAFE instance with the id 00408 \a afeId exists in the schema. 00409 00410 \param afeId ACD readout controller id 00411 00412 \return 1 if it exists, 0 if it doesn't. 00413 """ 00414 return self.AFE.exists(afeId) 00415 00416 ## private: 00417 def __removeAFE(self, afeId): 00418 self.AFE.remove(afeId) 00419 00420 def __addAFE(self, afeId): 00421 return self.AFE.add(afeId) 00422 00423 00424 class GAFE(gDb.Gdb): 00425 """\brief ACD Front-End Controller. 00426 00427 Has GAFE specific registers and dataless commands. 00428 00429 Valid Registers: 00430 - \c configuration 00431 - \c veto_dac 00432 - \c hld_dac 00433 - \c veto_vernier 00434 - \c bias_dac 00435 - \c tci_dac 00436 - \c vers_addr 00437 - \c write_ctr 00438 - \c reject_ctr 00439 - \c loop_ctr 00440 - \c chip_addr 00441 00442 \deprecated 00443 - \c \b lld_dac Use 'veto_vernier' instead 00444 00445 """ 00446 __attrs = [ 00447 # Registers 00448 gAttr.GattrReg('configuration', 0, 2), 00449 gAttr.GattrReg('veto_dac', 1, 2), 00450 gAttr.GattrReg('veto_vernier', 2, 2), 00451 gAttr.GattrReg('hld_dac', 3, 2), 00452 gAttr.GattrReg('bias_dac', 4, 2), 00453 gAttr.GattrReg('tci_dac', 5, 2), 00454 gAttr.GattrReg('vers_addr', 6, 2), 00455 gAttr.GattrReg('write_ctr', 7, 2), 00456 gAttr.GattrReg('reject_ctr', 8, 2), 00457 gAttr.GattrReg('loop_ctr', 9, 2), 00458 gAttr.GattrReg('chip_addr', 10, 2) 00459 ] 00460 00461 BCASTADDR = 0x1f 00462 NAFES = 18 00463 00464 def __init__(self, client, parent, id): 00465 """\brief Initialize valid registers as Gattrs. 00466 00467 """ 00468 if id < GAFE.NAFES: 00469 addr = id 00470 elif id == gDb.Children.BCASTID: 00471 addr = GAFE.BCASTADDR 00472 else: 00473 raise KeyError("*** gAEM: GAFE id %d is invalid" %(id)) 00474 gDb.Gdb.__init__(self, client, parent, id, self.__attrs, addr) 00475 00476 def read(self, reg): 00477 return self.cmdrsp('AEM_GAFE_read_sync', 'slh', 'LADR_AEM', self.up().addr(), self.addr(), reg, '!I') 00478 00479 def load(self, reg, value): 00480 return self.cmdrsp('AEM_GAFE_load_sync', 'slh', 'LADR_AEM', self.up().addr(), self.addr(), reg, value) 00481 00482 def send(self, cmd): 00483 return self.cmdrsp('AEM_GAFE_cmd_sync', 'slh', 'LADR_AEM', self.up().addr(), self.addr(), cmd) 00484