DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
master.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 timing
11import traceback
12import sys
13import random
14from io import StringIO
15
16# PDT imports
17import timing.cli.toolbox as toolbox
18import timing.common.definitions as defs
19
20from click import echo, style, secho
21from os.path import join, expandvars, basename
22from timing.core import SI534xSlave, I2CExpanderSlave
23
24from timing.common.definitions import kBoardSim, kBoardFMC, kBoardPC059, kBoardMicrozed, kBoardTLU
25from timing.common.definitions import kCarrierEnclustraA35, kCarrierKC705, kCarrierMicrozed
26from timing.common.definitions import kDesignMaster, kDesignOuroboros, kDesignOuroborosSim, kDesignEndpoint, kDesignFanout, kDesignOverlord
27from timing.common.definitions import kBoardNameMap, kCarrierNameMap, kDesignNameMap, TimestampSource
28from timing.common.definitions import kLibrarySupportedBoards, kLibrarySupportedDesigns
29
30from timing.common.toolbox import format_firmware_version
31# ------------------------------------------------------------------------------
32# __ ___ __
33# / |/ /__ ____ / /____ ____
34# / /|_/ / _ `(_-</ __/ -_) __/
35# /_/ /_/\_,_/___/\__/\__/_/
36
37
38@click.group('mst', invoke_without_command=True)
39@click.pass_obj
40@click.argument('device', callback=toolbox.validate_device, shell_complete=toolbox.completeDevices)
41def master(obj, device):
42 '''
43 Timing master commands.
44
45 DEVICE: uhal device identifier
46 '''
47 lDevice = obj.mConnectionManager.getDevice(str(device))
48 if obj.mTimeout:
49 lDevice.setTimeoutPeriod(obj.mTimeout)
50
51 echo('Created device ' + click.style(lDevice.id(), fg='blue'))
52
53 lTopDesign = lDevice.getNode('')
54
55 lMaster = lDevice.getNode('master')
56 lBoardInfo = toolbox.readSubNodes(lDevice.getNode('io.config'), False)
57 lNCmdchannels = lMaster.getNode('global.config.n_chan').read()
58 lDevice.dispatch()
59
60 echo("Design '{}' on board '{}' on carrier '{}' with frequency {} MHz".format(
61 style(kDesignNameMap[lBoardInfo['design_type'].value()], fg='blue'),
62 style(kBoardNameMap[lBoardInfo['board_type'].value()], fg='blue'),
63 style(kCarrierNameMap[lBoardInfo['carrier_type'].value()], fg='blue'),
64 style(str(lBoardInfo['clock_frequency'].value()/1e6), fg='blue')
65 ))
66
67 if lBoardInfo['board_type'].value() in kLibrarySupportedBoards and lBoardInfo['design_type'].value() in kLibrarySupportedDesigns:
68 lVersion = lTopDesign.read_firmware_version()
69 lTopDesign.validate_firmware_version()
70
71 try:
72 echo(lDevice.getNode('io').get_hardware_info())
73 except:
74 secho("Failed to retrieve hardware information! I2C issue? Initial board reset needed?", fg='yellow')
75 e = sys.exc_info()[0]
76 secho("Error: {}".format(e), fg='red')
77 else:
78 lVersion = lMaster.getNode('global.version').read()
79 lDevice.dispatch()
80
81 echo("Master FW rev: {}, channels: {}".format(
82 style(format_firmware_version(lVersion), fg='cyan'),
83 style(str(lNCmdchannels), fg='cyan'),
84 ))
85
86 obj.mDevice = lDevice
87 obj.mTopDesign = lTopDesign
88 obj.mMaster = lMaster
89 obj.mIO = lDevice.getNode('io')
90
91 obj.mVersion = lVersion
92 obj.mBoardType = lBoardInfo['board_type'].value()
93 obj.mCarrierType = lBoardInfo['carrier_type'].value()
94 obj.mDesignType = lBoardInfo['design_type'].value()
95
96 # only overlord has ext trig ept
97 if obj.mDesignType == kDesignOverlord:
98 obj.mExtTrig = obj.mTopDesign.get_external_triggers_endpoint_node()
99
100# ------------------------------------------------------------------------------
101
102# ------------------------------------------------------------------------------
103@master.command('status', short_help="Print master status")
104@click.pass_obj
105def status(obj):
106
107 lMaster = obj.mMaster
108 lIO = obj.mIO
109 firmware_clock_frequency_hz = lIO.read_firmware_frequency()
110
111 echo(lMaster.get_status_with_date(firmware_clock_frequency_hz))
112# ------------------------------------------------------------------------------
113
114# ------------------------------------------------------------------------------
115@master.command('synctime', help="Sync timestamp, and enable broadcast. kMixed: TS value from SW, strobe from external")
116@click.pass_obj
117@click.argument('source', type=click.Choice(TimestampSource.__members__.keys()))
118def synctime(obj, source):
119
120 lDesign = obj.mTopDesign
121 lMaster = obj.mMaster
122 lSource=TimestampSource.__members__[source]
123 lMaster.sync_timestamp(lSource)
124# ------------------------------------------------------------------------------
125
126# ------------------------------------------------------------------------------
127@master.command('send-cmd', short_help='Inject a single command.')
128@click.pass_obj
129@click.argument('cmd', type=toolbox.IntRange(0x0,0xff))
130@click.argument('chan', type=int)
131@click.option('-n', type=int, default=1)
132def sendcmd(obj, cmd, chan, n):
133 '''
134 Inject a single command.
135 '''
136
137 lMaster = obj.mMaster
138 lMaster.send_fl_cmd(cmd,chan,n)
139# ------------------------------------------------------------------------------
140
141# ------------------------------------------------------------------------------
142@master.command('faketrig-conf')
143@click.pass_obj
144@click.argument('cmd', type=toolbox.IntRange(0x0,0xff))
145@click.argument('chan', type=int)
146@click.argument('rate', type=float)
147@click.option('--poisson', is_flag=True, default=False, help="Randomize time interval between consecutive triggers.")
148def faketriggen(obj, cmd, chan, rate, poisson):
149 '''
150 \b
151 Enables the internal trigger generator.
152 Configures the internal command generator to produce triggers at a defined frequency.
153
154 Rate = (50MHz / 2^(d+8)) / p where n in [0,15] and p in [1,256]
155 \b
156 DIVIDER (int): Frequency divider.
157 '''
158
159 # The division from 50MHz to the desired rate is done in three steps:
160 # a) A pre-division by 256
161 # b) Division by a power of two set by n = 2 ^ rate_div_d (ranging from 2^0 -> 2^15)
162 # c) 1-in-n prescaling set by n = rate_div_p
163
164 lTopDesign = obj.mTopDesign
165 lTopDesign.enable_periodic_fl_cmd(cmd,chan,rate,poisson)
166# ------------------------------------------------------------------------------
167
168# ------------------------------------------------------------------------------
169@master.command('faketrig-clear')
170@click.pass_obj
171@click.argument('chan', type=int)
172def faketrigclear(obj, chan):
173 '''
174 Clear the internal trigger generator.
175 '''
176 lMaster = obj.mMaster
177 lMaster.disable_periodic_fl_cmd(chan)
178 secho( "Fake triggers disabled; chan: {}".format(chan), fg='green')
179# ------------------------------------------------------------------------------
180
181# ------------------------------------------------------------------------------
182@master.command('write-ept-reg')
183@click.pass_obj
184@click.argument('adr', type=toolbox.IntRange(0x0,0xffff))
185@click.argument('reg', type=toolbox.IntRange(0x0,0x7b))
186@click.argument('data', callback=toolbox.split_ints)
187@click.argument('mode', type=bool)
188def writeeptreg(obj, adr, reg, data, mode):
189 '''
190 Write data from endpoint
191 '''
192 lMaster = obj.mMaster
193 rx_data = lMaster.write_endpoint_data(adr, reg, data, mode)
194 #secho( "Fake triggers disabled; chan: {}".format(chan), fg='green')
195# ------------------------------------------------------------------------------
196
197# ------------------------------------------------------------------------------
198@master.command('read-ept-reg')
199@click.pass_obj
200@click.argument('adr', type=toolbox.IntRange(0x0,0xffff))
201@click.argument('reg', type=toolbox.IntRange(0x0,0x7b))
202@click.argument('length', type=int)
203@click.argument('mode', type=bool)
204def readeptreg(obj, adr, reg, length, mode):
205 '''
206 Read data from endpoint
207 '''
208 lMaster = obj.mMaster
209 rx_data = lMaster.read_endpoint_data(adr, reg, length, mode)
210 secho( f"Data from endpoint {adr}, reg {reg} and length {length}: {rx_data}", fg='green')
211# ------------------------------------------------------------------------------
212
213# ------------------------------------------------------------------------------
214@master.command('transmit-async-packet')
215@click.pass_obj
216@click.option('--packet', '-p', callback=toolbox.split_ints)
217def transmitasyncpacket(obj, packet):
218 '''
219 Transmit already formed packet
220 '''
221 lMaster = obj.mMaster
222 if len(packet) == 0:
223 # make a random packet
224 packet = [0x0, 0x0] + random.sample(range(256),random.randint(5, 20)) + [0x1aa]
225
226 rx_packet = lMaster.transmit_async_packet(packet)
227 secho( f"tx packet: {packet}", fg='green')
228 secho( f"rx packet: {rx_packet}", fg='green')
229# ------------------------------------------------------------------------------
230
231# ------------------------------------------------------------------------------
232@master.command('reset-command-counters')
233@click.pass_obj
235 '''
236 Transmit already formed packet
237 '''
238 lMaster = obj.mMaster
239 lMaster.reset_command_counters()
240# ------------------------------------------------------------------------------
241
242# ------------------------------------------------------------------------------
243@master.command('control-timestamp-broadcast')
244@click.option('--on/--off', default=True, help='enable/disable ts broadcast')
245@click.pass_obj
247 '''
248 Enable or disable timestamp broadcast
249 '''
250 lMaster = obj.mMaster
251 if on:
252 lMaster.enable_timestamp_broadcast()
253 else:
254 lMaster.disable_timestamp_broadcast()
255# ------------------------------------------------------------------------------
256
257# ------------------------------------------------------------------------------
258@master.group('part', invoke_without_command=True)
259@click.pass_obj
260def partition(obj):
261 """
262 Partition specific commands
263 """
264 secho("New partition concept not yet supported", fg='yellow')
265# ------------------------------------------------------------------------------
266
267
268# ------------------------------------------------------------------------------
269@partition.command('status', short_help='Display the status of the timing master.')
270@click.pass_obj
271@click.option('--watch', '-w', is_flag=True, default=False, help='Turn on automatic refresh')
272@click.option('--period','-p', type=click.IntRange(0, 10), default=2, help='Automatic refresh period')
273def partstatus(obj, watch, period):
274 '''
275 Display the master status, accepted and rejected command counters
276 '''
277
278 # lDevice = obj.mDevice
279 pass
280# ------------------------------------------------------------------------------
281
282# ------------------------------------------------------------------------------
283@partition.command('configure', short_help='Prepares partition for data taking.')
284@click.pass_obj
285def configure(obj):
286 pass
287# ------------------------------------------------------------------------------
288
289# ------------------------------------------------------------------------------
290@master.command('configure-endpoint-cmd-decoder', short_help='Configure a slot of endpoint command decoder.')
291@click.pass_obj
292@click.argument('addr', type=toolbox.IntRange(0x0,0xffff))
293@click.argument('slot', type=toolbox.IntRange(0x0,0x7))
294@click.argument('cmd', type=toolbox.IntRange(0x0,0xff))
295def configureendpointcmddecoder(obj, addr, slot, cmd):
296 '''
297 Configure endpoint command decoder
298 '''
299
300 lMaster = obj.mMaster
301 lMaster.configure_endpoint_command_decoder(addr,slot,cmd)
302# ------------------------------------------------------------------------------
sendcmd(obj, cmd, chan, n)
Definition master.py:132
writeeptreg(obj, adr, reg, data, mode)
Definition master.py:188
transmitasyncpacket(obj, packet)
Definition master.py:217
faketrigclear(obj, chan)
Definition master.py:172
synctime(obj, source)
Definition master.py:118
resetcommandcounters(obj)
Definition master.py:234
partstatus(obj, watch, period)
Definition master.py:273
controltimestampbroadcast(obj, on)
Definition master.py:246
readeptreg(obj, adr, reg, length, mode)
Definition master.py:204
configureendpointcmddecoder(obj, addr, slot, cmd)
Definition master.py:295
faketriggen(obj, cmd, chan, rate, poisson)
Definition master.py:148