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, I2C9546SwitchSlave
17
18
19from timing.common.definitions import kBoardSim, kBoardFMC, kBoardPC059, kBoardMicrozed, kBoardTLU, kBoardMIB, kBoardGIB, kBoardGIBV3, kBoardPC069, kBoardFIB
20from timing.common.definitions import kCarrierEnclustraA35, kCarrierKC705, kCarrierMicrozed
21from timing.common.definitions import ClockSource
22from timing.common.definitions import kBoardNameMap, kCarrierNameMap, kDesignNameMap
23
24
25# ------------------------------------------------------------------------------
26@click.group('debug', invoke_without_command=True)
27@click.pass_obj
28@click.argument('device', callback=toolbox.validate_device, shell_complete=toolbox.completeDevices)
29def debug(obj, device):
30 '''
31 Timing master commands.
32
33 DEVICE: uhal device identifier
34 '''
35 lDevice = obj.mConnectionManager.getDevice(str(device))
36 if obj.mTimeout:
37 lDevice.setTimeoutPeriod(obj.mTimeout)
38
39 echo('Created device ' + click.style(lDevice.id(), fg='blue'))
40
41 lBoardInfo = toolbox.readSubNodes(lDevice.getNode('io.config'), False)
42 lDevice.dispatch()
43
44 # print({ k:v.value() for k,v in lBoardInfo.items()})
45 # raise SystemExit(0)
46
47 echo("Design '{}' on board '{}' on carrier '{}'".format(
48 style(kDesignNameMap[lBoardInfo['design_type'].value()], fg='blue'),
49 style(kBoardNameMap[lBoardInfo['board_type'].value()], fg='blue'),
50 style(kCarrierNameMap[lBoardInfo['carrier_type'].value()], fg='blue')
51 ))
52
53 obj.mDevice = lDevice
54 obj.mBoardType = lBoardInfo['board_type'].value()
55 obj.mCarrierType = lBoardInfo['carrier_type'].value()
56 obj.mDesignType = lBoardInfo['design_type'].value()
57# ------------------------------------------------------------------------------
58
59
60# ------------------------------------------------------------------------------
61@debug.command('inspect')
62@click.argument('nodes')
63@click.pass_obj
64def inspect(obj, nodes):
65 lDevice = obj.mDevice
66
67 lNodeIds = lDevice.getNodes(nodes.encode('ascii','replace'))
68 lNodeVals = {n:lDevice.getNode(n).read() for n in lNodeIds}
69
70 lDevice.dispatch()
71
72 toolbox.printRegTable(lNodeVals, False)
73# ------------------------------------------------------------------------------
74
75
76# ------------------------------------------------------------------------------
77@debug.command()
78@click.pass_context
79def ipy(ctx):
80 '''
81 Start an interactive IPython session.
82
83 The board HwInterface is accessible as 'lDevice'
84 '''
85 lDevice = ctx.obj.mDevice
86
87 from IPython import embed
88 embed()
89# ------------------------------------------------------------------------------
90
91
92# ------------------------------------------------------------------------------
93@debug.command('uid', short_help="Unique ID reader.")
94@click.pass_obj
95def uuid(obj):
96
97 lDevice = obj.mDevice
98 lBoardType = obj.mBoardType
99 lIO = lDevice.getNode('io')
100
101 # Detect the on-board eprom and read the board UID
102 if lBoardType in [kBoardPC059, kBoardTLU, kBoardMIB, kBoardGIB, kBoardGIBV3]:
103 lUID = lDevice.getNode('io.i2c')
104 else:
105 lUID = lDevice.getNode('io.uid_i2c')
106
107 lPROMSlave = 'UID_PROM' if lBoardType in [kBoardTLU,kBoardMIB,kBoardGIB,kBoardGIBV3] else 'FMC_UID_PROM'
108
109 if lBoardType in [kBoardGIB, kBoardGIBV3]:
110 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x0)
111 lDevice.dispatch()
112 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
113 lDevice.dispatch()
114 print("switch reset")
115 # lIO.set_i2c_mux_channels(0x1)
116
117 lValues = lUID.get_slave(lPROMSlave).read_i2cArray(0xfa, 6)
118 lUniqueID = 0x0
119 for lVal in lValues:
120 lUniqueID = ( lUniqueID << 8 ) | lVal
121 echo("Timing Board PROM UID: "+style(hex(lUniqueID), fg="blue"))
122# ------------------------------------------------------------------------------
123
124
125# ------------------------------------------------------------------------------
126@debug.command('sfpexpander', short_help="Debug.")
127@click.pass_obj
128def sfpexpander(obj):
129 lDevice = obj.mDevice
130 lBoardType = obj.mBoardType
131
132 if lBoardType != kBoardPC059:
133 secho('No SFP expander on {}'.format(kBoardNameMap[lBoardInfo['board_type'].value()]))
134 return
135 lI2CBusNode = lDevice.getNode("io.i2c")
136 lSFPExp = I2CExpanderSlave(lI2CBusNode, lI2CBusNode.get_slave('SFPExpander').get_i2c_address())
137 lSFPExpStatus = lSFPExp.debug()
138
139 lLabels = [
140 'B0 values',
141 'B1 values',
142 'B0 enable',
143 'B1 enable',
144 'B0 invert',
145 'B1 invert',
146 'B0 I/O ',
147 'B1 I/O ',
148 ]
149 for a,v in enumerate(lSFPExpStatus):
150 echo("{} ({}): {}".format(lLabels[a], hex(a), hex(v)))
151# ------------------------------------------------------------------------------
152
153# ------------------------------------------------------------------------------
154@debug.command('scan-i2c', short_help="Debug.")
155@click.pass_obj
156def scan_i2c(obj):
157 lDevice = obj.mDevice
158 lBoardType = obj.mBoardType
159 lIO = lDevice.getNode('io')
160
161 lNodes = []
162 lSwitches={}
163 lSwitchChannels={}
164 if lBoardType in [kBoardFMC, kBoardPC069]:
165 lNodes = ['io.sfp_i2c','io.uid_i2c','io.pll_i2c']
166 elif lBoardType == kBoardPC059:
167 lNodes = ['io.i2c', 'io.usfp_i2c']
168 switch_address=lDevice.getNode('io.i2c').get_slave_address('SFP_Switch')
169 lSwitches={"io.i2c": switch_address}
170 lSwitchChannels={"io.i2c": 8}
171 elif lBoardType in [kBoardTLU, kBoardMIB, kBoardGIB, kBoardGIBV3]:
172 lNodes = ['io.i2c']
173 if lBoardType == kBoardGIBV3:
174 lSwitches={"io.i2c": 0x70}
175 lSwitchChannels={"io.i2c": 8}
176 elif lBoardType == kBoardGIB:
177 lSwitches={"io.i2c": 0x70}
178 lSwitchChannels={"io.i2c": 7}
179 else:
180 secho(f"Error I don't know about board {lBoardType} : {kBoardNameMap[lBoardType]}", fg='red')
181 # if lBoardType == kBoardPC059:
182 # lSFPSwitch = lDevice.getNode('io.i2c').get_slave('SFP_Switch')
183 # print(lSFPSwitch.read_i2cPrimitive(1))
184 # print(lSFPSwitch.write_i2cPrimitive([0x1]))
185 # print(lSFPSwitch.read_i2cPrimitive(1))
186
187 for n in lNodes:
188 lI2CBusNode = lDevice.getNode(n)
189 echo('Scanning '+style(n,fg='cyan'))
190 print("reset switch")
191 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x0)
192 lDevice.dispatch()
193 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
194 lDevice.dispatch()
195 lAddresses = lI2CBusNode.scan()
196 print(" '{}': {} devices found.\n Addresses: {}".format(n, len(lAddresses), ', '.join((hex(a) for a in lAddresses))))
197
198 if n in lSwitches:
199 for switch,address in lSwitches.items():
200 print (f"switch {switch} address: {address}")
201 switch_channels=lSwitchChannels[switch]
202 print(f"working with {switch}, @ adr {address}, it has {switch_channels} channels")
203
204 for channel in range(0,switch_channels):
205 secho(f"Scanning with channel {channel} enabled", fg='cyan')
206 try:
207 lI2CBusNode.write_i2cPrimitive(address, [1<<channel])
208 except:
209 secho(f"failure configuring switch {address}")
210 lAddresses = lI2CBusNode.scan()
211 print(" '{}': {} devices found.\n Addresses: {}".format(n, len(lAddresses), ', '.join((hex(a) for a in lAddresses))))
212
213# ------------------------------------------------------------------------------
214
215# ------------------------------------------------------------------------------
216@debug.command('pll', short_help="Debug.")
217@click.pass_obj
218def pll(obj):
219 lDevice = obj.mDevice
220 lBoardType = obj.mBoardType
221 lIO = lDevice.getNode('io')
222
223 lI2CBusNode = lDevice.getNode('io.i2c')
224 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
225 lDevice.getNode("io.csr.ctrl.clk_gen_rst").write(0x1)
226 lDevice.dispatch()
227
228 lI2CBusNode.write_i2cPrimitive(0x70, [1])
229
230 lSIChip = SI534xSlave(lI2CBusNode, 0x68)
231 #lSIVersion = lSIChip.read_device_version()
232
233 lSIVersion = lSIChip.read_device_version()
234 echo(f"PLL version {hex(lSIVersion)}")
235# ------------------------------------------------------------------------------
236
237# ------------------------------------------------------------------------------
238@debug.command('fanout-sfp-scan', short_help="Debug.")
239@click.pass_obj
241
242 lDevice = obj.mDevice
243 lBoardType = obj.mBoardType
244
245 if lBoardType != kBoardPC059:
246 print('Wrong board', lBoardType, 'sorry mate')
247 return
248
249
250 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x1)
251 lDevice.dispatch()
252 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x0)
253 lDevice.dispatch()
254 time.sleep(1)
255
256 lSFPNodeName = 'io.i2c'
257 lI2CBusNode = lDevice.getNode(lSFPNodeName)
258 lSwitchSlave = lI2CBusNode.get_slave('SFP_Switch')
259 print(lSwitchSlave.ping())
260
261 # print(lSwitchSlave.read_i2cPrimitive(1))
262 # time.sleep(0.1)
263
264 lSwitchSlave.write_i2cPrimitive([3])
265 print(lSwitchSlave.read_i2cPrimitive(1))
266 print(lSwitchSlave.read_i2cPrimitive(1))
267 print(lSwitchSlave.read_i2cPrimitive(1))
268
269# ------------------------------------------------------------------------------
270@debug.command('sfp-status', short_help="Debug.")
271@click.pass_obj
272def sfp_status(obj):
273
274 lDevice = obj.mDevice
275 lBoardType = obj.mBoardType
276
277 if lBoardType == kBoardFMC:
278 lSFPNodeName = 'io.sfp_i2c'
279 lSFPLabel = 'SFP'
280 elif lBoardType == kBoardPC059:
281 lSFPNodeName = 'io.usfp_i2c'
282 lSFPLabel = 'USFP'
283 else:
284 secho('No SFP on {}'.format(kBoardNameMap[lBoardType]))
285 return
286
287 lI2CBusNode = lDevice.getNode(lSFPNodeName)
288 lEEPromSlave = lI2CBusNode.get_slave('SFP_EEProm')
289 lDiagSlave = lI2CBusNode.get_slave('SFP_Diag')
290
291 readSFPStatus(lEEPromSlave, lDiagSlave, lSFPLabel)
292
293 if lBoardType == kBoardPC059:
294 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x1)
295 lDevice.dispatch()
296 lDevice.getNode('io.csr.ctrl.rst_i2cmux').write(0x0)
297 lDevice.dispatch()
298 time.sleep(0.1)
299
300 lI2CBusNode = lDevice.getNode('io.i2c')
301 lSwitchSlave = lI2CBusNode.get_slave('SFP_Switch')
302 lEEPromSlave = lI2CBusNode.get_slave('SFP_EEProm')
303 lDiagSlave = lI2CBusNode.get_slave('SFP_Diag')
304
305 # lOld = lSwitchSlave.read_i2cPrimitive(1)
306 # lSwitchSlave.write_i2cPrimitive([0x0])
307 time.sleep(0.1)
308 for iSFP in range(8):
309 try:
310 lSwitchSlave.write_i2cPrimitive([1 << iSFP])
311 except RuntimeError as lExc:
312 pass
313 if not lEEPromSlave.ping():
314 secho('SFP {} not available'.format(iSFP),fg='yellow')
315 continue
316 else:
317 secho('SFP {} found'.format(iSFP),fg='green')
318 # readSFPStatus(lEEPromSlave, lDiagSlave)
319
320# ------------------------------------------------------------------------------
321
322
323
324# ------------------------------------------------------------------------------
325def readSFPStatus(aEEProm, aDiag, aLabel):
326
327 def asciidecode( v ):
328 return (''.join([chr(c) for c in v])).rstrip()
329
330 def tempdecode( v ):
331 lSign = -1 if ((v[0]>>7) & 0x1) else 1
332 x = lSign*((v[0] & 0x7f) + v[1]/float(0xff))
333 return '{:.3f} C'.format(x)
334
335 def vccdecode( v ):
336 return '{:.4f} V'.format(((v[0] << 8) + v[1])/float(10000))
337
338 def biascurdecode( v ):
339 return '{:.3f} mA'.format(((v[0] << 8) + v[1])*2e-3)
340
341 def powerdecode( v ):
342 return '{:.3f} mW'.format(((v[0] << 8) + v[1])*1e-3)
343
344
345 echo()
346 lVenInfoEnc = collections.OrderedDict()
347 lVenInfoEnc['Name'] = asciidecode(aEEProm.read_i2cArray(20,16))
348 lVenInfoEnc['OUI'] = '{}.{}.{}'.format(*(aEEProm.read_i2cArray(37,3)))
349 lVenInfoEnc['Part Number'] = asciidecode(aEEProm.read_i2cArray(40,16))
350 lVenInfoEnc['Revision'] = asciidecode(aEEProm.read_i2cArray(56,4))
351 lVenInfoEnc['Serial Number'] = asciidecode(aEEProm.read_i2cArray(68,16))
352 lVenInfoEnc['Day'] = asciidecode(aEEProm.read_i2cArray(88,2))
353 lVenInfoEnc['Month'] = asciidecode(aEEProm.read_i2cArray(86,2))
354 lVenInfoEnc['Year'] = asciidecode(aEEProm.read_i2cArray(84,2))
355
356 secho("{} Vendor info".format(aLabel), fg='cyan')
357 # for k,v in lVenInfoEnc.items():
358 # v = ''.join([chr(c) for c in v])
359 # echo(' - '+k+': '+style(v, fg='cyan'))
360 echo(toolbox.formatDictTable(lVenInfoEnc, aHdr=False, aSort=False))
361 echo()
362 lLaserWl = aEEProm.read_i2cArray(60,2)
363 lLaserWl = (lLaserWl[0] << 8) + lLaserWl[1]
364 echo('Laser Wavelength: '+style(str(lLaserWl)+'nm', fg='cyan'))
365
366 lRegs = collections.OrderedDict()
367
368 lRegs['Identifier'] = aEEProm.read_i2c(0)
369 lRegs['Ext Identifier'] = aEEProm.read_i2c(1)
370 lRegs['Connector'] = aEEProm.read_i2c(2)
371
372 # Transciever Compatinility
373 lTransComp = aEEProm.read_i2cArray(3, 8)
374
375 lRegs['Encoding'] = aEEProm.read_i2c(11)
376 lRegs['BR, Nominal'] = aEEProm.read_i2c(12)
377 lRegs['Rate ID'] = aEEProm.read_i2c(13)
378
379 toolbox.printRegTable(lRegs, aHeader=False, sort=False)
380
381 echo()
382 secho("{} Diagnostic info".format(aLabel), fg='cyan')
383
384 lReadings = collections.OrderedDict()
385
386 lReadings['Temp'] = tempdecode(aDiag.read_i2cArray(96, 2))
387 lReadings['Vcc'] = vccdecode(aDiag.read_i2cArray(98, 2))
388 lReadings['TX bias'] = biascurdecode(aDiag.read_i2cArray(100, 2))
389 lReadings['TX power'] = powerdecode(aDiag.read_i2cArray(102, 2))
390 lReadings['RX power'] = powerdecode(aDiag.read_i2cArray(104, 2))
391 lMiscStatus = aDiag.read_i2c(110)
392 lReadings['TX disable'] = (lMiscStatus >> 7) & 0x1
393
394 # for k,v in lReadings.items():
395 # print (k, v)
396
397 echo(toolbox.formatDictTable(lReadings, aHdr=False, aSort=False))
398# ------------------------------------------------------------------------------
399
400# ------------------------------------------------------------------------------
401@debug.command('lm75-temp-read', short_help="Read temp data from a LM75.")
402@click.pass_obj
404
405 lDevice = obj.mDevice
406 lBoardType = obj.mBoardType
407 lIO = lDevice.getNode('io')
408
409 if lBoardType != kBoardFIB:
410 secho(f'Only FIB (v2) supported. Board type is {lBoardType}', fg='red')
411 return
412
413 i2c_bus = lDevice.getNode('io.i2c')
414
415 lValues = i2c_bus.get_slave('TEMP_MON').read_i2cPrimitive(2)
416 temp_raw = (lValues[1] & 0x80) >> 7
417 temp_raw = temp_raw | (lValues[0] << 1)
418 echo(f"LM75 temp data")
419 echo(f" raw bytes: {hex(lValues[0])}, {hex(lValues[1])}")
420 echo(f" combined word: {hex(temp_raw)}")
421 echo(f" temp [C]: {toolbox.twos_complement(temp_raw,9)*0.5}")
422# ------------------------------------------------------------------------------
423
424# ------------------------------------------------------------------------------
425@debug.command('ltc2945', short_help="Read data from a LTC2945.")
426@click.pass_obj
427def lm75_temp_read(obj):
428
429 lDevice = obj.mDevice
430 lBoardType = obj.mBoardType
431 lIO = lDevice.getNode('io')
432
433 if lBoardType not in [kBoardGIB, kBoardGIBV3]:
434 secho(f'Only GIB (v2 (not checked)) supported. Board type is {lBoardType}', fg='red')
435 return
436
437 i2c_bus = lDevice.getNode('io.i2c')
438
439 voltage_power_mon_i2c_addr_map = {"5": 0x67, "3.3": 0x6a, "2.5": 0x69}
440 voltage_sense_resistance_map = {"5": 0.005, "3.3": 0.02, "2.5": 0.02}
441
442 for v,addr in voltage_power_mon_i2c_addr_map.items():
443 sense_r = voltage_sense_resistance_map[v]
444 lLTC2945 = LTC2945Node(i2c_bus, addr, sense_r)
445
446 lLTC2945.write_i2c(0x0, 0x05)
447
448 delta_sense_v = lLTC2945.read_delta_sense_v()
449 v_in = lLTC2945.read_v_in()
450 power = lLTC2945.read_power()
451
452 echo(f"LTC2945 {v}V data is:")
453 echo(f"deltaSenseV : {delta_sense_v*1000} mV")
454 echo(f"Vin : {v_in} V")
455 echo(f"power is: {power*1000} mW\n")
456
457 #lLTC2945_5v = LTC2945Node(i2c_bus, ic_addr_5v_mon, 0.005)
458 #lLTC2945_3v3 = LTC2945Node(i2c_bus, ic_addr_3v3_mon, 0.02)
459
460 #lLTC2945_5v.write_i2c(0x0, 0x05)
461 #lLTC2945_3v3.write_i2c(0x0, 0x05)
462
463 #delta_sense_v_5v = lLTC2945_5v.read_delta_sense_v()
464 #echo(f"LTC2945 5V deltaSense V is: {delta_sense_v_5v*1000} mV\n")
465
466 #delta_sense_v_3v3 = lLTC2945_3v3.read_delta_sense_v()
467 #echo(f"LTC2945 3.3V deltaSense V is: {delta_sense_v_3v3*1000} mV\n")
468
469 #v_in_5v = lLTC2945_5v.read_v_in()
470 #echo(f"LTC2945 5V Vin is: {v_in_5v} V\n")
471
472 #v_in_3v3 = lLTC2945_3v3.read_v_in()
473 #echo(f"LTC2945 3.3V Vin is: {v_in_3v3} V\n")
474
475 #power_5v = lLTC2945_5v.read_power()
476 #echo(f"LTC2945 5V power is: {power_5v*1000} mW\n")
477
478 #power_3v3 = lLTC2945_3v3.read_power()
479 #echo(f"LTC2945 3.3V power is: {power_3v3*1000} mW\n")
480
481 #regs=i2c_bus.read_i2cArray(ic_addr_5v_mon, 0x0, 40, True)
482 #echo(f"LTC2945 5V regs: {regs}\n")
483
484 #v_in_raw = (regs[0x1e] & 0xf) << 4
485 #v_in_raw = v_in_raw | (regs[0x1f] >> 4)
486
487 #v_in_resolution = 0.025
488 #echo("LTC2945 Vin data - ")
489 #echo(f"raw bytes: {regs[0x1e]} {regs[0x1f]}")
490 #echo(f"combined word: {v_in_raw}")
491 #echo(f"Vin [V]: {v_in_raw*v_in_resolution}")
492# ------------------------------------------------------------------------------
493
494# ------------------------------------------------------------------------------
495@debug.group('gib', short_help='GIB debugging command group.')
496@click.option('--force', '-f', is_flag=True, default=False,
497 help="Run when GIB isn't detected")
498@click.pass_obj
499def gib(obj, force):
500 lDevice = obj.mDevice
501 lBoardType = obj.mBoardType
502
503 if lBoardType not in [kBoardGIB, kBoardGIBV3]:
504 if force:
505 secho('Warning, only designed for GIB(vX) testing. '
506 + 'Continuing due to --force flag...')
507 else:
508 secho('Only designed for GIB(vX) testing. Stopping...')
509 return
510 obj.mI2CBus = lDevice.getNode('io.i2c')
511# ------------------------------------------------------------------------------
512
513# ------------------------------------------------------------------------------
514@gib.command('reset-switch', short_help="Debug.")
515@click.pass_obj
517 lDevice = obj.mDevice
518 lI2CSwitch = I2C9546SwitchSlave(obj.mI2CBus, obj.mI2CBus.get_slave('I2CSwitch').get_i2c_address())
519
520 echo(f"Initial switch status:\t{lI2CSwitch.read_channels_states():08b}")
521 lI2CSwitch.enable_channel(0)
522 echo(f"Enabled channel 0:\t{lI2CSwitch.read_channels_states():08b}")
523 echo()
524
525 echo("reset switch")
526 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x0)
527 lDevice.dispatch()
528 lDevice.getNode("io.csr.ctrl.i2c_sw_rst").write(0x1)
529 lDevice.dispatch()
530
531 echo(f"State after reset:\t{lI2CSwitch.read_channels_states():08b}")
532# ------------------------------------------------------------------------------
533
534# ------------------------------------------------------------------------------
535@gib.command('reset-expander', short_help="Debug.")
536@click.pass_obj
538 lDevice = obj.mDevice
539 expander0 = I2CExpanderSlave(obj.mI2CBus, obj.mI2CBus.get_slave('SFPExpander0').get_i2c_address())
540 expander1 = I2CExpanderSlave(obj.mI2CBus, obj.mI2CBus.get_slave('SFPExpander1').get_i2c_address())
541
542 conf_00 = expander0.read_outputs_config(0)
543 conf_01 = expander0.read_outputs_config(1)
544 conf_10 = expander1.read_outputs_config(0)
545 conf_11 = expander1.read_outputs_config(1)
546
547 print("Expected state : 0x{00}{ff}{ff}{ff}")
548 print("{00}: Expander 1 bus 1 is output")
549 print("{ff}: Expander 1 bus 0 is intput")
550 print("{ff}: Expander 0 bus 1 is intput")
551 print("{ff}: Expander 0 bus 0 is intput\n")
552
553 print(f"Initial output state: {conf_11:#02x}{conf_10:02x}{conf_01:02x}{conf_00:02x}")
554
555 print("reset expander")
556 lDevice.getNode("io.csr.ctrl.i2c_exten_rst").write(0x0)
557 lDevice.dispatch()
558 lDevice.getNode("io.csr.ctrl.i2c_exten_rst").write(0x1)
559 lDevice.dispatch()
560
561 conf_00_rst = expander0.read_outputs_config(0)
562 conf_01_rst = expander0.read_outputs_config(1)
563 conf_10_rst = expander1.read_outputs_config(0)
564 conf_11_rst = expander1.read_outputs_config(1)
565
566 print(f"Output state after reset: {conf_11_rst:#02x}{conf_10_rst:02x}{conf_01_rst:02x}{conf_00_rst:02x}")
567
568 print("reconfigure expander")
569 lDevice.getNode('io').configure_expander()
570
571 conf_00_rcf = expander0.read_outputs_config(0)
572 conf_01_rcf = expander0.read_outputs_config(1)
573 conf_10_rcf = expander1.read_outputs_config(0)
574 conf_11_rcf = expander1.read_outputs_config(1)
575
576 print(f"Output state after reconfiguring: {conf_11_rcf:#02x}{conf_10_rcf:02x}{conf_01_rcf:02x}{conf_00_rcf:02x}")
577# ------------------------------------------------------------------------------
578
579# ------------------------------------------------------------------------------
580@gib.command('monitor-exp-intr', short_help="Debug.")
581@click.option('--no-end', is_flag=True, default=False,
582 help="Continue monitoring indefintely (requires manual interrupt).")
583@click.option('--no-exp-read', is_flag=True, default=False,
584 help="Prevents reading out the expander status.")
585@click.pass_obj
586def monitor_exp_intr(obj, no_end, no_exp_read):
587 lDevice = obj.mDevice
588 lIO = lDevice.getNode("io")
589
590 def format_exp(exp_data):
591 bus_10 = f"{(exp_data>>16)%(2**8):08b}"
592 bus_01 = f"{(exp_data>>8)%(2**8):08b}"
593 bus_00 = f"{exp_data%(2**8):08b}"
594 return f"[10]{bus_10} [01]{bus_01} [00]{bus_00}"
595
596 num_seconds = 10
597
598 intr0 = lDevice.getNode("io.csr.stat.i2c_exten_intr0")
599 intr1 = lDevice.getNode("io.csr.stat.i2c_exten_intr1")
600
601 init_i0 = intr0.read()
602 init_i1 = intr1.read()
603 lDevice.dispatch()
604 print(f"Initial status:\nInterrupt 0: {init_i0}\nInterrupt 1: {init_i1}")
605 if not no_exp_read:
606 init_exp = lIO.read_io_expanders()
607 print(f"Expander ([bus]contents): {format_exp(init_exp)}\n")
608
609 changed = False
610
611 if no_end:
612 while_cond = lambda t: True
613 print("Monitoring interrupt line indefinitely "
614 + "(requires manual interruption)...")
615 else:
616 print(f"Monitoring interrupt line for {num_seconds}s...")
617 t_end = time.time() + num_seconds
618 while_cond = lambda t: t < t_end
619 while while_cond(time.time()):
620 i0 = intr0.read()
621 i1 = intr1.read()
622 lDevice.dispatch()
623 if not no_exp_read:
624 exp = lIO.read_io_expanders()
625 time.sleep(1e-1) # Reduce probability that change occurs
626 # between reading interrupt line and expander state
627 exp_change = exp != init_exp
628 else:
629 exp_change = False
630
631 i0_change = i0 != init_i0
632 i1_change = i1 != init_i1
633 intr_change = i0_change or i1_change
634
635 if exp_change or intr_change:
636 if not no_end:
637 changed = True
638 break
639 else:
640 if i0_change:
641 print(f"INT0 changed: was {init_i0}, now {i0}")
642 init_i0 = i0
643 if i1_change:
644 print(f"INT1 changed: was {init_i1}, now {i1}")
645 init_i1 = i1
646 if exp_change and (not no_exp_read):
647 print(f"Expander changed: was {format_exp(init_exp)},")
648 print(f" now {format_exp(exp)}")
649 init_exp = exp
650
651 if changed:
652 if i0_change:
653 print(f"INT0 changed: now {i0}")
654 if i1_change:
655 print(f"INT1 changed: now {i1}")
656 if exp_change:
657 print(f"Expander changed: now {format_exp(exp)}")
658 if not intr_change:
659 print("No change in interrupt seen after change in expander")
660 print("This could be due to the change occuring between "
661 + "reading the interrupt lines and reading the "
662 + "expander state - multiple tests recommended.")
663 time.sleep(0.1)
664 i0_post = intr0.read()
665 i1_post = intr1.read()
666 lDevice.dispatch()
667 print("\nAfter reading expander:")
668 if i0 != i0_post:
669 print(f"INT0 changed: now {i0_post}")
670 if i1 != i1_post:
671 print(f"INT1 changed: now {i1_post}")
672 if (i0 == i0_post) and (i1 == i1_post):
673 print("No change in interrupt lines")
674 print(" ^ UNEXPECTED BEHAVIOUR ^")
675 else:
676 print("No changes observed.")
677# ------------------------------------------------------------------------------
678
679# ------------------------------------------------------------------------------
680@gib.command('reset-pll', short_help="Debug.")
681@click.option('--clock-source', 'clocksource',
682 type=click.Choice(ClockSource.__members__.keys()),
683 help='Manually specify clock source, free-running, upstream, etc..')
684@click.pass_obj
685def reset_pll(obj, clocksource):
686 lDevice = obj.mDevice
687 lBoardType = obj.mBoardType
688 lDesignType = obj.mDesignType
689 lIO = lDevice.getNode("io")
690 lPLL = lIO.get_pll()
691
692 if clocksource is None:
693 lClockSource = toolbox.get_default_clock_source(
694 lDesignType, lBoardType)
695 secho(f"Default clock config selected for {kDesignNameMap[lDesignType]} on {kBoardNameMap[lBoardType]} is: {lClockSource}", fg='yellow')
696 else:
697 lClockSource=ClockSource.__members__[clocksource]
698
699 print(("#"*30) + "\n Initial PLL status\n" + ("#"*30))
700 lPLL.get_status(True)
701
702 init_conf_id = lPLL.read_config_id()
703 print(f"\nFound configuration {init_conf_id} prior to reset.\n")
704 print("Setting reset line LOW...\n")
705 lIO.getNode("csr.ctrl.clk_gen_rst").write(0x0)
706 lDevice.dispatch()
707
708 print(("#"*30) + "\n Reset line set LOW\n" + ("#"*30))
709 try:
710 lPLL.get_status(True)
711 except Exception as e:
712 print("SUCCESS - PLL can't be ready with reset low, exception:\n" + str(e))
713
714 print("\nSetting reset line HIGH...\n")
715 lIO.getNode("csr.ctrl.clk_gen_rst").write(0x1)
716 lDevice.dispatch()
717 conf_id = lPLL.read_config_id()
718 print(f"\nFound configuration {init_conf_id} after reset.\n")
719 time.sleep(1)
720 lIO.configure_pll(lIO.get_full_clock_config_file_path(lClockSource))
721 assert lPLL.read_config_id() == init_conf_id, "New PLL configuration does not match initial configuration, io reset advised"
722
723 print(("#"*30) + "\n Post-reset PLL status\n" + ("#"*30))
724 lPLL.get_status(True)
725# ------------------------------------------------------------------------------
726
727# ------------------------------------------------------------------------------
728@gib.command('monitor-pll-intr', short_help="Debug.")
729@click.option('--no-end', is_flag=True, default=False,
730 help="Continue monitoring indefintely (requires manual interrupt).")
731@click.pass_obj
732def monitor_pll_intr(obj, no_end):
733 lDevice = obj.mDevice
734 lIO = lDevice.getNode("io")
735 lPLL = lIO.get_pll()
736
737 num_seconds = 10
738
739 pll_intr = lDevice.getNode("io.csr.stat.clk_gen_intr")
740
741 init_ipll = pll_intr.read()
742 lDevice.dispatch()
743 print(("#"*30) + "\n Initial PLL status\n" + ("#"*30))
744 lPLL.get_status(True)
745 print(f"\nPLL Interrupt: {init_ipll}\n")
746
747 changed = False
748
749 if no_end:
750 while_cond = lambda t: True
751 print("Monitoring interrupt line indefinitely "
752 + "(requires manual interruption)...")
753 else:
754 print(f"Monitoring interrupt line for {num_seconds}s...")
755 t_end = time.time() + num_seconds
756 while_cond = lambda t: t < t_end
757 while while_cond(time.time()):
758 ipll = pll_intr.read()
759 lDevice.dispatch()
760
761 pll_change = ipll != init_ipll
762
763 if pll_change:
764 if not no_end:
765 changed = True
766 break
767 else:
768 print(("-"*30) + "\nInterrupt change found. New PLL status:")
769 lPLL.get_status(True)
770 print(f"\nInterrupt was {init_ipll}, now {ipll}\n")
771 init_ipll = ipll
772
773 if changed:
774 print("\nInterrupt found\n")
775 print(("#"*30) + "\n New PLL status\n" + ("#"*30))
776 lPLL.get_status(True)
777 print(f"\nPLL Interrupt: was {init_ipll}, now {ipll}\n")
778
779 ipll_post = pll_intr.read()
780 lDevice.dispatch()
781 print("\nAfter reading the PLL:")
782 if ipll == ipll_post:
783 print("No change in interrupt observed")
784 else:
785 print(f"\nPLL Interrupt changed: now {ipll_post}\n")
786 else:
787 print("No changes observed.")
788# ------------------------------------------------------------------------------
gib(obj, force)
Definition debug.py:499
monitor_pll_intr(obj, no_end)
Definition debug.py:732
lm75_temp_read(obj)
Definition debug.py:403
readSFPStatus(aEEProm, aDiag, aLabel)
Definition debug.py:325
reset_pll(obj, clocksource)
Definition debug.py:685
monitor_exp_intr(obj, no_end, no_exp_read)
Definition debug.py:586
inspect(obj, nodes)
Definition debug.py:64
reset_switch(obj)
Definition debug.py:516
sfpexpander(obj)
Definition debug.py:128
fanout_sfpscan(obj)
Definition debug.py:240
reset_expander(obj)
Definition debug.py:537
sfp_status(obj)
Definition debug.py:272