DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
fmc.py
Go to the documentation of this file.
1from __future__ import print_function
2
3import click
4import time
5import collections
6
7from .boards import BoardShell
8from .factory import ShellFactory
9
10from os.path import join, expandvars, basename
11from click import echo, style, secho
12from timing.common.definitions import kBoardSim, kBoardFMC
13from timing.common.definitions import kCarrierEnclustraA35, kCarrierKC705, kCarrierMicrozed
14from timing.core import I2CSlave, SI534xSlave
15
16
17# ------------------------------------------------------------------------------
19 """docstring for PC059Shell"""
20 kFMCRev1 = 1
21 kFMCRev2 = 2
22
23 kUIDRevisionMap = {
24 0xd880395e720b: kFMCRev1,
25 0xd880395e501a: kFMCRev1,
26 0xd880395e50b8: kFMCRev1,
27 0xd880395e501b: kFMCRev1,
28 0xd880395e7201: kFMCRev1,
29 0xd880395e4fcc: kFMCRev1,
30 0xd880395e5069: kFMCRev1,
31 0xd880395e7206: kFMCRev1,
32 0xd880395e1c86: kFMCRev2,
33 0xd880395e2630: kFMCRev2,
34 0xd880395e262b: kFMCRev2,
35 0xd880395e2b38: kFMCRev2,
36 0xd880395e1a6a: kFMCRev2,
37 0xd880395e36ae: kFMCRev2,
38 0xd880395e2b2e: kFMCRev2,
39 0xd880395e2b33: kFMCRev2,
40 0xd880395e1c81: kFMCRev2,
41 }
42
43 kClockConfigMap = {
44 kFMCRev1: "SI5344/PDTS0000.txt",
45 kFMCRev2: "SI5344/PDTS0003.txt",
46 }
47
48 i2cMasters=[
49 'uid_i2c',
50 'sfp_i2c',
51 'pll_i2c'
52 ]
53
54 # ------------------------------------------------------------------------------
55 def getAX3Slave(self):
56 lIO = self.device.getNode('io')
57 return lIO.getNode('uid_i2c').get_slave('AX3_Switch')
58 # ------------------------------------------------------------------------------
59
60 # ------------------------------------------------------------------------------
61 def getUIDSlave(self):
62 lIO = self.device.getNode('io')
63 return lIO.getNode('uid_i2c').get_slave('FMC_UID_PROM')
64 # ------------------------------------------------------------------------------
65
66 # ------------------------------------------------------------------------------
67 def getSIChipSlave(self):
68 lIO = self.device.getNode('io')
69 return lIO.getNode('pll_i2c')
70 # ------------------------------------------------------------------------------
71
72
73 # ------------------------------------------------------------------------------
74 def resetI2CnPll(self):
75 lIO = self.device.getNode('io')
76
77 time.sleep(0.1)
78
79 # PLL and I2C reset
80 lIO.getNode('csr.ctrl.pll_rst').write(0x1)
81 lIO.getClient().dispatch()
82
83 lIO.getNode('csr.ctrl.pll_rst').write(0x0)
84 lIO.getClient().dispatch()
85 # ------------------------------------------------------------------------------
86
87 # ------------------------------------------------------------------------------
88 def enableI2CSwitch(self):
89 if self.info.carrierType == kCarrierEnclustraA35:
90 super(FMCShell, self).enableI2CSwitch()
91 # ------------------------------------------------------------------------------
92
93 # ------------------------------------------------------------------------------
94 def reset(self, soft, forcepllcfg):
95 '''
96 Perform a hard reset on the timing master, including
97
98 \b
99 - ipbus registers
100 - i2c buses
101 - pll and pll configuration
102
103 \b
104 Fanout mode:
105 0 = local master
106 1 = sfp
107 '''
108
109 echo('Resetting ' + click.style(self.device.id(), fg='blue'))
110
111 lDevice = self.device
112 lBoardType = self.info.boardType
113 lCarrierType = self.info.carrierType
114 lDesignType = self.info.designType
115
116 lIO = lDevice.getNode('io')
117
118 # Global soft reset
119 self.soft_reset()
120
121 if not soft:
122 time.sleep(0.1)
123
124 # PLL and I2C reset
125 self.resetI2CnPll()
126
127 # Enable I2C routing
129
130 lUniqueID = self.readUID()
131 # echo("Timing Board PROM UID: "+style(hex(lUniqueID), fg="blue"))
132
133 # Ensure that the board is known to the revision DB
134 try:
135 lRevision = self.kUIDRevisionMap[lUniqueID]
136 except KeyError:
137 raise click.ClickException("No revision associated to UID "+hex(lUniqueID))
138
139 # Access the clock chip
140 lSIChip = self.getSIChipSlave()
141
142 # Ensure that the board revision has a registered clock config
143 if forcepllcfg is not None:
144 lFullClockConfigPath = forcepllcfg
145 echo("Using PLL Clock configuration file: "+style(basename(lFullClockConfigPath), fg='green') )
146
147 else:
148 try:
149 lClockConfigPath = self.kClockConfigMap[lRevision]
150 except KeyError:
151 raise ClickException("Board revision " << lRevision << " has no associated clock configuration")
152
153
154 echo("PLL Clock configuration file: "+style(lClockConfigPath, fg='green') )
155
156 # Configure the clock chip
157 lFullClockConfigPath = expandvars(join('${TIMING_SHARE}/config/etc/clock', lClockConfigPath))
158
159 lSIChip.configure(lFullClockConfigPath)
160 echo("SI354x configuration id: {}".format(style(lSIChip.read_config_id(), fg='green')))
161
162# ------------------------------------------------------------------------------
163
164ShellFactory.registerBoard(kBoardSim, FMCShell)
165ShellFactory.registerBoard(kBoardFMC, FMCShell)
reset(self, soft, forcepllcfg)
Definition fmc.py:94