1from __future__
import print_function
14from io
import StringIO
20from click
import echo, style, secho
21from os.path
import join, expandvars, basename
22from timing.core import SI534xSlave, I2CExpanderSlave
26from timing.common.definitions import kDesignMaster, kDesignOuroboros, kDesignOuroborosSim, kDesignEndpoint, kDesignFanout, kDesignOverlord
38@click.group('mst', invoke_without_command=True)
40@click.argument('device', callback=toolbox.validate_device, shell_complete=toolbox.completeDevices)
41def master(obj, device):
43 Timing master commands.
45 DEVICE: uhal device identifier
47 lDevice = obj.mConnectionManager.getDevice(str(device))
49 lDevice.setTimeoutPeriod(obj.mTimeout)
51 echo(
'Created device ' + click.style(lDevice.id(), fg=
'blue'))
53 lTopDesign = lDevice.getNode(
'')
55 lMaster = lDevice.getNode(
'master')
56 lBoardInfo = toolbox.readSubNodes(lDevice.getNode(
'io.config'),
False)
57 lNCmdchannels = lMaster.getNode(
'global.config.n_chan').read()
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')
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()
72 echo(lDevice.getNode(
'io').get_hardware_info())
74 secho(
"Failed to retrieve hardware information! I2C issue? Initial board reset needed?", fg=
'yellow')
76 secho(
"Error: {}".format(e), fg=
'red')
78 lVersion = lMaster.getNode(
'global.version').read()
81 echo(
"Master FW rev: {}, channels: {}".format(
82 style(format_firmware_version(lVersion), fg=
'cyan'),
83 style(str(lNCmdchannels), fg=
'cyan'),
87 obj.mTopDesign = lTopDesign
89 obj.mIO = lDevice.getNode(
'io')
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()
97 if obj.mDesignType == kDesignOverlord:
98 obj.mExtTrig = obj.mTopDesign.get_external_triggers_endpoint_node()
103@master.command('status', short_help="Print master status")
107 lMaster = obj.mMaster
109 firmware_clock_frequency_hz = lIO.read_firmware_frequency()
111 echo(lMaster.get_status_with_date(firmware_clock_frequency_hz))
115@master.command('synctime', help="Sync timestamp, and enable broadcast. kMixed: TS value from SW, strobe from external")
117@click.argument('source', type=click.Choice(TimestampSource.__members__.keys()))
120 lDesign = obj.mTopDesign
121 lMaster = obj.mMaster
122 lSource=TimestampSource.__members__[source]
123 lMaster.sync_timestamp(lSource)
127@master.command('send-cmd', short_help='Inject a single command.')
129@click.argument('cmd', type=toolbox.IntRange(0x0,0xff))
130@click.argument('chan', type=int)
131@click.option('-n', type=int, default=1)
134 Inject a single command.
137 lMaster = obj.mMaster
138 lMaster.send_fl_cmd(cmd,chan,n)
142@master.command('faketrig-conf')
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.")
151 Enables the internal trigger generator.
152 Configures the internal command generator to produce triggers at a defined frequency.
154 Rate = (50MHz / 2^(d+8)) / p where n in [0,15] and p in [1,256]
156 DIVIDER (int): Frequency divider.
164 lTopDesign = obj.mTopDesign
165 lTopDesign.enable_periodic_fl_cmd(cmd,chan,rate,poisson)
169@master.command('faketrig-clear')
171@click.argument('chan', type=int)
174 Clear the internal trigger generator.
176 lMaster = obj.mMaster
177 lMaster.disable_periodic_fl_cmd(chan)
178 secho(
"Fake triggers disabled; chan: {}".format(chan), fg=
'green')
182@master.command('write-ept-reg')
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)
190 Write data from endpoint
192 lMaster = obj.mMaster
193 rx_data = lMaster.write_endpoint_data(adr, reg, data, mode)
198@master.command('read-ept-reg')
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)
206 Read data from endpoint
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')
214@master.command('transmit-async-packet')
216@click.option('--packet', '-p', callback=toolbox.split_ints)
219 Transmit already formed packet
221 lMaster = obj.mMaster
224 packet = [0x0, 0x0] + random.sample(range(256),random.randint(5, 20)) + [0x1aa]
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')
232@master.command('reset-command-counters')
236 Transmit already formed packet
238 lMaster = obj.mMaster
239 lMaster.reset_command_counters()
243@master.command('control-timestamp-broadcast')
244@click.option('--on/--off', default=True, help='enable/disable ts broadcast')
248 Enable or disable timestamp broadcast
250 lMaster = obj.mMaster
252 lMaster.enable_timestamp_broadcast()
254 lMaster.disable_timestamp_broadcast()
258@master.group('part', invoke_without_command=True)
262 Partition specific commands
264 secho(
"New partition concept not yet supported", fg=
'yellow')
269@partition.command('status', short_help='Display the status of the timing master.')
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')
275 Display the master status, accepted and rejected command counters
283@partition.command(
'configure', short_help=
'Prepares partition for data taking.')
290@master.command(
'configure-endpoint-cmd-decoder', short_help=
'Configure a slot of endpoint command decoder.')
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))
297 Configure endpoint command decoder
300 lMaster = obj.mMaster
301 lMaster.configure_endpoint_command_decoder(addr,slot,cmd)
sendcmd(obj, cmd, chan, n)
writeeptreg(obj, adr, reg, data, mode)
transmitasyncpacket(obj, packet)
resetcommandcounters(obj)
partstatus(obj, watch, period)
controltimestampbroadcast(obj, on)
readeptreg(obj, adr, reg, length, mode)
configureendpointcmddecoder(obj, addr, slot, cmd)
faketriggen(obj, cmd, chan, rate, poisson)