DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
debug.py
Go to the documentation of this file.
1from __future__ import print_function
2
3# Python imports
4import uhal
5import click
6import click_didyoumean
7import time
8import collections
9import timing
10
11import timing.cli.toolbox as toolbox
12import timing.common.definitions as defs
13
14from click import echo, style, secho
15from os.path import join, expandvars
16from timing.core import SI534xSlave, I2CExpanderSlave, LTC2945Node
17
18
19from timing.common.definitions import kBoardSim, kBoardFMC, kBoardPC059, kBoardMicrozed, kBoardTLU, kBoardMIB, kBoardGIB, kBoardPC069, kBoardFIB
20from timing.common.definitions import kCarrierEnclustraA35, kCarrierKC705, kCarrierMicrozed
21from timing.common.definitions import kBoardNameMap, kCarrierNameMap, kDesignNameMap
22
23
24# ------------------------------------------------------------------------------
25@click.group('debug', invoke_without_command=True)
26@click.pass_obj
27@click.argument('device', callback=toolbox.validate_device, shell_complete=toolbox.completeDevices)
28def debug(obj, device):
29 '''
30 Timing master commands.
31
32 DEVICE: uhal device identifier
33 '''
34 lDevice = obj.mConnectionManager.getDevice(str(device))
35 if obj.mTimeout:
36 lDevice.setTimeoutPeriod(obj.mTimeout)
37
38 echo('Created device ' + click.style(lDevice.id(), fg='blue'))
39
40 lBoardInfo = toolbox.readSubNodes(lDevice.getNode('io.config'), False)
41 lDevice.dispatch()
42
43 # print({ k:v.value() for k,v in lBoardInfo.items()})
44 # raise SystemExit(0)
45
46 echo("Design '{}' on board '{}' on carrier '{}'".format(
47 style(kDesignNameMap[lBoardInfo['design_type'].value()], fg='blue'),
48 style(kBoardNameMap[lBoardInfo['board_type'].value()], fg='blue'),
49 style(kCarrierNameMap[lBoardInfo['carrier_type'].value()], fg='blue')
50 ))
51
52 obj.mDevice = lDevice
53 obj.mBoardType = lBoardInfo['board_type'].value()
54 obj.mCarrierType = lBoardInfo['carrier_type'].value()
55 obj.mDesignType = lBoardInfo['design_type'].value()
56# ------------------------------------------------------------------------------
57
58
59# ------------------------------------------------------------------------------
60@debug.command('inspect')
61@click.argument('nodes')
62@click.pass_obj
63def inspect(obj, nodes):
64 lDevice = obj.mDevice
65
66 lNodeIds = lDevice.getNodes(nodes.encode('ascii','replace'))
67 lNodeVals = {n:lDevice.getNode(n).read() for n in lNodeIds}
68
69 lDevice.dispatch()
70
71 toolbox.printRegTable(lNodeVals, False)
72# ------------------------------------------------------------------------------
73
74
75# ------------------------------------------------------------------------------
76@debug.command()
77@click.pass_context
78def ipy(ctx):
79 '''
80 Start an interactive IPython session.
81
82 The board HwInterface is accessible as 'lDevice'
83 '''
84 lDevice = ctx.obj.mDevice
85
86 from IPython import embed
87 embed()
88# ------------------------------------------------------------------------------
89
90
91# ------------------------------------------------------------------------------
92@debug.command('uid', short_help="Unique ID reader.")
93@click.pass_obj
94def uuid(obj):
95
96 lDevice = obj.mDevice
97 lBoardType = obj.mBoardType
98 lIO = lDevice.getNode('io')
99
100 # Detect the on-board eprom and read the board UID
101 if lBoardType in [kBoardPC059, kBoardTLU, kBoardMIB, kBoardGIB]:
102 lUID = lDevice.getNode('io.i2c')
103 else:
104 lUID = lDevice.getNode('io.uid_i2c')
105
106 lPROMSlave = 'UID_PROM' if lBoardType in [kBoardTLU,kBoardMIB,kBoardGIB] else 'FMC_UID_PROM'
107
108 if lBoardType == kBoardGIB:
109 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x0)
110 lDevice.dispatch()
111 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
112 lDevice.dispatch()
113 print("switch reset")
114 # lIO.set_i2c_mux_channels(0x1)
115
116 lValues = lUID.get_slave(lPROMSlave).read_i2cArray(0xfa, 6)
117 lUniqueID = 0x0
118 for lVal in lValues:
119 lUniqueID = ( lUniqueID << 8 ) | lVal
120 echo("Timing Board PROM UID: "+style(hex(lUniqueID), fg="blue"))
121# ------------------------------------------------------------------------------
122
123
124# ------------------------------------------------------------------------------
125@debug.command('sfpexpander', short_help="Debug.")
126@click.pass_obj
127def sfpexpander(obj):
128 lDevice = obj.mDevice
129 lBoardType = obj.mBoardType
130
131 if lBoardType != kBoardPC059:
132 secho('No SFP expander on {}'.format(kBoardNameMap[lBoardInfo['board_type'].value()]))
133 return
134 lI2CBusNode = lDevice.getNode("io.i2c")
135 lSFPExp = I2CExpanderSlave(lI2CBusNode, lI2CBusNode.get_slave('SFPExpander').get_i2c_address())
136 lSFPExpStatus = lSFPExp.debug()
137
138 lLabels = [
139 'B0 values',
140 'B1 values',
141 'B0 enable',
142 'B1 enable',
143 'B0 invert',
144 'B1 invert',
145 'B0 I/O ',
146 'B1 I/O ',
147 ]
148 for a,v in enumerate(lSFPExpStatus):
149 echo("{} ({}): {}".format(lLabels[a], hex(a), hex(v)))
150# ------------------------------------------------------------------------------
151
152# ------------------------------------------------------------------------------
153@debug.command('scan-i2c', short_help="Debug.")
154@click.pass_obj
155def scan_i2c(obj):
156 lDevice = obj.mDevice
157 lBoardType = obj.mBoardType
158 lIO = lDevice.getNode('io')
159
160 lNodes = []
161 lSwitches={}
162 lSwitchChannels={}
163 if lBoardType in [kBoardFMC, kBoardPC069]:
164 lNodes = ['io.sfp_i2c','io.uid_i2c','io.pll_i2c']
165 elif lBoardType == kBoardPC059:
166 lNodes = ['io.i2c', 'io.usfp_i2c']
167 switch_address=lDevice.getNode('io.i2c').get_slave_address('SFP_Switch')
168 lSwitches={"io.i2c": switch_address}
169 lSwitchChannels={"io.i2c": 8}
170 elif lBoardType in [kBoardTLU, kBoardMIB, kBoardGIB]:
171 lNodes = ['io.i2c']
172 if lBoardType == kBoardGIB:
173 lSwitches={"io.i2c": 0x70}
174 lSwitchChannels={"io.i2c": 7}
175 else:
176 secho(f"Error I don't know about board {lBoardType} : {kBoardNameMap[lBoardType]}", fg='red')
177 # if lBoardType == kBoardPC059:
178 # lSFPSwitch = lDevice.getNode('io.i2c').get_slave('SFP_Switch')
179 # print(lSFPSwitch.read_i2cPrimitive(1))
180 # print(lSFPSwitch.write_i2cPrimitive([0x1]))
181 # print(lSFPSwitch.read_i2cPrimitive(1))
182
183 for n in lNodes:
184 lI2CBusNode = lDevice.getNode(n)
185 echo('Scanning '+style(n,fg='cyan'))
186 print("reset switch")
187 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x0)
188 lDevice.dispatch()
189 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
190 lDevice.dispatch()
191 lAddresses = lI2CBusNode.scan()
192 print(" '{}': {} devices found.\n Addresses: {}".format(n, len(lAddresses), ', '.join((hex(a) for a in lAddresses))))
193
194 if n in lSwitches:
195 for switch,address in lSwitches.items():
196 print (f"switch {switch} address: {address}")
197 switch_channels=lSwitchChannels[switch]
198 print(f"working with {switch}, @ adr {address}, it has {switch_channels} channels")
199
200 for channel in range(0,switch_channels):
201 secho(f"Scanning with channel {channel} enabled", fg='cyan')
202 try:
203 lI2CBusNode.write_i2cPrimitive(address, [1<<channel])
204 except:
205 secho(f"failure configuring switch {address}")
206 lAddresses = lI2CBusNode.scan()
207 print(" '{}': {} devices found.\n Addresses: {}".format(n, len(lAddresses), ', '.join((hex(a) for a in lAddresses))))
208
209# ------------------------------------------------------------------------------
210
211# ------------------------------------------------------------------------------
212@debug.command('pll', short_help="Debug.")
213@click.pass_obj
214def pll(obj):
215 lDevice = obj.mDevice
216 lBoardType = obj.mBoardType
217 lIO = lDevice.getNode('io')
218
219 lI2CBusNode = lDevice.getNode('io.i2c')
220 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
221 lDevice.getNode("io.csr.ctrl.clk_gen_rst").write(0x1)
222 lDevice.dispatch()
223
224 lI2CBusNode.write_i2cPrimitive(0x70, [1])
225
226 lSIChip = SI534xSlave(lI2CBusNode, 0x68)
227 #lSIVersion = lSIChip.read_device_version()
228
229 lSIVersion = lSIChip.read_device_version()
230 echo(f"PLL version {hex(lSIVersion)}")
231# ------------------------------------------------------------------------------
232
233# ------------------------------------------------------------------------------
234@debug.command('fanout-sfp-scan', short_help="Debug.")
235@click.pass_obj
237
238 lDevice = obj.mDevice
239 lBoardType = obj.mBoardType
240
241 if lBoardType != kBoardPC059:
242 print('Wrong board', lBoardType, 'sorry mate')
243 return
244
245
246 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x1)
247 lDevice.dispatch()
248 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x0)
249 lDevice.dispatch()
250 time.sleep(1)
251
252 lSFPNodeName = 'io.i2c'
253 lI2CBusNode = lDevice.getNode(lSFPNodeName)
254 lSwitchSlave = lI2CBusNode.get_slave('SFP_Switch')
255 print(lSwitchSlave.ping())
256
257 # print(lSwitchSlave.read_i2cPrimitive(1))
258 # time.sleep(0.1)
259
260 lSwitchSlave.write_i2cPrimitive([3])
261 print(lSwitchSlave.read_i2cPrimitive(1))
262 print(lSwitchSlave.read_i2cPrimitive(1))
263 print(lSwitchSlave.read_i2cPrimitive(1))
264
265# ------------------------------------------------------------------------------
266@debug.command('sfp-status', short_help="Debug.")
267@click.pass_obj
268def sfp_status(obj):
269
270 lDevice = obj.mDevice
271 lBoardType = obj.mBoardType
272
273 if lBoardType == kBoardFMC:
274 lSFPNodeName = 'io.sfp_i2c'
275 lSFPLabel = 'SFP'
276 elif lBoardType == kBoardPC059:
277 lSFPNodeName = 'io.usfp_i2c'
278 lSFPLabel = 'USFP'
279 else:
280 secho('No SFP on {}'.format(kBoardNameMap[lBoardType]))
281 return
282
283 lI2CBusNode = lDevice.getNode(lSFPNodeName)
284 lEEPromSlave = lI2CBusNode.get_slave('SFP_EEProm')
285 lDiagSlave = lI2CBusNode.get_slave('SFP_Diag')
286
287 readSFPStatus(lEEPromSlave, lDiagSlave, lSFPLabel)
288
289 if lBoardType == kBoardPC059:
290 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x1)
291 lDevice.dispatch()
292 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x0)
293 lDevice.dispatch()
294 time.sleep(0.1)
295
296 lI2CBusNode = lDevice.getNode('io.i2c')
297 lSwitchSlave = lI2CBusNode.get_slave('SFP_Switch')
298 lEEPromSlave = lI2CBusNode.get_slave('SFP_EEProm')
299 lDiagSlave = lI2CBusNode.get_slave('SFP_Diag')
300
301 # lOld = lSwitchSlave.read_i2cPrimitive(1)
302 # lSwitchSlave.write_i2cPrimitive([0x0])
303 time.sleep(0.1)
304 for iSFP in range(8):
305 try:
306 lSwitchSlave.write_i2cPrimitive([1 << iSFP])
307 except RuntimeError as lExc:
308 pass
309 if not lEEPromSlave.ping():
310 secho('SFP {} not available'.format(iSFP),fg='yellow')
311 continue
312 else:
313 secho('SFP {} found'.format(iSFP),fg='green')
314 # readSFPStatus(lEEPromSlave, lDiagSlave)
315
316# ------------------------------------------------------------------------------
317
318
319
320# ------------------------------------------------------------------------------
321def readSFPStatus(aEEProm, aDiag, aLabel):
322
323 def asciidecode( v ):
324 return (''.join([chr(c) for c in v])).rstrip()
325
326 def tempdecode( v ):
327 lSign = -1 if ((v[0]>>7) & 0x1) else 1
328 x = lSign*((v[0] & 0x7f) + v[1]/float(0xff))
329 return '{:.3f} C'.format(x)
330
331 def vccdecode( v ):
332 return '{:.4f} V'.format(((v[0] << 8) + v[1])/float(10000))
333
334 def biascurdecode( v ):
335 return '{:.3f} mA'.format(((v[0] << 8) + v[1])*2e-3)
336
337 def powerdecode( v ):
338 return '{:.3f} mW'.format(((v[0] << 8) + v[1])*1e-3)
339
340
341 echo()
342 lVenInfoEnc = collections.OrderedDict()
343 lVenInfoEnc['Name'] = asciidecode(aEEProm.read_i2cArray(20,16))
344 lVenInfoEnc['OUI'] = '{}.{}.{}'.format(*(aEEProm.read_i2cArray(37,3)))
345 lVenInfoEnc['Part Number'] = asciidecode(aEEProm.read_i2cArray(40,16))
346 lVenInfoEnc['Revision'] = asciidecode(aEEProm.read_i2cArray(56,4))
347 lVenInfoEnc['Serial Number'] = asciidecode(aEEProm.read_i2cArray(68,16))
348 lVenInfoEnc['Day'] = asciidecode(aEEProm.read_i2cArray(88,2))
349 lVenInfoEnc['Month'] = asciidecode(aEEProm.read_i2cArray(86,2))
350 lVenInfoEnc['Year'] = asciidecode(aEEProm.read_i2cArray(84,2))
351
352 secho("{} Vendor info".format(aLabel), fg='cyan')
353 # for k,v in lVenInfoEnc.items():
354 # v = ''.join([chr(c) for c in v])
355 # echo(' - '+k+': '+style(v, fg='cyan'))
356 echo(toolbox.formatDictTable(lVenInfoEnc, aHdr=False, aSort=False))
357 echo()
358 lLaserWl = aEEProm.read_i2cArray(60,2)
359 lLaserWl = (lLaserWl[0] << 8) + lLaserWl[1]
360 echo('Laser Wavelength: '+style(str(lLaserWl)+'nm', fg='cyan'))
361
362 lRegs = collections.OrderedDict()
363
364 lRegs['Identifier'] = aEEProm.read_i2c(0)
365 lRegs['Ext Identifier'] = aEEProm.read_i2c(1)
366 lRegs['Connector'] = aEEProm.read_i2c(2)
367
368 # Transciever Compatinility
369 lTransComp = aEEProm.read_i2cArray(3, 8)
370
371 lRegs['Encoding'] = aEEProm.read_i2c(11)
372 lRegs['BR, Nominal'] = aEEProm.read_i2c(12)
373 lRegs['Rate ID'] = aEEProm.read_i2c(13)
374
375 toolbox.printRegTable(lRegs, aHeader=False, sort=False)
376
377 echo()
378 secho("{} Diagnostic info".format(aLabel), fg='cyan')
379
380 lReadings = collections.OrderedDict()
381
382 lReadings['Temp'] = tempdecode(aDiag.read_i2cArray(96, 2))
383 lReadings['Vcc'] = vccdecode(aDiag.read_i2cArray(98, 2))
384 lReadings['TX bias'] = biascurdecode(aDiag.read_i2cArray(100, 2))
385 lReadings['TX power'] = powerdecode(aDiag.read_i2cArray(102, 2))
386 lReadings['RX power'] = powerdecode(aDiag.read_i2cArray(104, 2))
387 lMiscStatus = aDiag.read_i2c(110)
388 lReadings['TX disable'] = (lMiscStatus >> 7) & 0x1
389
390 # for k,v in lReadings.items():
391 # print (k, v)
392
393 echo(toolbox.formatDictTable(lReadings, aHdr=False, aSort=False))
394# ------------------------------------------------------------------------------
395
396# ------------------------------------------------------------------------------
397@debug.command('lm75-temp-read', short_help="Read temp data from a LM75.")
398@click.pass_obj
400
401 lDevice = obj.mDevice
402 lBoardType = obj.mBoardType
403 lIO = lDevice.getNode('io')
404
405 if lBoardType != kBoardFIB:
406 secho(f'Only FIB (v2) supported. Board type is {lBoardType}', fg='red')
407 return
408
409 i2c_bus = lDevice.getNode('io.i2c')
410
411 lValues = i2c_bus.get_slave('TEMP_MON').read_i2cPrimitive(2)
412 temp_raw = (lValues[1] & 0x80) >> 7
413 temp_raw = temp_raw | (lValues[0] << 1)
414 echo(f"LM75 temp data")
415 echo(f" raw bytes: {hex(lValues[0])}, {hex(lValues[1])}")
416 echo(f" combined word: {hex(temp_raw)}")
417 echo(f" temp [C]: {toolbox.twos_complement(temp_raw,9)*0.5}")
418# ------------------------------------------------------------------------------
419
420# ------------------------------------------------------------------------------
421@debug.command('ltc2945', short_help="Read data from a LTC2945.")
422@click.pass_obj
423def lm75_temp_read(obj):
424
425 lDevice = obj.mDevice
426 lBoardType = obj.mBoardType
427 lIO = lDevice.getNode('io')
428
429 if lBoardType != kBoardGIB:
430 secho(f'Only GIB (v2 (not checked)) supported. Board type is {lBoardType}', fg='red')
431 return
432
433 i2c_bus = lDevice.getNode('io.i2c')
434
435 voltage_power_mon_i2c_addr_map = {"5": 0x67, "3.3": 0x6a, "2.5": 0x69}
436 voltage_sense_resistance_map = {"5": 0.005, "3.3": 0.02, "2.5": 0.02}
437
438 for v,addr in voltage_power_mon_i2c_addr_map.items():
439 sense_r = voltage_sense_resistance_map[v]
440 lLTC2945 = LTC2945Node(i2c_bus, addr, sense_r)
441
442 lLTC2945.write_i2c(0x0, 0x05)
443
444 delta_sense_v = lLTC2945.read_delta_sense_v()
445 v_in = lLTC2945.read_v_in()
446 power = lLTC2945.read_power()
447
448 echo(f"LTC2945 {v}V data is:")
449 echo(f"deltaSenseV : {delta_sense_v*1000} mV")
450 echo(f"Vin : {v_in} V")
451 echo(f"power is: {power*1000} mW\n")
452
453 #lLTC2945_5v = LTC2945Node(i2c_bus, ic_addr_5v_mon, 0.005)
454 #lLTC2945_3v3 = LTC2945Node(i2c_bus, ic_addr_3v3_mon, 0.02)
455
456 #lLTC2945_5v.write_i2c(0x0, 0x05)
457 #lLTC2945_3v3.write_i2c(0x0, 0x05)
458
459 #delta_sense_v_5v = lLTC2945_5v.read_delta_sense_v()
460 #echo(f"LTC2945 5V deltaSense V is: {delta_sense_v_5v*1000} mV\n")
461
462 #delta_sense_v_3v3 = lLTC2945_3v3.read_delta_sense_v()
463 #echo(f"LTC2945 3.3V deltaSense V is: {delta_sense_v_3v3*1000} mV\n")
464
465 #v_in_5v = lLTC2945_5v.read_v_in()
466 #echo(f"LTC2945 5V Vin is: {v_in_5v} V\n")
467
468 #v_in_3v3 = lLTC2945_3v3.read_v_in()
469 #echo(f"LTC2945 3.3V Vin is: {v_in_3v3} V\n")
470
471 #power_5v = lLTC2945_5v.read_power()
472 #echo(f"LTC2945 5V power is: {power_5v*1000} mW\n")
473
474 #power_3v3 = lLTC2945_3v3.read_power()
475 #echo(f"LTC2945 3.3V power is: {power_3v3*1000} mW\n")
476
477 #regs=i2c_bus.read_i2cArray(ic_addr_5v_mon, 0x0, 40, True)
478 #echo(f"LTC2945 5V regs: {regs}\n")
479
480 #v_in_raw = (regs[0x1e] & 0xf) << 4
481 #v_in_raw = v_in_raw | (regs[0x1f] >> 4)
482
483 #v_in_resolution = 0.025
484 #echo("LTC2945 Vin data - ")
485 #echo(f"raw bytes: {regs[0x1e]} {regs[0x1f]}")
486 #echo(f"combined word: {v_in_raw}")
487 #echo(f"Vin [V]: {v_in_raw*v_in_resolution}")
488# ------------------------------------------------------------------------------
lm75_temp_read(obj)
Definition debug.py:399
readSFPStatus(aEEProm, aDiag, aLabel)
Definition debug.py:321
inspect(obj, nodes)
Definition debug.py:63
sfpexpander(obj)
Definition debug.py:127
fanout_sfpscan(obj)
Definition debug.py:236
sfp_status(obj)
Definition debug.py:268