DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
hsi.py
Go to the documentation of this file.
1import click
2import sys
3import time
4import array
5import collections
6import h5py
7from datetime import datetime
8
9from . import toolbox
10import timing.common.definitions as defs
11from timing.common.definitions import kLibrarySupportedBoards, kLibrarySupportedDesigns, kHSIWordsNumber
12
13from click import echo, style, secho
14import time
15
16# ------------------------------------------------------------------------------
17# ____ __ _ __
18# / __/__ ___/ /__ ___ (_)__ / /_
19# / _// _ \/ _ / _ \/ _ \/ / _ \/ __/
20# /___/_//_/\_,_/ .__/\___/_/_//_/\__/
21# /_/
22@click.group('hsi', invoke_without_command=True)
23@click.pass_obj
24@click.argument('device', callback=toolbox.validate_device, shell_complete=toolbox.completeDevices)
25def hsi(obj, device):
26 '''
27 HSI commands.
28
29 \b
30 DEVICE: uhal device identifier
31 IDS: id(s) of the target endpoint(s).
32 '''
33
34 lDevice = obj.mConnectionManager.getDevice(str(device))
35 if obj.mTimeout:
36 lDevice.setTimeoutPeriod(obj.mTimeout)
37
38
39 echo('Created HSI device')
40 lTopDesign = lDevice.getNode('')
41 lBoardInfo = toolbox.readSubNodes(lDevice.getNode('io.config'), False)
42 lDevice.dispatch()
43
44 if lBoardInfo['board_type'].value() in kLibrarySupportedBoards and lBoardInfo['design_type'].value() in kLibrarySupportedDesigns:
45 lTopDesign.validate_firmware_version()
46 try:
47 echo(lDevice.getNode('io').get_hardware_info())
48 except:
49 secho("Failed to retrieve hardware information! I2C issue? Initial board reset needed?", fg='yellow')
50 e = sys.exc_info()[0]
51 secho("Error: {}".format(e), fg='red')
52
53 obj.mDevice = lDevice
54 obj.mEndpoint = lDevice.getNode('endpoint0')
55 obj.mTopDesign = lDevice.getNode('')
56 obj.mHSI = obj.mTopDesign.get_hsi_node()
57# ------------------------------------------------------------------------------
58
59
60# ------------------------------------------------------------------------------
61@hsi.command('status')
62@click.pass_obj
63@click.pass_context
64def status(ctx, obj):
65 '''
66 Print the status of CRT endpoint wrapper block.
67 '''
68
69 lDevice = obj.mDevice
70 lHSI = obj.mHSI
71 lEndpoint = obj.mEndpoint
72
73 echo(lEndpoint.get_status())
74 echo(lHSI.get_status())
75# ------------------------------------------------------------------------------
76
77# ------------------------------------------------------------------------------
78@hsi.command('enable', short_help="Configure the HSI endpoint for running")
79@click.pass_obj
80@click.pass_context
81@click.argument('action', default='on', type=click.Choice(['on', 'off', 'reset']))
82@click.option('--partition', '-p', type=click.IntRange(0,4), help='Partition', default=0)
83@click.option('--address', '-a', type=toolbox.IntRange(0x0,0x100), help='Address', default=0)
84def enable(ctx, obj, action, partition, address):
85 '''
86 Activate the timing endpoint in the hsi design. Left in for compatibility reasons
87 '''
88
89 lDevice = obj.mDevice
90 lEndpoint = obj.mEndpoint
91 lHSI = obj.mHSI
92
93 if action == 'off':
94 lEndpoint.disable()
95 elif action == 'on':
96 lEndpoint.enable(address=address,partition=partition)
97 elif action == 'reset':
98 lEndpoint.reset(address=address,partition=partition)
99 lHSI.reset_hsi()
100
101 time.sleep(0.1)
102 ctx.invoke(status)
103# ------------------------------------------------------------------------------
104
105# ------------------------------------------------------------------------------
106@hsi.command('configure', short_help="Configure the HSI block for running")
107@click.pass_obj
108@click.pass_context
109@click.option('--src', '-s', type=click.IntRange(0x0,0x1), help='Source of HSI data,; 0: hardware; 1: timestamp (emulation mode)', default=0)
110@click.option('--re-mask', '-r', type=click.IntRange(0,0xffffffff), help='Rising edge mask', default=0)
111@click.option('--fe-mask', '-f', type=click.IntRange(0,0xffffffff), help='Falling edge mask', default=0)
112@click.option('--inv-mask', '-i', type=click.IntRange(0,0xffffffff), help='Invert mask', default=0)
113@click.option('--rate', type=float, help='Random trigger rate [Hz] on bit 0 in emulation mode', default=1)
114def configure(ctx, obj, src, re_mask, fe_mask, inv_mask, rate):
115 '''
116 Configure the hsi in the hsi wrapper block.
117 '''
118
119 lDevice = obj.mDevice
120 lHSI = obj.mHSI
121 lTopDesign = obj.mTopDesign
122
123 lHSI.reset_hsi()
124 lTopDesign.configure_hsi(src, re_mask, fe_mask, inv_mask, rate)
125
126 secho("HSI configured", fg='green')
127
128 time.sleep(0.1)
129 ctx.invoke(status)
130# ------------------------------------------------------------------------------
131
132
133# ------------------------------------------------------------------------------
134@hsi.command('start', short_help='Start the hsi triggering and the writing events into buffer.')
135@click.pass_obj
136@click.pass_context
137def readback(ctx, obj):
138 '''
139 Read the content of the endpoint master readout buffer.
140 '''
141 lDevice = obj.mDevice
142 lHSI = obj.mHSI
143
144 lHSI.start_hsi()
145 secho("HSI start", fg='green')
146
147 time.sleep(0.1)
148 ctx.invoke(status)
149# ------------------------------------------------------------------------------
150
151# ------------------------------------------------------------------------------
152@hsi.command('stop', short_help='Stop the hsi triggering and the writing events into buffer.')
153@click.pass_obj
154@click.pass_context
155def readback(ctx, obj):
156 '''
157 Read the content of the endpoint master readout buffer.
158 '''
159 lDevice = obj.mDevice
160 lHSI = obj.mHSI
161
162 lHSI.stop_hsi()
163 secho("HSI stop", fg='green')
164
165 time.sleep(0.1)
166 ctx.invoke(status)
167# ------------------------------------------------------------------------------
168
169# ------------------------------------------------------------------------------
170@hsi.command('read', short_help='Read the content of the hsi readout buffer.')
171@click.pass_obj
172@click.pass_context
173@click.option('--all/--events', '-a/ ', 'readall', default=False, help="Buffer readout mode.\n- events: only completed events are readout.\n- all: the content of the buffer is fully read-out.")
174@click.option('--continuous', '-c', 'continuous', is_flag=True, default=False, help="Read data continuously")
175@click.option('--print', '-p', 'print_out', is_flag=True, default=False, help="Print event data")
176@click.option('--read-period', '-r', type=int, help='Period of readout [ms]', default=100)
177@click.option('--save', '-s', is_flag=True, default=False, help='Flag controlling data saving to file')
178@click.option('--file-name', '-f', type=click.Path(), help='Name of file to store data in')
179def read(ctx, obj, readall, continuous, print_out, read_period, save, file_name):
180 '''
181 Read the content of the endpoint master readout buffer.
182 '''
183 lDevice = obj.mDevice
184 lHSI = obj.mHSI
185
186 read_events=0
187 if continuous:
188 secho("[INFO] Starting HSI data readout", fg='green')
189 if not (save or print_out):
190 secho('[WARNING] you have chosen to neither save or print the HSI data', fg='yellow')
191 last_ts=0
192 if save:
193 h5_file_name = datetime.now().strftime("hsi_data_%d_%m_%Y_%H_%M_%S.hdf5")
194 if file_name is not None:
195 h5_file_name=file_name
196
197 f = h5py.File(h5_file_name, "w")
198 hsi_dataset = f.create_dataset("hsi_frames", (0,7), maxshape=(None, 7), chunks=True, dtype='u4')
199 else:
200 if file_name is not None:
201 secho('[WARNING] You have provided a file name but chosen not to save the readout data', fg='yellow')
202
203 with toolbox.InterruptHandler() as h:
204 while(True):
205 n_words=0
206 hsi_words = lHSI.read_data_buffer(n_words,False,False)
207 n_hsi_events = len(hsi_words) // kHSIWordsNumber
208
209 if save:
210 hsi_dataset_start_index=hsi_dataset.shape[0]
211 hsi_dataset.resize(hsi_dataset_start_index+n_hsi_events, axis=0)
212
213 if (len(hsi_words) % kHSIWordsNumber == 0 and hsi_words.size() > 0):
214
215 for i in range(0,n_hsi_events):
216 start_index = i * kHSIWordsNumber
217 end_index = start_index + kHSIWordsNumber
218 raw_event=hsi_words[start_index:end_index]
219
220 header = raw_event[0]
221 ts_low = raw_event[1]
222 ts_high = raw_event[2]
223 data = raw_event[3]
224 trigger = raw_event[4]
225
226 ts = ts_low | (ts_high << 32)
227
228 # bits 15-0 contain the sequence counter
229 counter = header & 0x0000ffff
230
231 if (header >> 16) != 0xaa00:
232 secho("[ERROR] Invalid HSIEventHeader", fg='red')
233 continue
234
235 if ts == 0:
236 secho("[ERROR] Invalid HSIEvent timestamp", fg='red')
237 continue
238
239 delta_ticks=ts-last_ts
240 if last_ts == 0:
241 delta_ticks=0
242 last_ts=ts
243
244 if print_out:
245 print(f"[INFO] got event: {counter} ts: {ts} signals: {data} delta ts: {delta_ticks}")
246
247 read_events=read_events+1
248 if save:
249 hsi_dataset[hsi_dataset_start_index+i,0]=(0x1 << 6) | 0x1 # DAQHeader, frame version: 1, det id: 1
250 hsi_dataset[hsi_dataset_start_index+i,1]=ts_low
251 hsi_dataset[hsi_dataset_start_index+i,2]=ts_high
252 hsi_dataset[hsi_dataset_start_index+i,3]=data
253 hsi_dataset[hsi_dataset_start_index+i,4]=0x0
254 hsi_dataset[hsi_dataset_start_index+i,5]=trigger
255 hsi_dataset[hsi_dataset_start_index+i,6]=counter
256
257 elif len(hsi_words) != 0:
258 secho(f"[ERROR] unexpected n words {len(hsi_words)}", fg='red')
259 if h.interrupted:
260 secho(f"[INFO] Stopping HSI data readout after {read_events} events", fg='green')
261 break
262 time.sleep(read_period*1e-3)
263 if save:
264 f.close()
265 else:
266 echo(lHSI.get_data_buffer_table(readall,False))
267# ------------------------------------------------------------------------------
status(ctx, obj)
Definition hsi.py:64
configure(ctx, obj, src, re_mask, fe_mask, inv_mask, rate)
Definition hsi.py:114
readback(ctx, obj)
Definition hsi.py:137
read(ctx, obj, readall, continuous, print_out, read_period, save, file_name)
Definition hsi.py:179