DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
timing
python
timing
shells
master.py
Go to the documentation of this file.
1
from
__future__
import
print_function
2
3
import
click
4
import
time
5
import
collections
6
7
import
timing.cli.toolbox
as
toolbox
8
import
timing.common.definitions
as
defs
9
10
from
.factory
import
ShellFactory, ShellContext
11
from
click
import
echo, style, secho
12
from
timing.core
import
SI534xSlave, I2CExpanderSlave, DACSlave
13
14
from
timing.common.definitions
import
kBoardSim, kBoardFMC, kBoardPC059, kBoardMicrozed, kBoardTLU
15
from
timing.common.definitions
import
kCarrierEnclustraA35, kCarrierKC705, kCarrierMicrozed
16
from
timing.common.definitions
import
kDesignOverlord, kDesignMaster, kDesignOuroboros, kDesignOuroborosSim, kDesignEndpoint, kDesignFanout
17
from
timing.common.definitions
import
kBoardNameMap, kCarrierNameMap, kDesignNameMap
18
19
from
os.path
import
join, expandvars, basename
20
21
# ------------------------------------------------------------------------------
22
class
MasterShell
(object):
23
24
kFWMajorRequired = 5
25
26
def
__init__
(self):
27
28
lMstCtx =
ShellContext
()
29
30
# Tol-level nodes
31
lMaster = self.device.getNode(
'master'
)
32
lExtTrigNode = self.device.getNode(
'trig_rx'
)
33
lIO = self.device.getNode(
'io'
)
34
35
lVersion = lMaster.getNode(
'global.version'
).read()
36
lGenerics = toolbox.readSubNodes(lMaster.getNode(
'global.config'
),
False
)
37
self.device.dispatch()
38
39
lMajor = (lVersion >> 16) & 0xff
40
lMinor = (lVersion >> 8) & 0xff
41
lPatch = (lVersion >> 0) & 0xff
42
43
lMstCtx.version = (lVersion.value(), lMajor, lMinor, lPatch)
44
lMstCtx.generics = {k:v.value()
for
k,v
in
lGenerics.items()}
45
46
if
lMajor < self.
kFWMajorRequired
:
47
secho(
'ERROR: Incompatible master firmware version. Found {}, required {}'
.format(hex(lMajor), hex(kMasterFWMajorRequired)), fg=
'red'
)
48
raise
click.Abort()
49
50
# store references in context
51
lMstCtx.masterNode = lMaster
52
lMstCtx.globalNode = lMaster.getNode(
'global'
)
53
lMstCtx.aCmdNode = lMaster.getNode(
'acmd'
)
54
lMstCtx.echoNode = lMaster.getNode(
'echo'
)
55
lMstCtx.extTrigNode = lExtTrigNode
56
57
self.
masterCtx
= lMstCtx
58
self.
ioNode
= lIO
59
# ------------------------------------------------------------------------------
60
61
62
# ------------------------------------------------------------------------------
63
def
identify
(self):
64
echo(
"design '{}' on board '{}' on carrier '{}'"
.format(
65
style(kDesignNameMap[self.info.designType], fg=
'blue'
),
66
style(kBoardNameMap[self.info.boardType], fg=
'blue'
),
67
style(kCarrierNameMap[self.info.carrierType], fg=
'blue'
)
68
))
69
echo(
"Master FW rev: {}, partitions: {}, channels: {}"
.format(
70
style(hex(self.
masterCtx
.version[0]), fg=
'cyan'
),
71
style(str(self.
masterCtx
.generics[
'n_part'
]), fg=
'cyan'
),
72
style(str(self.
masterCtx
.generics[
'n_chan'
]), fg=
'cyan'
),
73
))
74
# ------------------------------------------------------------------------------
75
76
77
# ------------------------------------------------------------------------------
78
def
initPartitions
(self):
79
80
for
pid
in
range(self.
masterCtx
.generics[
'n_part'
]):
81
82
lPartNode = self.
masterCtx
.masterNode.getNode(
'partition{}'
.format(pid))
83
84
lPartNode.reset();
85
lPartNode.configure(0x0,
False
);
86
lPartNode.enable();
87
# ------------------------------------------------------------------------------
88
89
# ------------------------------------------------------------------------------
90
def
synctime
(self):
91
92
lMaster = self.
masterCtx
.masterNode
93
lIO = self.
ioNode
94
95
firmmware_frequency_hz = lIO.read_firmware_frequency()
96
97
lTStampReadNode = lMaster.getNode(
'tstamp.ctr.val'
)
98
lTStampWriteNode = lMaster.getNode(
'tstamp.ctr.set'
)
99
100
lTimeStamp = lTStampReadNode.readBlock(2)
101
lTStampReadNode.getClient().dispatch()
102
103
lTime = int(lTimeStamp[0]) + (int(lTimeStamp[1]) << 32)
104
secho(
'Old Timestamp {}'
.format(hex(lTime)), fg=
'cyan'
)
105
106
# Take the local time and split it up
107
lNow = int(time.time()*firmmware_frequency_hz)
108
lNowH = (lNow >> 32) & ((1<<32)-1)
109
lNowL = (lNow >> 0) & ((1<<32)-1)
110
111
# push it on the board
112
lTStampWriteNode.writeBlock([lNowL, lNowH])
113
lTStampWriteNode.getClient().dispatch()
114
115
# Read it back
116
lTimeStamp = lTStampReadNode.readBlock(2)
117
lTStampReadNode.getClient().dispatch()
118
x = time.time()
119
lTime = (int(lTimeStamp[1]) << 32) + int(lTimeStamp[0])
120
121
secho(
'New Timestamp {}'
.format(hex(lTime)), fg=
'cyan'
)
122
123
print(float(lTime)/firmmware_frequency_hz - x)
124
125
echo (
"DeltaT {}"
.format(toolbox.formatTStamp(lTimeStamp)))
126
# ------------------------------------------------------------------------------
127
128
129
130
# ------------------------------------------------------------------------------
131
def
enableEptAndWaitForReady
( self, aTimeout=0.5 ):
132
133
lGlobal = self.
masterCtx
.globalNode
134
135
lGlobal.getNode(
'csr.ctrl.ep_en'
).write(0x0)
136
lGlobal.getClient().dispatch()
137
lGlobal.getNode(
'csr.ctrl.ep_en'
).write(0x1)
138
lGlobal.getClient().dispatch()
139
140
# Wait for the endpoint to be happy
141
lTOutStart = time.time()
142
# secho ('Return EPT reset, waiting for lock', fg='cyan')
143
while
time.time() < lTOutStart + aTimeout:
144
time.sleep(0.1)
145
146
lEptRdy = lGlobal.getNode(
'csr.stat.ep_rdy'
).read()
147
lEptStat = lGlobal.getNode(
'csr.stat.ep_stat'
).read()
148
lEptFDel = lGlobal.getNode(
'csr.stat.ep_fdel'
).read()
149
lEptEdge = lGlobal.getNode(
'csr.stat.ep_edge'
).read()
150
lGlobal.getClient().dispatch()
151
152
if
int(lEptRdy) == 1:
153
# secho('Endpoint locked: state={}'.format(hex(lEptStat)), fg='blue')
154
break
155
if
int(lEptRdy) == 0:
156
raise
RuntimeError(
'Failed to bring up the RTT endpoint. Current state {}'
.format(hex(lEptStat)))
157
# else:
158
# secho ('Endpoint locked', fg='cyan')
159
return
(lEptFDel.value(), lEptEdge.value())
160
# ------------------------------------------------------------------------------
161
162
163
# ------------------------------------------------------------------------------
164
def
send_echo_and_measure_delay
( self, aTimeout=0.5 ):
165
166
lEcho = self.
masterCtx
.echoNode
167
168
lEcho.getNode(
'csr.ctrl.go'
).write(0x1)
169
lEcho.getClient().dispatch()
170
lTOutStart = time.time()
171
while
time.time() < lTOutStart + aTimeout:
172
time.sleep(0.1)
173
174
lDone = lEcho.getNode(
'csr.stat.rx_done'
).read()
175
lEcho.getClient().dispatch()
176
177
if
int(lDone) == 1:
178
break
179
if
not
int(lDone):
180
raise
RuntimeError(
"Timeout while waiting for echo"
)
181
182
lTimeRxL = lEcho.getNode(
'csr.rx_l'
).read()
183
lTimeRxH = lEcho.getNode(
'csr.rx_h'
).read()
184
lTimeTxL = lEcho.getNode(
'csr.tx_l'
).read()
185
lTimeTxH = lEcho.getNode(
'csr.tx_h'
).read()
186
lEcho.getClient().dispatch()
187
188
lTimeRx = (lTimeRxH << 32) + lTimeRxL
189
lTimeTx = (lTimeTxH << 32) + lTimeTxL
190
191
return
lTimeTx, lTimeRx
192
# ------------------------------------------------------------------------------
193
194
195
# ------------------------------------------------------------------------------
196
def
pushDelay
( self, aAddr, aCDel):
197
198
lACmd = self.
masterCtx
.aCmdNode
199
200
# Keep the TX sfp on
201
toolbox.resetSubNodes(lACmd.getNode(
'csr.ctrl'
), dispatch=
False
)
202
lACmd.getNode(
'csr.ctrl.tx_en'
).write(0x1)
203
lACmd.getNode(
'csr.ctrl.addr'
).write(aAddr)
204
lACmd.getNode(
'csr.ctrl.cdel'
).write(aCDel)
205
lACmd.getNode(
'csr.ctrl.update'
).write(0x1)
206
lACmd.getNode(
'csr.ctrl.go'
).write(0x1)
207
lACmd.getNode(
'csr.ctrl.go'
).write(0x0)
208
lACmd.getClient().dispatch()
209
secho(
'Coarse delay {} applied'
.format(aCDel), fg=
'green'
)
210
# ------------------------------------------------------------------------------
211
212
213
# ------------------------------------------------------------------------------
214
def
enableEndpointSFP
(self, aAddr, aEnable=1):
215
216
lACmd = self.
masterCtx
.aCmdNode
217
218
toolbox.resetSubNodes(lACmd.getNode(
'csr.ctrl'
))
219
lACmd.getNode(
'csr.ctrl.addr'
).write(aAddr)
220
lACmd.getNode(
'csr.ctrl.tx_en'
).write(aEnable)
221
lACmd.getNode(
'csr.ctrl.go'
).write(0x1)
222
lACmd.getNode(
'csr.ctrl.go'
).write(0x0)
223
lACmd.getClient().dispatch()
224
# ------------------------------------------------------------------------------
225
226
227
# ------------------------------------------------------------------------------
228
229
ShellFactory.registerBoard(kDesignOverlord, MasterShell)
230
231
# ------------------------------------------------------------------------------
232
timing.shells.factory.ShellContext
Definition
factory.py:7
timing.shells.master.MasterShell
Definition
master.py:22
timing.shells.master.MasterShell.enableEptAndWaitForReady
enableEptAndWaitForReady(self, aTimeout=0.5)
Definition
master.py:131
timing.shells.master.MasterShell.enableEndpointSFP
enableEndpointSFP(self, aAddr, aEnable=1)
Definition
master.py:214
timing.shells.master.MasterShell.send_echo_and_measure_delay
send_echo_and_measure_delay(self, aTimeout=0.5)
Definition
master.py:164
timing.shells.master.MasterShell.kFWMajorRequired
int kFWMajorRequired
Definition
master.py:24
timing.shells.master.MasterShell.pushDelay
pushDelay(self, aAddr, aCDel)
Definition
master.py:196
timing.shells.master.MasterShell.ioNode
ioNode
Definition
master.py:58
timing.shells.master.MasterShell.__init__
__init__(self)
Definition
master.py:26
timing.shells.master.MasterShell.identify
identify(self)
Definition
master.py:63
timing.shells.master.MasterShell.initPartitions
initPartitions(self)
Definition
master.py:78
timing.shells.master.MasterShell.synctime
synctime(self)
Definition
master.py:90
timing.shells.master.MasterShell.masterCtx
masterCtx
Definition
master.py:57
timing.cli.toolbox
Definition
toolbox.py:1
timing.common.definitions
Definition
__init__.py:1
timing.core
Definition
__init__.py:1
Generated on
for DUNE-DAQ by
1.17.0