DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
io.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 math
10import sys
11import timing
12
13import timing.cli.toolbox as toolbox
14import timing.common.definitions as defs
15
16from click import echo, style, secho
17from os.path import join, expandvars, basename
18from timing.core import SI534xSlave, I2CExpanderSlave, DACSlave
19
20from timing.common.definitions import kBoardSim, kBoardFMC, kBoardPC059, kBoardMicrozed, kBoardTLU, kBoardFIB, kBoardMIB, kBoardPC069, kBoardGIB, kFIBRev2
21from timing.common.definitions import kFMCRev1, kFMCRev2, kFMCRev3, kFMCRev4, kPC059Rev1, kTLURev1, kSIMRev1, kFIBRev1, kMIBRev1, kGIBRev1
22from timing.common.definitions import kCarrierEnclustraA35, kCarrierKC705, kCarrierMicrozed, kCarrierNexusVideo, kCarrierTrenzTE0712
23from timing.common.definitions import kDesignMaster, kDesignOuroboros, kDesignOuroborosSim, kDesignEndpoint, kDesignFanout, kDesignChronos, kDesignBoreas, kDesignTest, kDesignKerberos, kDesignGaia, kDesignCharon, kDesignHades
24from timing.common.definitions import ClockSource, kFreeRun, kInput0, kInput1, kInput2, kInput3
25from timing.common.definitions import kBoardNameMap, kCarrierNameMap, kDesignNameMap, kUIDRevisionMap, kClockConfigMap
26from timing.common.definitions import kLibrarySupportedBoards, kLibrarySupportedDesigns
27
28# ------------------------------------------------------------------------------
29# __ ___ __
30# / |/ /__ ____ / /____ ____
31# / /|_/ / _ `(_-</ __/ -_) __/
32# /_/ /_/\_,_/___/\__/\__/_/
33
34
35@click.group('io', invoke_without_command=True)
36@click.pass_obj
37@click.argument('device', callback=toolbox.validate_device, shell_complete=toolbox.completeDevices)
38def io(obj, device):
39 '''
40 Timing master commands.
41
42 DEVICE: uhal device identifier
43 '''
44 lDevice = obj.mConnectionManager.getDevice(str(device))
45 if obj.mTimeout:
46 lDevice.setTimeoutPeriod(obj.mTimeout)
47
48 echo('Created device ' + click.style(lDevice.id(), fg='blue'))
49 lTopDesign = lDevice.getNode('')
50 lBoardInfo = toolbox.readSubNodes(lDevice.getNode('io.config'), False)
51 lDevice.dispatch()
52
53 if lBoardInfo['board_type'].value() in kLibrarySupportedBoards and lBoardInfo['design_type'].value() in kLibrarySupportedDesigns:
54 lTopDesign.validate_firmware_version()
55
56 echo("Design '{}' on board '{}' on carrier '{}' with frequency {} MHz".format(
57 style(kDesignNameMap[lBoardInfo['design_type'].value()], fg='blue'),
58 style(kBoardNameMap[lBoardInfo['board_type'].value()], fg='blue'),
59 style(kCarrierNameMap[lBoardInfo['carrier_type'].value()], fg='blue'),
60 style(str(lBoardInfo['clock_frequency'].value()/1e6), fg='blue')
61 ))
62
63 obj.mDevice = lDevice
64
65 obj.mBoardType = lBoardInfo['board_type'].value()
66 obj.mCarrierType = lBoardInfo['carrier_type'].value()
67 obj.mDesignType = lBoardInfo['design_type'].value()
68
69# ------------------------------------------------------------------------------
70
71# ------------------------------------------------------------------------------
72@io.command('reset', short_help="Perform a hard reset on the timing master.")
73@click.option('--soft', '-s', is_flag=True, default=False, help='Soft reset i.e. skip the clock chip configuration.')
74@click.option('--clock-source', 'clocksource', type=click.Choice(ClockSource.__members__.keys()), help='Manually specify clock source, free-running, upstream, etc..')
75@click.option('--force-pll-cfg', 'forcepllcfg', type=click.Path(exists=True), help='Manually specify clock config file' )
76@click.pass_obj
77@click.pass_context
78def reset(ctx, obj, soft, clocksource, forcepllcfg):
79 '''
80 Perform a hard reset on a timing board, including
81
82 \b
83 - ipbus registers
84 - i2c buses
85 - pll and pll configuration
86 '''
87
88 echo('Resetting ' + click.style(obj.mDevice.id(), fg='blue'))
89
90 lDevice = obj.mDevice
91 lBoardType = obj.mBoardType
92 lDesignType = obj.mDesignType
93
94 lIO = lDevice.getNode('io')
95
96 if lBoardType in kLibrarySupportedBoards:
97
98 if soft:
99 lIO.soft_reset()
100 return
101
102 if forcepllcfg is not None:
103 if clocksource is not None:
104 secho("You specified both a clock source for automatic clock config file look-up, and an explicit clock config file. Explicit clock config file will take precedence.", fg='yellow')
105
106 lIO.reset(forcepllcfg)
107 else:
108 if clocksource is None:
109 if lDesignType in [kDesignMaster, kDesignBoreas, kDesignOuroboros, kDesignOuroborosSim]:
110 lClockSource=kFreeRun
111 elif lDesignType in [kDesignEndpoint, kDesignChronos, kDesignFanout, kDesignHades, kDesignCharon]:
112 lClockSource=kInput1
113 elif lDesignType in [kDesignGaia, kDesignKerberos]:
114 lClockSource=kInput0
115 else:
116 secho("Unable to match a default clock source for design {}\nReset failed!".format(lDesignType), fg='red')
117 return
118 else:
119 lClockSource=ClockSource.__members__[clocksource]
120
121 lIO.reset(lClockSource)
122 ctx.invoke(clkstatus)
123 else:
124 secho("Board identifier {} not supported by timing library".format(lBoardType), fg='yellow')
125 # board not supported by library, do reset here
126# ------------------------------------------------------------------------------
127
128# ------------------------------------------------------------------------------
129@io.command('freq', short_help="Measure some frequencies.")
130@click.pass_obj
131def freq(obj):
132 lDevice = obj.mDevice
133 lBoardType = obj.mBoardType
134 lIO = lDevice.getNode('io')
135
136 secho("PLL Clock frequency measurement:", fg='cyan')
137
138 if lBoardType in kLibrarySupportedBoards:
139 echo(lIO.get_clock_frequencies_table())
140 else:
141 secho("Board {} not supported by timing library".format(lBoardType), fg='yellow')
142 # do freq measurement here
143 if lBoardType == kBoardMIB:
144
145 # MIB clock freq meas reg ops here
146
147 secho('MIB clock freqs', fg='green')
148# ------------------------------------------------------------------------------
149
150# ------------------------------------------------------------------------------
151@io.command('status')
152@click.pass_obj
153@click.pass_context
154@click.option('-v', 'verbose', is_flag=True)
155def status(ctx, obj, verbose):
156
157 lDevice = obj.mDevice
158 lBoardType = obj.mBoardType
159 lIO = lDevice.getNode('io')
160
161 if lBoardType in kLibrarySupportedBoards:
162 ctx.invoke(print_hardware_info)
163 echo(lIO.get_status())
164 else:
165 secho("Board {} not supported by timing library".format(lBoardType), fg='yellow')
166 # do status printing here
167# ------------------------------------------------------------------------------
168
169# ------------------------------------------------------------------------------
170@io.command('clk-status')
171@click.pass_obj
172@click.pass_context
173@click.option('-v', 'verbose', is_flag=True)
174def clkstatus(ctx, obj, verbose):
175
176 lDevice = obj.mDevice
177 lDesignType = obj.mDesignType
178 lIO = lDevice.getNode('io')
179 lBoardType = obj.mBoardType
180
181 ctx.invoke(status)
182
183 echo()
184 ctx.invoke(freq)
185 echo()
186
187 if lBoardType in kLibrarySupportedBoards:
188 echo(lIO.get_pll_status())
189 else:
190 secho("Board {} not supported by timing library".format(lBoardType), fg='yellow')
191 # do freq measurement here
192# ------------------------------------------------------------------------------
193
194# ------------------------------------------------------------------------------
195@io.command('dac-setup')
196@click.argument('value', type=click.IntRange(0,0xffff))
197@click.pass_obj
198@click.pass_context
199def dacsetup(ctx, obj, value):
200
201 lDevice = obj.mDevice
202 lBoardType = obj.mBoardType
203 lIO = lDevice.getNode('io')
204
205 if lBoardType == kBoardTLU:
206 lIO.configure_dac(0,value)
207 lIO.configure_dac(1,value)
208 secho("DAC1 and DAC2 set to " + hex(value), fg='cyan')
209 else:
210 secho("DAC setup only supported for TLU")
211# ------------------------------------------------------------------------------
212
213# ------------------------------------------------------------------------------
214@io.command('sfp-status', short_help="Read SFP parameters.")
215@click.pass_obj
216@click.pass_context
217@click.option('--sfp-id', 'sfp_id', required=False, type=click.IntRange(0, 8), help='SFP id to query.')
218def sfpstatus(ctx, obj, sfp_id):
219 '''
220 Read SFP status
221 '''
222
223 lDevice = obj.mDevice
224 lBoardType = obj.mBoardType
225 lCarrierType = obj.mCarrierType
226 lDesignType = obj.mDesignType
227
228 lIO = lDevice.getNode('io')
229
230
231 if lBoardType in kLibrarySupportedBoards:
232 ctx.invoke(print_hardware_info)
233 if sfp_id is not None:
234 echo(lIO.get_sfp_status(sfp_id))
235 else:
236 if lBoardType in [kBoardFMC, kBoardTLU, kBoardPC069]:
237 echo(lIO.get_sfp_status(0))
238 elif lBoardType in [ kBoardPC059, kBoardFIB, kBoardMIB, kBoardGIB ]:
239 # PC059 sfp id 0 is upstream sfp
240 if lBoardType == kBoardPC059:
241 lSFPIDRange = 9
242 elif lBoardType == kBoardFIB:
243 lSFPIDRange = 8
244 elif lBoardType == kBoardMIB:
245 lSFPIDRange = 3
246 elif lBoardType == kBoardGIB:
247 lSFPIDRange = 6
248 for i in range(lSFPIDRange):
249 try:
250 echo(lIO.get_sfp_status(i))
251 #echo()
252 except:
253 secho(f"SFP {i} status gather failed\n", fg='red')
254 pass
255 else:
256 secho(f"I don't know how many SFPs there are for board: {timing.common.definitions.BoardType(lBoardType)}\n", fg='red')
257
258 else:
259 secho("Board {} not supported by timing library".format(lBoardType), fg='yellow')
260 # do sfp status here
261# ------------------------------------------------------------------------------
262
263# ------------------------------------------------------------------------------
264@io.command('switch-sfp-tx', short_help="Control sfp tx")
265@click.pass_obj
266@click.pass_context
267@click.option('--sfp-id', 'sfp_id', required=False, type=click.IntRange(0, 8), help='SFP id to query.')
268@click.option('--on/--off', default=False, help='enable/disable tx; default: FALSE')
269def switchsfptx(ctx, obj, sfp_id, on):
270 '''
271 Toggle SFP tx disable reg (if supported)
272 '''
273
274 lDevice = obj.mDevice
275 lBoardType = obj.mBoardType
276 lCarrierType = obj.mCarrierType
277 lDesignType = obj.mDesignType
278
279 lIO = lDevice.getNode('io')
280
281 if lBoardType in kLibrarySupportedBoards:
282 ctx.invoke(print_hardware_info)
283 lSFP=sfp_id
284 if sfp_id is None:
285 lSFP=0
286 lIO.switch_sfp_tx(lSFP, on)
287 else:
288 secho("Board {} not supported by timing library".format(lBoardType), fg='yellow')
289 # do sfp switch here
290# ------------------------------------------------------------------------------
291
292# ------------------------------------------------------------------------------
293@io.command('switch-sfp-mux', short_help="Switch sfp mux")
294@click.argument('mux', type=int)
295@click.pass_obj
296def switchsfpmux(obj, mux):
297
298 lDevice = obj.mDevice
299 lBoardType = obj.mBoardType
300 lIO = lDevice.getNode('io')
301
302 if lBoardType in [kBoardPC059]:
303
304 echo("Setting sfp mux channel: {}".format(mux))
305 lIO.switch_sfp_mux_channel(mux)
306
307 else:
308 raise RuntimeError('Board {} does not have a sfp mux!'.format(kBoardNameMap[lBoardType]))
309# ------------------------------------------------------------------------------
310
311# ------------------------------------------------------------------------------
312@io.command('print-hardware-info')
313@click.pass_obj
314@click.pass_context
316
317 lDevice = obj.mDevice
318 lBoardType = obj.mBoardType
319 lIO = lDevice.getNode('io')
320
321 if lBoardType in kLibrarySupportedBoards:
322 try:
323 echo(lIO.get_hardware_info())
324 except:
325 secho("Failed to retrieve hardware information! I2C issue? Initial board reset needed?", fg='yellow')
326 e = sys.exc_info()[0]
327 secho("Error: {}".format(e), fg='red')
328 else:
329 secho("Board {} not supported by timing library".format(lBoardType), fg='yellow')
330 # do status printing here
331# ------------------------------------------------------------------------------
status(ctx, obj, verbose)
Definition io.py:155
sfpstatus(ctx, obj, sfp_id)
Definition io.py:218
freq(obj)
Definition io.py:131
print_hardware_info(ctx, obj)
Definition io.py:315
dacsetup(ctx, obj, value)
Definition io.py:199
reset(ctx, obj, soft, clocksource, forcepllcfg)
Definition io.py:78
switchsfptx(ctx, obj, sfp_id, on)
Definition io.py:269
switchsfpmux(obj, mux)
Definition io.py:296
clkstatus(ctx, obj, verbose)
Definition io.py:174