19from timing.common.definitions import kBoardSim, kBoardFMC, kBoardPC059, kBoardMicrozed, kBoardTLU, kBoardMIB, kBoardGIB, kBoardGIBV3, kBoardPC069, kBoardFIB
29def debug(obj, device):
31 Timing master commands.
33 DEVICE: uhal device identifier
35 lDevice = obj.mConnectionManager.getDevice(str(device))
37 lDevice.setTimeoutPeriod(obj.mTimeout)
39 echo(
'Created device ' + click.style(lDevice.id(), fg=
'blue'))
41 lBoardInfo = toolbox.readSubNodes(lDevice.getNode(
'io.config'),
False)
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')
54 obj.mBoardType = lBoardInfo[
'board_type'].value()
55 obj.mCarrierType = lBoardInfo[
'carrier_type'].value()
56 obj.mDesignType = lBoardInfo[
'design_type'].value()
61@debug.command('inspect')
62@click.argument('nodes')
98 lBoardType = obj.mBoardType
99 lIO = lDevice.getNode(
'io')
102 if lBoardType
in [kBoardPC059, kBoardTLU, kBoardMIB, kBoardGIB, kBoardGIBV3]:
103 lUID = lDevice.getNode(
'io.i2c')
105 lUID = lDevice.getNode(
'io.uid_i2c')
107 lPROMSlave =
'UID_PROM' if lBoardType
in [kBoardTLU,kBoardMIB,kBoardGIB,kBoardGIBV3]
else 'FMC_UID_PROM'
109 if lBoardType
in [kBoardGIB, kBoardGIBV3]:
110 lDevice.getNode(
"io.csr.ctrl.i2c_sw_rst").write(0x0)
112 lDevice.getNode(
"io.csr.ctrl.i2c_sw_rst").write(0x1)
114 print(
"switch reset")
117 lValues = lUID.get_slave(lPROMSlave).read_i2cArray(0xfa, 6)
120 lUniqueID = ( lUniqueID << 8 ) | lVal
121 echo(
"Timing Board PROM UID: "+style(hex(lUniqueID), fg=
"blue"))
126@debug.command('sfpexpander', short_help="Debug.")
129 lDevice = obj.mDevice
130 lBoardType = obj.mBoardType
132 if lBoardType != kBoardPC059:
133 secho(
'No SFP expander on {}'.format(kBoardNameMap[lBoardInfo[
'board_type'].value()]))
135 lI2CBusNode = lDevice.getNode(
"io.i2c")
136 lSFPExp = I2CExpanderSlave(lI2CBusNode, lI2CBusNode.get_slave(
'SFPExpander').get_i2c_address())
137 lSFPExpStatus = lSFPExp.debug()
149 for a,v
in enumerate(lSFPExpStatus):
150 echo(
"{} ({}): {}".format(lLabels[a], hex(a), hex(v)))
154@debug.command('scan-i2c', short_help="Debug.")
157 lDevice = obj.mDevice
158 lBoardType = obj.mBoardType
159 lIO = lDevice.getNode(
'io')
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]:
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}
180 secho(f
"Error I don't know about board {lBoardType} : {kBoardNameMap[lBoardType]}", fg=
'red')
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)
193 lDevice.getNode(
"io.csr.ctrl.i2c_sw_rst").write(0x1)
195 lAddresses = lI2CBusNode.scan()
196 print(
" '{}': {} devices found.\n Addresses: {}".format(n, len(lAddresses),
', '.join((hex(a)
for a
in lAddresses))))
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")
204 for channel
in range(0,switch_channels):
205 secho(f
"Scanning with channel {channel} enabled", fg=
'cyan')
207 lI2CBusNode.write_i2cPrimitive(address, [1<<channel])
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))))
216@debug.command('pll', short_help="Debug.")
219 lDevice = obj.mDevice
220 lBoardType = obj.mBoardType
221 lIO = lDevice.getNode(
'io')
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)
228 lI2CBusNode.write_i2cPrimitive(0x70, [1])
230 lSIChip = SI534xSlave(lI2CBusNode, 0x68)
233 lSIVersion = lSIChip.read_device_version()
234 echo(f
"PLL version {hex(lSIVersion)}")
238@debug.command('fanout-sfp-scan', short_help="Debug.")
242 lDevice = obj.mDevice
243 lBoardType = obj.mBoardType
245 if lBoardType != kBoardPC059:
246 print(
'Wrong board', lBoardType,
'sorry mate')
250 lDevice.getNode(
'io.csr.ctrl.rst_i2cmux').write(0x1)
252 lDevice.getNode(
'io.csr.ctrl.rst_i2cmux').write(0x0)
256 lSFPNodeName =
'io.i2c'
257 lI2CBusNode = lDevice.getNode(lSFPNodeName)
258 lSwitchSlave = lI2CBusNode.get_slave(
'SFP_Switch')
259 print(lSwitchSlave.ping())
264 lSwitchSlave.write_i2cPrimitive([3])
265 print(lSwitchSlave.read_i2cPrimitive(1))
266 print(lSwitchSlave.read_i2cPrimitive(1))
267 print(lSwitchSlave.read_i2cPrimitive(1))
270@debug.command('sfp-status', short_help="Debug.")
274 lDevice = obj.mDevice
275 lBoardType = obj.mBoardType
277 if lBoardType == kBoardFMC:
278 lSFPNodeName =
'io.sfp_i2c'
280 elif lBoardType == kBoardPC059:
281 lSFPNodeName =
'io.usfp_i2c'
284 secho(
'No SFP on {}'.format(kBoardNameMap[lBoardType]))
287 lI2CBusNode = lDevice.getNode(lSFPNodeName)
288 lEEPromSlave = lI2CBusNode.get_slave(
'SFP_EEProm')
289 lDiagSlave = lI2CBusNode.get_slave(
'SFP_Diag')
293 if lBoardType == kBoardPC059:
294 lDevice.getNode(
'io.csr.ctrl.rst_i2cmux').write(0x1)
296 lDevice.getNode(
'io.csr.ctrl.rst_i2cmux').write(0x0)
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')
308 for iSFP
in range(8):
310 lSwitchSlave.write_i2cPrimitive([1 << iSFP])
311 except RuntimeError
as lExc:
313 if not lEEPromSlave.ping():
314 secho(
'SFP {} not available'.format(iSFP),fg=
'yellow')
317 secho(
'SFP {} found'.format(iSFP),fg=
'green')
327 def asciidecode( v ):
328 return (
''.join([chr(c)
for c
in v])).rstrip()
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)
336 return '{:.4f} V'.format(((v[0] << 8) + v[1])/float(10000))
338 def biascurdecode( v ):
339 return '{:.3f} mA'.format(((v[0] << 8) + v[1])*2e-3)
341 def powerdecode( v ):
342 return '{:.3f} mW'.format(((v[0] << 8) + v[1])*1e-3)
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))
356 secho(
"{} Vendor info".format(aLabel), fg=
'cyan')
360 echo(toolbox.formatDictTable(lVenInfoEnc, aHdr=
False, aSort=
False))
362 lLaserWl = aEEProm.read_i2cArray(60,2)
363 lLaserWl = (lLaserWl[0] << 8) + lLaserWl[1]
364 echo(
'Laser Wavelength: '+style(str(lLaserWl)+
'nm', fg=
'cyan'))
366 lRegs = collections.OrderedDict()
368 lRegs[
'Identifier'] = aEEProm.read_i2c(0)
369 lRegs[
'Ext Identifier'] = aEEProm.read_i2c(1)
370 lRegs[
'Connector'] = aEEProm.read_i2c(2)
373 lTransComp = aEEProm.read_i2cArray(3, 8)
375 lRegs[
'Encoding'] = aEEProm.read_i2c(11)
376 lRegs[
'BR, Nominal'] = aEEProm.read_i2c(12)
377 lRegs[
'Rate ID'] = aEEProm.read_i2c(13)
379 toolbox.printRegTable(lRegs, aHeader=
False, sort=
False)
382 secho(
"{} Diagnostic info".format(aLabel), fg=
'cyan')
384 lReadings = collections.OrderedDict()
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
397 echo(toolbox.formatDictTable(lReadings, aHdr=
False, aSort=
False))
401@debug.command('lm75-temp-read', short_help="Read temp data from a LM75.")
405 lDevice = obj.mDevice
406 lBoardType = obj.mBoardType
407 lIO = lDevice.getNode(
'io')
409 if lBoardType != kBoardFIB:
410 secho(f
'Only FIB (v2) supported. Board type is {lBoardType}', fg=
'red')
413 i2c_bus = lDevice.getNode(
'io.i2c')
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}")
425@debug.command('ltc2945', short_help="Read data from a LTC2945.")
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())
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)
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")
553 print(f
"Initial output state: {conf_11:#02x}{conf_10:02x}{conf_01:02x}{conf_00:02x}")
555 print(
"reset expander")
556 lDevice.getNode(
"io.csr.ctrl.i2c_exten_rst").write(0x0)
558 lDevice.getNode(
"io.csr.ctrl.i2c_exten_rst").write(0x1)
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)
566 print(f
"Output state after reset: {conf_11_rst:#02x}{conf_10_rst:02x}{conf_01_rst:02x}{conf_00_rst:02x}")
568 print(
"reconfigure expander")
569 lDevice.getNode(
'io').configure_expander()
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)
576 print(f
"Output state after reconfiguring: {conf_11_rcf:#02x}{conf_10_rcf:02x}{conf_01_rcf:02x}{conf_00_rcf:02x}")
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.")
587 lDevice = obj.mDevice
588 lIO = lDevice.getNode(
"io")
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}"
598 intr0 = lDevice.getNode(
"io.csr.stat.i2c_exten_intr0")
599 intr1 = lDevice.getNode(
"io.csr.stat.i2c_exten_intr1")
601 init_i0 = intr0.read()
602 init_i1 = intr1.read()
604 print(f
"Initial status:\nInterrupt 0: {init_i0}\nInterrupt 1: {init_i1}")
606 init_exp = lIO.read_io_expanders()
607 print(f
"Expander ([bus]contents): {format_exp(init_exp)}\n")
612 while_cond =
lambda t:
True
613 print(
"Monitoring interrupt line indefinitely "
614 +
"(requires manual interruption)...")
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()):
624 exp = lIO.read_io_expanders()
627 exp_change = exp != init_exp
631 i0_change = i0 != init_i0
632 i1_change = i1 != init_i1
633 intr_change = i0_change
or i1_change
635 if exp_change
or intr_change:
641 print(f
"INT0 changed: was {init_i0}, now {i0}")
644 print(f
"INT1 changed: was {init_i1}, now {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)}")
653 print(f
"INT0 changed: now {i0}")
655 print(f
"INT1 changed: now {i1}")
657 print(f
"Expander changed: now {format_exp(exp)}")
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.")
664 i0_post = intr0.read()
665 i1_post = intr1.read()
667 print(
"\nAfter reading expander:")
669 print(f
"INT0 changed: now {i0_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 ^")
676 print(
"No changes observed.")
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..')
686 lDevice = obj.mDevice
687 lBoardType = obj.mBoardType
688 lDesignType = obj.mDesignType
689 lIO = lDevice.getNode(
"io")
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')
697 lClockSource=ClockSource.__members__[clocksource]
699 print((
"#"*30) +
"\n Initial PLL status\n" + (
"#"*30))
700 lPLL.get_status(
True)
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)
708 print((
"#"*30) +
"\n Reset line set LOW\n" + (
"#"*30))
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))
714 print(
"\nSetting reset line HIGH...\n")
715 lIO.getNode(
"csr.ctrl.clk_gen_rst").write(0x1)
717 conf_id = lPLL.read_config_id()
718 print(f
"\nFound configuration {init_conf_id} after reset.\n")
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"
723 print((
"#"*30) +
"\n Post-reset PLL status\n" + (
"#"*30))
724 lPLL.get_status(
True)
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).")
733 lDevice = obj.mDevice
734 lIO = lDevice.getNode(
"io")
739 pll_intr = lDevice.getNode(
"io.csr.stat.clk_gen_intr")
741 init_ipll = pll_intr.read()
743 print((
"#"*30) +
"\n Initial PLL status\n" + (
"#"*30))
744 lPLL.get_status(
True)
745 print(f
"\nPLL Interrupt: {init_ipll}\n")
750 while_cond =
lambda t:
True
751 print(
"Monitoring interrupt line indefinitely "
752 +
"(requires manual interruption)...")
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()
761 pll_change = ipll != init_ipll
768 print((
"-"*30) +
"\nInterrupt change found. New PLL status:")
769 lPLL.get_status(
True)
770 print(f
"\nInterrupt was {init_ipll}, now {ipll}\n")
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")
779 ipll_post = pll_intr.read()
781 print(
"\nAfter reading the PLL:")
782 if ipll == ipll_post:
783 print(
"No change in interrupt observed")
785 print(f
"\nPLL Interrupt changed: now {ipll_post}\n")
787 print(
"No changes observed.")