Skip to content
Snippets Groups Projects
Commit 39f5498c authored by Daniele Dal Santo's avatar Daniele Dal Santo
Browse files

Merge branch 'dev-enh-fix' into 'master'

Fixed issue in dev-enhance merge

See merge request !56
parents e8d78018 88c47e3b
No related branches found
No related tags found
1 merge request!56Fixed issue in dev-enhance merge
......@@ -18,3 +18,4 @@ poetry.lock
dist
.python-version
Eye_Diagram*
lpgbt_calibration.csv
......@@ -64,19 +64,35 @@ or by providing a config like `30000000_test_lpgbtv1_vtrxv1_3.json`:
```
InitOpto -config_path configs/30000000_test_lpgbtv1_vtrxv1_3.json -configure 1 -i
```
Notice that if one uses the `config_path` argument, then `optoboard_serial`, `vtrx_v`, `flx_G` and `flx_d` **must be specified inside the configuration file** by adding a key-value pair of the type:
```python
"Optoboard":
{
"serial": "30000000",
"flx_G": 0,
"flx_d": 0,
"vtrx_v": "1.3"
},
```
Remove the `-i` flag if you don't want to start the Python interactive shell and just configure.
Consult our [optoboard_felix API](https://optoboard-system.docs.cern.ch/software/optoboard_felix/) in the Optoboard system docs for available methods and more information.
## Config files
The script has default configs according to the lpGBT and VTRx+ quad laser driver version, **please do not change them**. If the user wants to provide its own config please duplicate the default according to your lpGBT and VTRx+ quad laser driver version and change values there.
The script has default configs according to the lpGBT and VTRx+ quad laser driver version, **please do not change them**. If the user wants to provide its own config please **duplicate the default ones according to your lpGBT and VTRx+ quad laser driver version and change values there**. Note that the format of the provided file has to follow the one of `00000000_test_lpgbtv1_vtrxv1_2` and `30000000_test_lpgbtv1_vtrxv1_3`, which differs from the default. Also note that different chip versions have different register maps.
Two example configs `00000000_test_lpgbtv1_vtrxv1_2` and `30000000_test_lpgbtv1_vtrxv1_3` are provided for duplication. Note that you can't just change the VTRx+ version in one of them, due to different register maps the configs also have different keys.
## Create multiple optoboard instances
## Use as module for scripting
Multiple optoboard instances can be initialized at once by providing a json following the model of `optoConfigList_example.json` to `InitOpto`:
```
InitOpto -optoListPath optoConfigList_example.json -i
```
Minimal example with multiple Optoboards:
Another option is shown in the minimal example below:
```python
from collections import OrderedDict
......
......@@ -597,6 +597,59 @@ class Lpgbt(Hardware):
return dict_EPRX_locking
def check_EPTX_status(self):
"""Check lpGBTs elink downlink status for all channels.
Specifically: outputs frequency and polarity of the downlinks.
Downlink numbering convention is as follows:
dl 0 == (e-group,channel) 00
1 == 02
2 == 10
3 == 12
4 == 20
5 == 22
6 == 30
7 == 32
Returns:
Nested dictionary with the status of the 8 downlinks with keys:
["EPTX"+str(dl)]["polarity"] and ["EPTX"+str(dl)]["data_rate"]
polarity (string): 0=NON INVERTED, 1=INVERTED
data_rate (int): possible values in [0,3], 2 corresponds to 160Mb/s
"""
output_driver = ["01_00","03_02","11_10","13_12","21_20","23_22","31_30","33_32"]
group = [0,0,1,1,2,2,3,3]
channel = [0,2,0,2,0,2,0,2]
dict_EPTX_status = {}
for dl in range(0,8):
dict_EPTX_status["EPTX"+str(dl)] = {}
polarity = self.read("EPTX"+str(output_driver[dl])+"CHNCNTR","EPTX"+str(group[dl])+str(channel[dl])+"INVERT")
if polarity:
polarity_str = "INVERTED"
else:
polarity_str = "NOT INVERTED"
dict_EPTX_status["EPTX"+str(dl)]["polarity"] = polarity_str
logger.info("Status of EPTX %s:", str(dl))
logger.info("The polarity is %s",polarity_str)
data_rate = self.read("EPTXDATARATE","EPTX"+str(group[dl])+"DATARATE")
dict_EPTX_status["EPTX"+str(dl)]["data_rate"] = data_rate
logger.info("The data rate is %s",str(data_rate))
logger.info("\n")
return dict_EPTX_status
def check_EPRX_DLL_locking(self):
"""Check lpGBTs elink uplink DLL locking for all channels.
......@@ -774,7 +827,7 @@ class Lpgbt(Hardware):
return read
def set_DL_elinks(self, group, data_source):
"""Check lpGBTs elink uplink status for all channels.
"""Set EPTX data source.
The output of any EPTX group can be set to a known pattern i.e. PRBS7. The pattern can be analysed on the module side.
......@@ -1085,7 +1138,84 @@ class Lpgbt(Hardware):
self.write_read("PROCESSANDSEUMONITOR", "SEUENABLE", 0)
return seuCounter
def swap_rx_polarity(self,group):
"""Swapping the polarity of RX (uplink) for all channels.
This always concerns channel 0 of each e-group.
If inverted, change it to not inverted, and visa versa.
Args:
group (int) can be from 0 to 3
"""
group_str = str(group)
logger.info("Swapping uplink polarity of e-group %s", group_str)
polarity = self.read("EPRX"+group_str+"0CHNCNTR","EPRX"+group_str+"0INVERT")
if polarity:
self.write_read("EPRX"+group_str+"0CHNCNTR","EPRX"+group_str+"0INVERT",0)
logger.info("Polarity swapped from INVERTED to NOT INVERTED")
else:
self.write_read("EPRX"+group_str+"0CHNCNTR","EPRX"+group_str+"0INVERT",1)
logger.info("Polarity swapped from NOT INVERTED to INVERTED")
def swap_tx_polarity(self,dl):
"""Swapping the polarity of RX (uplink) for all channels.
If inverted, change it to not inverted, and visa versa.
The polarity corresponds to a specific combination of e-group and channel
number. The convention is as follows:
dl == (e-group,channel)
0 == 00
1 == 02
2 == 10
3 == 12
4 == 20
5 == 22
6 == 30
7 == 32
Args:
dl (int) can be from 0 to 7
"""
output_driver = ["01_00","03_02","11_10","13_12","21_20","23_22","31_30","33_32"]
channels = ["00","02","10","12","20","22","30","32"]
logger.info("Swapping polarity of downlink %s",str(channels[dl]))
polarity = self.read("EPTX"+str(output_driver[dl])+"CHNCNTR","EPTX"+str(channels[dl])+"INVERT")
if polarity:
self.write_read("EPTX"+str(output_driver[dl])+"CHNCNTR","EPTX"+str(channels[dl])+"INVERT",0)
logger.info("Polarity swapped from INVERTED to NOT INVERTED")
else:
self.write_read("EPTX"+str(output_driver[dl])+"CHNCNTR","EPTX"+str(channels[dl])+"INVERT",1)
logger.info("Polarity swapped from INVERTED to NOT INVERTED")
def read_id(self):
"""Read the Id of lpgbt and check if they are the same
Returns:
The Id or False if there is a mistake
"""
id1 = self.fuses_read_bank(0)
id2 = self.fuses_read_bank(8)
id2=(id2>>6)|(id2 << (32 - 6)) & 0xFFFFFFFF
id3 = self.fuses_read_bank(12)
id3=(id3>>12)|(id3 << (32 - 12)) & 0xFFFFFFFF
id4 = self.fuses_read_bank(16)
id4=(id4>>18)|(id4 << (32 - 18)) & 0xFFFFFFFF
id5 = self.fuses_read_bank(20)
id5=(id5>>24)|(id5 << (32 - 24)) & 0xFFFFFFFF
if id1==id2 and id1 == id3 and id1==id4 and id1==id5:
print("The ID of the lpgbt is %i" %id1)
return id1
else:
raise Exception("The ID identification wasn't successful")
def tx_rx_scan(self, optical_channel, url=os.environ.get("FELIX_BACKEND_URL") if os.environ.get("FELIX_BACKEND_URL") is not None else "http://localhost:8001"):
"""Iteratively turn off the lpGBT downlink to identify to which of them each FE is connected
......
......@@ -222,8 +222,7 @@ class Optoboard:
def opto_doc(self):
"""Check the status of the different devices on the Optoboard.
Checks lpGBT info, PUSM status, lpGBT configuration pins, EPRX setting and locking status.
Checks lpGBT info, PUSM status, lpGBT configuration pins, EPRX and EPTX settings, and locking status.
Returns:
opto_doc_dic (dict): status dictionary with devices as keys
"""
......@@ -237,7 +236,8 @@ class Optoboard:
**obj.check_PUSM_status(),
**obj.check_lpgbt_config_pins(),
**obj.check_EPRX_status(),
**obj.check_EPRX_locking()
**obj.check_EPRX_locking(),
**obj.check_EPTX_status()
}
......
......@@ -116,3 +116,19 @@ class Vtrx(Hardware):
logger.debug("vtrx.readAll - registers: %s, read: %s", registers, read)
return read
def read_uniqueId(self):
"""Read out the VTRx+ unique 32-bit chip ID that is set during production testing.
Returns:
id (int): VTRx+ unique 32-bit chip ID
"""
register3 = self.read("UID3", None)
register2 = self.read("UID2", None)
register1 = self.read("UID1", None)
register0 = self.read("UID0", None)
id = register3 << 24 | register2 << 16 | register1 << 8 | register0
logger.info("VTRx unique chip ID: %s",id)
return id
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment