Merge branch 'developer' into dev/ctb_clocks
Build on RHEL8 docker image / build (push) Failing after 0s
Build on RHEL9 docker image / build (push) Failing after 0s
Run Simulator Tests on local RHEL9 / build (push) Successful in 14m42s
Run Simulator Tests on local RHEL8 / build (push) Successful in 17m12s

This commit is contained in:
2026-04-22 16:36:13 +02:00
72 changed files with 43083 additions and 36506 deletions
+6 -2
View File
@@ -6,6 +6,10 @@ on:
branches:
- developer
- main
push:
branches:
- developer
- main
release:
types:
- published
@@ -87,7 +91,7 @@ jobs:
- name: Copy documentation and Release notes to versioned folder
if: github.event_name == 'release' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)
if: github.event_name == 'release' || (github.event_name == 'push')
run: |
VERSION="${{ steps.version.outputs.version }}"
mkdir -p "gh-pages/${VERSION}"
@@ -99,7 +103,7 @@ jobs:
fi
- name: Commit and Push changes to gh-pages
if: github.event_name == 'release' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)
if: github.event_name == 'release' || (github.event_name == 'push')
run: |
cd gh-pages
git config --global user.name 'github-actions'
+86 -90
View File
@@ -4,7 +4,7 @@ from pathlib import Path
from PyQt5 import QtWidgets, uic
from pyctbgui.utils.defines import Defines
from slsdet import dacIndex, detectorType
from slsdet import powerIndex, detectorType
class PowerSuppliesTab(QtWidgets.QWidget):
@@ -16,120 +16,116 @@ class PowerSuppliesTab(QtWidgets.QWidget):
def refresh(self):
self.updateVoltageNames()
if self.det.type == detectorType.CHIPTESTBOARD:
self.getVChip()
for i in Defines.powerSupplies:
self.getVoltage(i)
if self.det.type == detectorType.CHIPTESTBOARD:
self.getCurrent(i)
self.update(i)
def update(self, i):
self.getPowerEnable(i)
self.getVoltage(i)
if self.det.type == detectorType.CHIPTESTBOARD:
self.getMeasuredVoltage(i)
self.getMeasuredCurrent(i)
def connect_ui(self):
for i in Defines.powerSupplies:
spinBox = getattr(self.view, f"spinBoxV{i}")
checkBox = getattr(self.view, f"checkBoxV{i}")
spinBox.editingFinished.connect(partial(self.setVoltage, i))
checkBox.stateChanged.connect(partial(self.setVoltage, i))
checkBox.stateChanged.connect(partial(self.setPowerEnable, i))
self.view.pushButtonPowerOff.clicked.connect(self.powerOff)
def setup_ui(self):
for i in Defines.powerSupplies:
dac = getattr(dacIndex, f"V_POWER_{i}")
spinBox = getattr(self.view, f"spinBoxV{i}")
checkBox = getattr(self.view, f"checkBoxV{i}")
retval = self.det.getPower(dac)[0]
spinBox.setValue(retval)
if retval == 0:
checkBox.setChecked(False)
spinBox.setDisabled(True)
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
label = getattr(self.view, f"labelI{i}")
label.setDisabled(True)
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
self.view.spinBoxVChip.setDisabled(True)
self.view.labelVChip.setDisabled(True)
for i in Defines.powerSupplies:
labelV = getattr(self.view, f"labelV{i}")
labelV.setDisabled(True)
labelI = getattr(self.view, f"labelI{i}")
labelI.setDisabled(True)
def updateVoltageNames(self):
retval = self.det.getPowerNames()
getattr(self.view, "checkBoxVA").setText(retval[0])
getattr(self.view, "checkBoxVB").setText(retval[1])
getattr(self.view, "checkBoxVC").setText(retval[2])
getattr(self.view, "checkBoxVD").setText(retval[3])
getattr(self.view, "checkBoxVIO").setText(retval[4])
for i in Defines.powerSupplies:
checkBox = getattr(self.view, f"checkBoxV{i}")
dac = getattr(powerIndex, f"V_POWER_{i}")
retval = self.det.getPowerName(dac)
checkBox.setText(retval)
def getVoltage(self, i):
spinBox = getattr(self.view, f"spinBoxV{i}")
checkBox = getattr(self.view, f"checkBoxV{i}")
voltageIndex = getattr(dacIndex, f"V_POWER_{i}")
def getMeasuredVoltage(self, i):
label = getattr(self.view, f"labelV{i}")
spinBox.editingFinished.disconnect()
checkBox.stateChanged.disconnect()
if self.det.type == detectorType.XILINX_CHIPTESTBOARD:
retval = self.det.getPower(voltageIndex)[0]
else:
retval = self.det.getMeasuredPower(voltageIndex)[0]
# spinBox.setValue(retval)
if retval > 1:
checkBox.setChecked(True)
if checkBox.isChecked():
spinBox.setEnabled(True)
else:
spinBox.setDisabled(True)
voltageIndex = getattr(powerIndex, f"V_POWER_{i}")
retval = self.det.getMeasuredPower(voltageIndex)
label.setText(f'{str(retval)} mV')
spinBox.editingFinished.connect(partial(self.setVoltage, i))
checkBox.stateChanged.connect(partial(self.setVoltage, i))
if self.det.type == detectorType.CHIPTESTBOARD:
self.getVChip()
# TODO: handle multiple events when pressing enter (twice)
def setVoltage(self, i):
checkBox = getattr(self.view, f"checkBoxV{i}")
spinBox = getattr(self.view, f"spinBoxV{i}")
voltageIndex = getattr(dacIndex, f"V_POWER_{i}")
spinBox.editingFinished.disconnect()
value = 0
if checkBox.isChecked():
value = spinBox.value()
try:
self.det.setPower(voltageIndex, value)
except Exception as e:
QtWidgets.QMessageBox.warning(self.mainWindow, "Voltage Fail", str(e), QtWidgets.QMessageBox.Ok)
pass
# TODO: (properly) disconnecting and connecting to handle multiple events (out of focus and pressing enter).
spinBox.editingFinished.connect(partial(self.setVoltage, i))
self.getVoltage(i)
if self.det.type == detectorType.CHIPTESTBOARD:
self.getCurrent(i)
def getCurrent(self, i):
def getMeasuredCurrent(self, i):
label = getattr(self.view, f"labelI{i}")
currentIndex = getattr(dacIndex, f"I_POWER_{i}")
retval = self.det.getMeasuredCurrent(currentIndex)[0]
currentIndex = getattr(powerIndex, f"I_POWER_{i}")
retval = self.det.getMeasuredCurrent(currentIndex)
label.setText(f'{str(retval)} mA')
def getVChip(self):
self.view.spinBoxVChip.setValue(self.det.getPower(dacIndex.V_POWER_CHIP)[0])
self.view.labelVChip.setText(f"{str(self.det.getPowerDAC(powerIndex.V_POWER_CHIP))} mV")
def getVoltage(self, i):
spinBox = getattr(self.view, f"spinBoxV{i}")
spinBox.editingFinished.disconnect()
voltageIndex = getattr(powerIndex, f"V_POWER_{i}")
spinBox.setValue(self.det.getPowerDAC(voltageIndex))
spinBox.editingFinished.connect(partial(self.setVoltage, i))
def setVoltage(self, i):
spinBox = getattr(self.view, f"spinBoxV{i}")
spinBox.editingFinished.disconnect()
voltageIndex = getattr(powerIndex, f"V_POWER_{i}")
try:
self.det.setPowerDAC(voltageIndex, spinBox.value())
except Exception as e:
QtWidgets.QMessageBox.warning(self.mainWindow, "Voltage Fail", str(e), QtWidgets.QMessageBox.Ok)
pass
spinBox.editingFinished.connect(partial(self.setVoltage, i))
self.update(i)
if self.det.type == detectorType.CHIPTESTBOARD:
self.getVChip()
def getPowerEnable(self, i):
checkBox = getattr(self.view, f"checkBoxV{i}")
checkBox.stateChanged.disconnect()
voltageIndex = getattr(powerIndex, f"V_POWER_{i}")
retval = self.det.isPowerEnabled(voltageIndex)
checkBox.setChecked(retval)
checkBox.stateChanged.connect(partial(self.setPowerEnable, i))
def setPowerEnable(self, i):
checkBox = getattr(self.view, f"checkBoxV{i}")
checkBox.stateChanged.disconnect()
voltageIndex = getattr(powerIndex, f"V_POWER_{i}")
try:
self.det.setPowerEnabled([voltageIndex], checkBox.isChecked())
except Exception as e:
QtWidgets.QMessageBox.warning(self.mainWindow, "Voltage Fail", str(e), QtWidgets.QMessageBox.Ok)
pass
checkBox.stateChanged.connect(partial(self.setPowerEnable, i))
self.update(i)
if self.det.type == detectorType.CHIPTESTBOARD:
self.getVChip()
def powerOff(self):
for i in Defines.powerSupplies:
# set all voltages to 0
checkBox = getattr(self.view, f"checkBoxV{i}")
checkBox.stateChanged.disconnect()
checkBox.setChecked(False)
checkBox.stateChanged.connect(partial(self.setVoltage, i))
self.setVoltage(i)
voltageIndices = [getattr(powerIndex, f"V_POWER_{i}") for i in Defines.powerSupplies]
try:
self.det.setPowerEnabled(voltageIndices, False)
except Exception as e:
QtWidgets.QMessageBox.warning(self.mainWindow, "Power Off Fail", str(e), QtWidgets.QMessageBox.Ok)
pass
finally:
self.refresh()
def saveParameters(self) -> list:
commands = []
for i in Defines.powerSupplies:
enabled = getattr(self.view, f"checkBoxV{i}").isChecked()
if enabled:
value = getattr(self.view, f"spinBoxV{i}").value()
commands.append(f"v_{i.lower()} {value}")
else:
commands.append(f"v_{i.lower()} 0")
commands.append(f"power v_{i.lower()} {enabled}")
value = getattr(self.view, f"spinBoxV{i}").value()
commands.append(f"powerdac v_{i.lower()} {value}")
return commands
+15 -33
View File
@@ -53,7 +53,7 @@
<string> mV</string>
</property>
<property name="maximum">
<number>2468</number>
<number>5000</number>
</property>
</widget>
</item>
@@ -100,7 +100,7 @@
<number>0</number>
</property>
<property name="maximum">
<number>2468</number>
<number>5000</number>
</property>
<property name="value">
<number>0</number>
@@ -212,35 +212,7 @@ QPushButton:disabled{background-color: grey;}</string>
<string> mV</string>
</property>
<property name="maximum">
<number>2468</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBoxVChip">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Only accepts value range (1200 - 2468)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="suffix">
<string> mV</string>
</property>
<property name="maximum">
<number>2468</number>
<number>5000</number>
</property>
</widget>
</item>
@@ -372,7 +344,7 @@ QPushButton:disabled{background-color: grey;}</string>
<string> mV</string>
</property>
<property name="maximum">
<number>2468</number>
<number>5000</number>
</property>
</widget>
</item>
@@ -455,7 +427,7 @@ QPushButton:disabled{background-color: grey;}</string>
<string> mV</string>
</property>
<property name="maximum">
<number>2468</number>
<number>5000</number>
</property>
</widget>
</item>
@@ -475,6 +447,16 @@ QPushButton:disabled{background-color: grey;}</string>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QLabel" name="labelVChip">
<property name="text">
<string>0 mV</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
+2 -2
View File
@@ -3,8 +3,8 @@
# from .detector import Detector, DetectorError, free_shared_memory
from .eiger import Eiger
from .ctb import Ctb
from .dacs import DetectorDacs, Dac
from .powers import DetectorPowers, Power
from .dacs import NamedDacs, DetectorDacs, Dac
from .powers import NamedPowers, Power
from .detector import Detector
from .jungfrau import Jungfrau
from .mythen3 import Mythen3
+68 -3
View File
@@ -2,12 +2,15 @@
# Copyright (C) 2021 Contributors to the SLS Detector Package
from .detector import Detector, freeze
from .utils import element_if_equal
from .dacs import DetectorDacs, NamedDacs
from .powers import DetectorPowers, NamedPowers
from .dacs import NamedDacs
from .powers import NamedPowers
from .proxy import SlowAdcProxy
from . import _slsdet
dacIndex = _slsdet.slsDetectorDefs.dacIndex
from .detector_property import DetectorProperty
import numpy as np
from .utils import element
@freeze
@@ -24,4 +27,66 @@ class Ctb(Detector):
@property
def powers(self):
return self._powers
return self._powers
@property
def powerlist(self):
return self.getPowerNames()
@powerlist.setter
def powerlist(self, value):
self.setPowerNames(value)
@property
def adclist(self):
return self.getAdcNames()
@adclist.setter
def adclist(self, value):
self.setAdcNames(value)
@property
def signallist(self):
return self.getSignalNames()
@signallist.setter
def signallist(self, value):
self.setSignalNames(value)
@property
def slowadc(self):
"""
[Ctb] Slow ADC channel in uV of all channels or specific ones from 0-7.
Example
-------
>>> d.slowadc
0: 0 uV
1: 0 uV
2: 0 uV
3: 0 uV
4: 0 uV
5: 0 uV
6: 0 uV
7: 0 uV
>>> d.slowadc[3]
0
"""
return SlowAdcProxy(self)
@property
def slowadclist(self):
return self.getSlowADCNames()
@slowadclist.setter
def slowadclist(self, value):
self.setSlowADCNames(value)
@property
def slowadcvalues(self):
"""[Chiptestboard][Xilinx CTB] Gets the slow adc values for every slow adc for this detector."""
return {
slowadc.name.lower(): element_if_equal(np.array(self.getSlowADC(slowadc)))
for slowadc in self.getSlowADCList()
}
+20 -27
View File
@@ -41,40 +41,33 @@ class NamedDacs:
New implementation of the detector dacs. Used at the moment for
Ctb but should replace the old one for all detectors
"""
_frozen = False
_direct_access = ['_detector', '_current', '_dacnames']
_direct_access = ['_detector', '_current']
def __init__(self, detector):
self._frozen = False
self._detector = detector
self._current = 0
#only get the dacnames if we have modules attached
if detector.size() == 0:
self._dacnames = [f"dac{i}" for i in range(18)]
else:
self._dacnames = [n.replace(" ", "") for n in detector.getDacNames()]
# Populate the dacs
for i,name in enumerate(self._dacnames):
#name, enum, low, high, default, detector
setattr(self, name, Dac(name, dacIndex(i), 0, 4000, 1000, detector))
self._frozen = True
# def __getattr__(self, name):
# return self.__getattribute__('_' + name)
@property
def _dacnames(self):
if self._detector.size() == 0:
raise RuntimeError("No modules added")
return [n.replace(" ", "") for n in self._detector.daclist]
def __getattr__(self, name):
if name in self._dacnames:
idx = self._dacnames.index(name)
return Dac(name, dacIndex(idx), 0, 4096, -100, self._detector)
raise AttributeError(f'Dac not found: {name}')
def __setattr__(self, name, value):
if not self._frozen:
#durning init we need to be able to set up the class
if name in ('_detector', '_current', '_frozen'):
super().__setattr__(name, value)
elif name in self._dacnames:
return getattr(self, name).__setitem__(slice(None, None, None), value)
else:
#Later we restrict us to manipulate dacs and a few fields
if name in self._direct_access:
super().__setattr__(name, value)
elif name in self._dacnames:
return self.__getattribute__(name).__setitem__(slice(None, None, None), value)
else:
raise AttributeError(f'Dac not found: {name}')
raise AttributeError(f'Dac not found: {name}')
def __next__(self):
if self._current >= len(self._dacnames):
@@ -82,10 +75,10 @@ class NamedDacs:
raise StopIteration
else:
self._current += 1
return self.__getattribute__(self._dacnames[self._current-1])
# return self.__getattr__(self._dacnames[self._current-1])
return getattr(self, self._dacnames[self._current-1])
def __iter__(self):
self._current = 0
return self
def __repr__(self):
+11 -152
View File
@@ -10,6 +10,7 @@ runStatus = slsDetectorDefs.runStatus
timingMode = slsDetectorDefs.timingMode
speedLevel = slsDetectorDefs.speedLevel
dacIndex = slsDetectorDefs.dacIndex
powerIndex = slsDetectorDefs.powerIndex
detectorType = slsDetectorDefs.detectorType
streamingInterface = slsDetectorDefs.streamingInterface
@@ -20,7 +21,7 @@ from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname
from ._slsdet import xy, freeSharedMemory, getUserDetails
from .gaincaps import Mythen3GainCapsWrapper
from . import utils as ut
from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
from .proxy import JsonProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
from .registers import Register, Adc_register
import datetime as dt
@@ -516,13 +517,12 @@ class Detector(CppDetectorApi):
@element
def powerchip(self):
"""
[Jungfrau][Moench][Mythen3][Gotthard2][Xilinx Ctb] Power the chip.
[Jungfrau][Moench][Mythen3][Gotthard2] Power the chip.
Note
----
[Jungfrau][Moench] Default is disabled. Get will return power status. Can be off if temperature event occured (temperature over temp_threshold with temp_control enabled. Will configure chip (only chip v1.1).\n
[Mythen3][Gotthard2] Default is 1. If module not connected or wrong module, powerchip will fail.
[Xilinx Ctb] Default is 0. Also configures the chip if powered on.
"""
return self.getPowerChip()
@@ -1987,26 +1987,7 @@ class Detector(CppDetectorApi):
return super().getBit(resolved)
@property
def slowadc(self):
"""
[Ctb] Slow ADC channel in uV of all channels or specific ones from 0-7.
Example
-------
>>> d.slowadc
0: 0 uV
1: 0 uV
2: 0 uV
3: 0 uV
4: 0 uV
5: 0 uV
6: 0 uV
7: 0 uV
>>> d.slowadc[3]
0
"""
return SlowAdcProxy(self)
@property
def daclist(self):
@@ -2022,52 +2003,7 @@ class Detector(CppDetectorApi):
def daclist(self, value):
self.setDacNames(value)
@property
def adclist(self):
"""
[Chiptestboard] List of names for every adc for this board. 32 adcs
"""
return self.getAdcNames()
@adclist.setter
def adclist(self, value):
self.setAdcNames(value)
@property
def signallist(self):
"""
[Chiptestboard] List of names for every io signal for this board. 64 signals
"""
return self.getSignalNames()
@signallist.setter
def signallist(self, value):
self.setSignalNames(value)
@property
def powerlist(self):
"""
[Chiptestboard] List of names for every power for this board. 5 power supply
"""
return self.getPowerNames()
@powerlist.setter
def powerlist(self, value):
self.setPowerNames(value)
@property
def slowadclist(self):
"""
[Chiptestboard] List of names for every slowadc for this board. 8 slowadc
"""
return self.getSlowADCNames()
@slowadclist.setter
def slowadclist(self, value):
self.setSlowADCNames(value)
@property
def dacvalues(self):
"""Gets the dac values for every dac for this detector."""
@@ -2076,21 +2012,6 @@ class Detector(CppDetectorApi):
for dac in self.getDacList()
}
@property
def powervalues(self):
"""[Chiptestboard] Gets the power values for every power for this detector."""
return {
power.name.lower(): element_if_equal(np.array(self.getPower(power)))
for power in self.getPowerList()
}
@property
def slowadcvalues(self):
"""[Chiptestboard] Gets the slow adc values for every slow adc for this detector."""
return {
slowadc.name.lower(): element_if_equal(np.array(self.getSlowADC(slowadc)))
for slowadc in self.getSlowADCList()
}
@property
def timinglist(self):
@@ -4189,77 +4110,15 @@ class Detector(CppDetectorApi):
n = ut.merge_args(2, n)
ut.set_using_dict(self.setPatternLoopCycles, *n)
@property
@element
def v_a(self):
"""[Ctb][Xilinx Ctb] Power supply a in mV."""
return self.getPower(dacIndex.V_POWER_A)
@v_a.setter
def v_a(self, value):
value = ut.merge_args(dacIndex.V_POWER_A, value)
ut.set_using_dict(self.setPower, *value)
@property
@element
def v_b(self):
"""[Ctb][Xilinx Ctb] Power supply b in mV."""
return self.getPower(dacIndex.V_POWER_B)
@v_b.setter
def v_b(self, value):
value = ut.merge_args(dacIndex.V_POWER_B, value)
ut.set_using_dict(self.setPower, *value)
@property
@element
def v_c(self):
"""[Ctb][Xilinx Ctb] Power supply c in mV."""
return self.getPower(dacIndex.V_POWER_C)
@v_c.setter
def v_c(self, value):
value = ut.merge_args(dacIndex.V_POWER_C, value)
ut.set_using_dict(self.setPower, *value)
@property
@element
def v_d(self):
"""[Ctb][Xilinx Ctb] Power supply d in mV."""
return self.getPower(dacIndex.V_POWER_D)
@v_d.setter
def v_d(self, value):
value = ut.merge_args(dacIndex.V_POWER_D, value)
ut.set_using_dict(self.setPower, *value)
@property
@element
def v_io(self):
"""[Ctb][Xilinx Ctb] Power supply io in mV. Minimum 1200 mV.
Note
----
Must be the first power regulator to be set after fpga reset (on-board detector server start up).
"""
return self.getPower(dacIndex.V_POWER_IO)
@v_io.setter
def v_io(self, value):
value = ut.merge_args(dacIndex.V_POWER_IO, value)
ut.set_using_dict(self.setPower, *value)
@property
@element
def v_limit(self):
"""[Ctb][Xilinx Ctb] Soft limit for power supplies (ctb only) and DACS in mV."""
return self.getPower(dacIndex.V_LIMIT)
return self.getVoltageLimit()
@v_limit.setter
def v_limit(self, value):
value = ut.merge_args(dacIndex.V_LIMIT, value)
ut.set_using_dict(self.setPower, *value)
ut.set_using_dict(self.setVoltageLimit, value)
@property
@element
@@ -4268,7 +4127,7 @@ class Detector(CppDetectorApi):
:setter: Not implemented
"""
return self.getMeasuredCurrent(dacIndex.I_POWER_A)
return self.getMeasuredCurrent(powerIndex.I_POWER_A)
@property
@element
@@ -4277,7 +4136,7 @@ class Detector(CppDetectorApi):
:setter: Not implemented
"""
return self.getMeasuredCurrent(dacIndex.I_POWER_B)
return self.getMeasuredCurrent(powerIndex.I_POWER_B)
@property
@element
@@ -4286,7 +4145,7 @@ class Detector(CppDetectorApi):
:setter: Not implemented
"""
return self.getMeasuredCurrent(dacIndex.I_POWER_C)
return self.getMeasuredCurrent(powerIndex.I_POWER_C)
@property
@element
@@ -4295,7 +4154,7 @@ class Detector(CppDetectorApi):
:setter: Not implemented
"""
return self.getMeasuredCurrent(dacIndex.I_POWER_D)
return self.getMeasuredCurrent(powerIndex.I_POWER_D)
@property
@element
@@ -4304,7 +4163,7 @@ class Detector(CppDetectorApi):
:setter: Not implemented
"""
return self.getMeasuredCurrent(dacIndex.I_POWER_IO)
return self.getMeasuredCurrent(powerIndex.I_POWER_IO)
@property
def clkphase(self):
+93 -145
View File
@@ -1,77 +1,125 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
from .detector_property import DetectorProperty
from functools import partial
import numpy as np
from . import _slsdet
from .detector import freeze
dacIndex = _slsdet.slsDetectorDefs.dacIndex
class Power(DetectorProperty):
powerIndex = _slsdet.slsDetectorDefs.powerIndex
class Power:
"""
This class represents a power on the Chip Test Board. One instance handles all
powers with the same name for a multi detector instance. (TODO: Not needed for CTB)
This class represents a power supply on the Chip Test Board.
.. note ::
This class is used to build up DetectorPowers and is in general
This class is used to build up NamedPowers and is in general
not directly accessible to the user.
"""
_direct_access = ['_detector']
def __init__(self, name, enum, default, detector):
super().__init__(partial(detector.getPower, enum),
lambda x, y : detector.setPower(enum, x, y),
detector.size,
name)
self._frozen = False
self.__name__ = name
self.enum = enum
self.default = default
self.detector = detector
self._frozen = True
def enable(self):
" Enable this power supply."
self.detector.setPowerEnabled([self.enum], True)
def disable(self):
" Disable this power supply."
self.detector.setPowerEnabled([self.enum], False)
@property
def dac(self):
" Returns the dac value for this power supply in mV."
return self.detector.getPowerDAC(self.enum)
@property
def enabled(self):
" Returns whether this power supply is enabled."
return self.detector.isPowerEnabled(self.enum)
# prevent unknown attributes
def __setattr__(self, name, value):
if not getattr(self, "_frozen", False) or name in ("_frozen", "__name__", "enum", "default", "detector"):
super().__setattr__(name, value)
else:
raise AttributeError(f"Cannot set attribute '{name}' on Power.")
def __eq__(self, other):
if isinstance(other, Power):
return (
self.detector == other.detector and
self.enum == other.enum
)
if isinstance(other, int):
return self.dac == other
return NotImplemented
def __repr__(self):
"""String representation for a single power in all modules"""
powerstr = ''.join([f'{item:5d}' for item in self.get()])
return f'{self.__name__:15s}:{powerstr}'
"String representation for a single power supply"
return f'{self.__name__:15s}: {str(self.enabled):5s}, {self.dac:5d} mV'
class NamedPowers:
"""
New implementation of the detector powers.
List implementation of the all the power supplies with its names.
d.powers gives you list of all powers with their DAC values and enables.
Example
--------
# print all powers with DAC and enables
d.powers
# set DAC or enables
d.powers.VA = 1200
d.powers.VA.enable()
d.powers.VA.disable()
# get
d.powers.VA.enabled
d.powers.VA.dac
d.powers.VA # print both enabled and dac
"""
_frozen = False
_direct_access = ['_detector', '_current', '_powernames']
_direct_access = ['_detector', '_current']
def __init__(self, detector):
self._frozen = False
self._detector = detector
self._current = 0
#only get the powernames if we have modules attached
if detector.size() == 0:
self._powernames = ["VA", "VB", "VC", "VD", "VIO"]
else:
self._powernames = [n.replace(" ", "") for n in detector.getPowerNames()]
# Populate the powers
for i,name in enumerate(self._powernames):
#name, enum, low, high, default, detector
k = dacIndex(i + int(dacIndex.V_POWER_A))
setattr(self, name, Power(name, k, 0, detector))
self._frozen = True
# def __getattr__(self, name):
# return self.__getattribute__('_' + name)
@property
def _powernames(self):
if self._detector.size() == 0:
raise RuntimeError("No modules added")
# always get the latest list
if hasattr(self._detector, 'powerlist'):
return [n.replace(" ", "") for n in self._detector.powerlist]
else:
raise RuntimeError("Detector does not have powerlist attribute")
def __getattr__(self, name):
if name in self._powernames:
idx = self._powernames.index(name)
return Power(name, powerIndex(idx), 0, self._detector)
raise AttributeError(f'Power not found: {name}')
def __setattr__(self, name, value):
if not self._frozen:
#durning init we need to be able to set up the class
if name in ("_detector", "_current", "_frozen"):
super().__setattr__(name, value)
else:
#Later we restrict us to manipulate powers and a few fields
if name in self._direct_access:
super().__setattr__(name, value)
elif name in self._powernames:
return self.__getattribute__(name).__setitem__(slice(None, None), value)
elif name in self._powernames:
if isinstance(value, int):
idx = self._powernames.index(name)
self._detector.setPowerDAC(powerIndex(idx), value)
else:
raise AttributeError(f'Power not found: {name}')
raise AttributeError(f"Can only set DAC (int) for '{name}' on Power.")
else:
raise AttributeError(f'Power not found: {name}')
def __next__(self):
if self._current >= len(self._powernames):
@@ -79,83 +127,11 @@ class NamedPowers:
raise StopIteration
else:
self._current += 1
return self.__getattribute__(self._powernames[self._current-1])
return getattr(self, self._powernames[self._current-1])
# return self.__getattr__(self._powernames[self._current-1])
def __iter__(self):
return self
def __repr__(self):
r_str = ['========== POWERS =========']
r_str += [repr(power) for power in self]
return '\n'.join(r_str)
def get_asarray(self):
"""
Read the powers into a numpy array with dimensions [npowers, nmodules]
"""
power_array = np.zeros((len(self._powernames), len(self._detector)))
for i, _d in enumerate(self):
power_array[i,:] = _d[:]
return power_array
def to_array(self):
return self.get_asarray()
def set_from_array(self, power_array):
"""
Set the power from an numpy array with power values. [npowers, nmodules]
"""
power_array = power_array.astype(np.int)
for i, _d in enumerate(self):
_d[:] = power_array[i]
def from_array(self, power_array):
self.set_from_array(power_array)
class DetectorPowers:
_powers = []
_powernames = [_d[0] for _d in _powers]
_allowed_attr = ['_detector', '_current']
_frozen = False
def __init__(self, detector):
# We need to at least initially know which detector we are connected to
self._detector = detector
# Index to support iteration
self._current = 0
# Name the attributes?
for _d in self._powers:
setattr(self, '_'+_d[0], Power(*_d, detector))
self._frozen = True
def __getattr__(self, name):
return self.__getattribute__('_' + name)
@property
def powernames(self):
return [_d[0] for _d in _powers]
def __setattr__(self, name, value):
if name in self._powernames:
return self.__getattribute__('_' + name).__setitem__(slice(None, None), value)
else:
if self._frozen == True and name not in self._allowed_attr:
raise AttributeError(f'Power not found: {name}')
super().__setattr__(name, value)
def __next__(self):
if self._current >= len(self._powers):
self._current = 0
raise StopIteration
else:
self._current += 1
return self.__getattr__(self._powernames[self._current-1])
def __iter__(self):
return self
def __repr__(self):
@@ -163,33 +139,5 @@ class DetectorPowers:
r_str += [repr(power) for power in self]
return '\n'.join(r_str)
def get_asarray(self):
"""
Read the powers into a numpy array with dimensions [npowers, nmodules]
"""
power_array = np.zeros((len(self._powers), len(self._detector)))
for i, _d in enumerate(self):
power_array[i,:] = _d[:]
return power_array
def to_array(self):
return self.get_asarray()
def set_from_array(self, power_array):
"""
Set the powers from an numpy array with power values. [npowers, nmodules]
"""
power_array = power_array.astype(np.int)
for i, _d in enumerate(self):
_d[:] = power_array[i]
def from_array(self, power_array):
self.set_from_array(power_array)
def set_default(self):
"""
Set all powers to their default values
"""
for _d in self:
_d[:] = _d.default
def __dir__(self):
return super().__dir__() + self._powernames
+40 -29
View File
@@ -1549,21 +1549,46 @@ void init_det(py::module &m) {
Detector::getSYNCClock,
py::arg() = Positions{});
CppDetectorApi.def("getPowerList",
(std::vector<defs::dacIndex>(Detector::*)() const) &
(std::vector<defs::powerIndex>(Detector::*)() const) &
Detector::getPowerList);
CppDetectorApi.def("getPowerDAC",
(int (Detector::*)(defs::powerIndex) const) &
Detector::getPowerDAC,
py::arg());
CppDetectorApi.def("setPowerDAC",
(void (Detector::*)(defs::powerIndex, int)) &
Detector::setPowerDAC,
py::arg(), py::arg());
CppDetectorApi.def("isPowerEnabled",
(bool (Detector::*)(defs::powerIndex) const) &
Detector::isPowerEnabled,
py::arg());
CppDetectorApi.def(
"setPowerEnabled",
(void (Detector::*)(const std::vector<defs::powerIndex> &, bool)) &
Detector::setPowerEnabled,
py::arg(), py::arg());
CppDetectorApi.def("getMeasuredPower",
(int (Detector::*)(defs::powerIndex) const) &
Detector::getMeasuredPower,
py::arg());
CppDetectorApi.def("getMeasuredCurrent",
(int (Detector::*)(defs::powerIndex) const) &
Detector::getMeasuredCurrent,
py::arg());
CppDetectorApi.def("getVoltageLimit",
(int (Detector::*)() const) & Detector::getVoltageLimit);
CppDetectorApi.def(
"setVoltageLimit",
(void (Detector::*)(const int)) & Detector::setVoltageLimit, py::arg());
CppDetectorApi.def("getSlowADCList",
(std::vector<defs::dacIndex>(Detector::*)() const) &
Detector::getSlowADCList);
CppDetectorApi.def(
"getPower",
"getSlowADC",
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
Detector::getPower,
Detector::getSlowADC,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def(
"setPower",
(void (Detector::*)(defs::dacIndex, int, sls::Positions)) &
Detector::setPower,
py::arg(), py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getADCVpp",
(Result<int>(Detector::*)(bool, sls::Positions) const) &
Detector::getADCVpp,
@@ -1629,21 +1654,6 @@ void init_det(py::module &m) {
(void (Detector::*)(int, sls::Positions)) &
Detector::setDBITClock,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def(
"getMeasuredPower",
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
Detector::getMeasuredPower,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def(
"getMeasuredCurrent",
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
Detector::getMeasuredCurrent,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def(
"getSlowADC",
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
Detector::getSlowADC,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getExternalSamplingSource",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getExternalSamplingSource,
@@ -1766,18 +1776,19 @@ void init_det(py::module &m) {
Detector::getPowerNames);
CppDetectorApi.def(
"getPowerIndex",
(defs::dacIndex(Detector::*)(const std::string &) const) &
(defs::powerIndex(Detector::*)(const std::string &) const) &
Detector::getPowerIndex,
py::arg());
CppDetectorApi.def(
"setPowerName",
(void (Detector::*)(const defs::dacIndex, const std::string &)) &
(void (Detector::*)(const defs::powerIndex, const std::string &)) &
Detector::setPowerName,
py::arg(), py::arg());
CppDetectorApi.def("getPowerName",
(std::string(Detector::*)(const defs::dacIndex) const) &
Detector::getPowerName,
py::arg());
CppDetectorApi.def(
"getPowerName",
(std::string(Detector::*)(const defs::powerIndex) const) &
Detector::getPowerName,
py::arg());
CppDetectorApi.def("setSlowADCNames",
(void (Detector::*)(const std::vector<std::string>)) &
Detector::setSlowADCNames,
+20 -12
View File
@@ -29,6 +29,12 @@ void init_enums(py::module &m) {
slsDetectorDefs::detectorType::XILINX_CHIPTESTBOARD)
.export_values();
py::enum_<slsDetectorDefs::boolFormat>(Defs, "boolFormat")
.value("TrueFalse", slsDetectorDefs::boolFormat::TrueFalse)
.value("OnOff", slsDetectorDefs::boolFormat::OnOff)
.value("OneZero", slsDetectorDefs::boolFormat::OneZero)
.export_values();
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
@@ -175,18 +181,6 @@ void init_enums(py::module &m) {
.value("TEMPERATURE_FPGA3",
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA3)
.value("TRIMBIT_SCAN", slsDetectorDefs::dacIndex::TRIMBIT_SCAN)
.value("V_POWER_A", slsDetectorDefs::dacIndex::V_POWER_A)
.value("V_POWER_B", slsDetectorDefs::dacIndex::V_POWER_B)
.value("V_POWER_C", slsDetectorDefs::dacIndex::V_POWER_C)
.value("V_POWER_D", slsDetectorDefs::dacIndex::V_POWER_D)
.value("V_POWER_IO", slsDetectorDefs::dacIndex::V_POWER_IO)
.value("V_POWER_CHIP", slsDetectorDefs::dacIndex::V_POWER_CHIP)
.value("I_POWER_A", slsDetectorDefs::dacIndex::I_POWER_A)
.value("I_POWER_B", slsDetectorDefs::dacIndex::I_POWER_B)
.value("I_POWER_C", slsDetectorDefs::dacIndex::I_POWER_C)
.value("I_POWER_D", slsDetectorDefs::dacIndex::I_POWER_D)
.value("I_POWER_IO", slsDetectorDefs::dacIndex::I_POWER_IO)
.value("V_LIMIT", slsDetectorDefs::dacIndex::V_LIMIT)
.value("SLOW_ADC0", slsDetectorDefs::dacIndex::SLOW_ADC0)
.value("SLOW_ADC1", slsDetectorDefs::dacIndex::SLOW_ADC1)
.value("SLOW_ADC2", slsDetectorDefs::dacIndex::SLOW_ADC2)
@@ -198,6 +192,20 @@ void init_enums(py::module &m) {
.value("SLOW_ADC_TEMP", slsDetectorDefs::dacIndex::SLOW_ADC_TEMP)
.export_values();
py::enum_<slsDetectorDefs::powerIndex>(Defs, "powerIndex")
.value("V_POWER_A", slsDetectorDefs::powerIndex::V_POWER_A)
.value("V_POWER_B", slsDetectorDefs::powerIndex::V_POWER_B)
.value("V_POWER_C", slsDetectorDefs::powerIndex::V_POWER_C)
.value("V_POWER_D", slsDetectorDefs::powerIndex::V_POWER_D)
.value("V_POWER_IO", slsDetectorDefs::powerIndex::V_POWER_IO)
.value("V_POWER_CHIP", slsDetectorDefs::powerIndex::V_POWER_CHIP)
.value("I_POWER_A", slsDetectorDefs::powerIndex::I_POWER_A)
.value("I_POWER_B", slsDetectorDefs::powerIndex::I_POWER_B)
.value("I_POWER_C", slsDetectorDefs::powerIndex::I_POWER_C)
.value("I_POWER_D", slsDetectorDefs::powerIndex::I_POWER_D)
.value("I_POWER_IO", slsDetectorDefs::powerIndex::I_POWER_IO)
.export_values();
py::enum_<slsDetectorDefs::detectorSettings>(Defs, "detectorSettings")
.value("STANDARD", slsDetectorDefs::detectorSettings::STANDARD)
.value("FAST", slsDetectorDefs::detectorSettings::FAST)
+321
View File
@@ -394,3 +394,324 @@ def test_patternstart(session_simulator, request):
assert "not implemented" in str(exc_info.value)
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_v_limit(session_simulator, request):
"""Test v_limit."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
if det_type in ['ctb', 'xilinx_ctb']:
# save previous value
prev_val = d.getVoltageLimit()
from slsdet import dacIndex, powerIndex
prev_dac_val = d.getDAC(dacIndex.DAC_0, False)
prev_power_dac_val = d.getPowerDAC(powerIndex.V_POWER_A)
with pytest.raises(Exception):
d.v_limit = (1200, 'mV') #mV unit not supported, should be 'no unit'
with pytest.raises(Exception):
d.v_limit = -100 # previously worked but not allowing now
# setting dac and power dac with no vlimit should work
d.v_limit = 0
assert d.v_limit == 0
d.setDAC(dacIndex.DAC_0, 1200, True, [0])
d.setPowerDAC(powerIndex.V_POWER_A, 1200)
# setting vlimit should throw setting values above vlimit
d.v_limit = 1500
assert d.v_limit == 1500
with pytest.raises(Exception):
d.setDAC(dacIndex.DAC_0, 1501, True, [0])
with pytest.raises(Exception):
d.setPowerDAC(powerIndex.V_POWER_A, 1501)
# setting dac and power dac below vlimit should still work
d.setDAC(dacIndex.DAC_0, 1210, True, [0])
d.setPowerDAC(powerIndex.V_POWER_A, 1210)
# restore previous value
d.setVoltageLimit(prev_val)
d.setPowerDAC(powerIndex.V_POWER_A, prev_power_dac_val)
for i in range(len(d)):
d.setDAC(dacIndex.DAC_0, prev_dac_val[i], False, [i])
else:
with pytest.raises(Exception) as exc_info:
d.v_limit
assert "not implemented" in str(exc_info.value)
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_v_abcd(session_simulator, request):
"""Test v_a, v_b, v_c, v_d, v_io are deprecated comands."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
with pytest.raises(Exception):
d.v_a
with pytest.raises(Exception):
d.v_b
with pytest.raises(Exception):
d.v_c
with pytest.raises(Exception):
d.v_d
with pytest.raises(Exception):
d.v_io
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_powers(session_simulator, request):
"""Test powers and powerlist."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
from slsdet import Ctb
c = Ctb()
if det_type in ['ctb', 'xilinx_ctb']:
c.powerlist
# save previous value
from slsdet import powerIndex
prev_val_dac = {power: c.getPowerDAC(power) for power in c.getPowerList()}
prev_val = {power: c.isPowerEnabled(power) for power in c.getPowerList()}
# invalid
invalid_assignments = [
(c.powers, "random", True), # set random power
(c.powers, "random", True), # set random attribute of power
(c.powers.VA, "dac", "1200"),
(c.powers.VA, "enabled", "True"),
(c.powers, "VA", "-100"),
(c.powers, "VA", "-1"),
(c.powers, "VA", "4096")
]
for obj, attr, value in invalid_assignments:
with pytest.raises(Exception):
setattr(obj, attr, value)
# vchip power can only be accessed via pybindings because it cannot be enabled/disabled
with pytest.raises(Exception):
c.powers.VCHIP
# valid
c.powers
c.powers.VA = 1200
assert c.powers.VA == 1200
assert c.powers.VA.dac == 1200
c.powers.VA.enable()
assert c.powers.VA.enabled == True
c.setPowerEnabled([powerIndex.V_POWER_B, powerIndex.V_POWER_C], True)
assert c.powers.VB.enabled == True
assert c.powers.VC.enabled == True
c.powers.VA = 1500
assert c.powers.VA == 1500
assert c.powers.VA.dac == 1500
# change power name and test same value
temp = c.powers.VB
c.powerlist = ["VA", "m_VB", "VC", "VD", "VIO"]
assert c.powers.m_VB.enabled == True
assert c.powers.m_VB == temp
# restore previous value
for power in c.getPowerList():
c.setPowerDAC(power, prev_val_dac[power])
c.setPowerEnabled([power], prev_val[power])
else:
with pytest.raises(Exception) as exc_info:
c.powerlist
assert "only for CTB" in str(exc_info.value)
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_adclist(session_simulator, request):
"""Test ADC list."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
from slsdet import Ctb
c = Ctb()
if det_type in ['ctb', 'xilinx_ctb']:
c.adclist
c.adclist = ["1", "2", "3", "test", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32"]
c.adclist
else:
with pytest.raises(Exception) as exc_info:
c.adclist
assert "only for CTB" in str(exc_info.value)
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_signallist(session_simulator, request):
"""Test signal list."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
from slsdet import Ctb
c = Ctb()
if det_type in ['ctb', 'xilinx_ctb']:
c.signallist
c.signallist = ["1", "2", "3", "test", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64"]
c.signallist
else:
with pytest.raises(Exception) as exc_info:
c.signallist
assert "only for CTB" in str(exc_info.value)
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_slowadc(session_simulator, request):
"""Test slow ADC and slow adc list."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
from slsdet import Ctb
c = Ctb()
if det_type in ['ctb', 'xilinx_ctb']:
c.slowadc
c.slowadc.SLOWADC5
c.slowadclist = ["1", "2", "3", "test", "5", "6", "7", "8"]
c.slowadc.test
else:
with pytest.raises(Exception) as exc_info:
c.signallist
assert "only for CTB" in str(exc_info.value)
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@pytest.mark.detectorintegration
def test_dac(session_simulator, request):
"""Test dac."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
from slsdet import dacIndex
if det_type in ['ctb', 'xilinx_ctb']:
from slsdet import Ctb
c = Ctb()
# valid
c.daclist
c.dacvalues
# save previous value
prev_val = {dac: c.getDAC(dac, False) for dac in c.getDacList()}
prev_dac_list = c.daclist
# invalid
invalid_assignments = [
(c.dacs, "vb_comp", "1200"), # set random dac
(c.dacs, "DAC18", "1200"), # set dac 18
(c.dacs, "DAC0", "-1"),
(c.dacs, "DAC0", "4096")
]
for obj, attr, value in invalid_assignments:
with pytest.raises(Exception):
setattr(obj, attr, value)
# valid
c.dacs.DAC0 = 1200
assert c.getDAC(dacIndex.DAC_0, False)[0] == 1200
c.dacs.DAC0 = 0
assert c.dacs.DAC0[0] == 0
# restore previous value
for dac in c.getDacList():
c.setDAC(dac, prev_val[dac][0], False)
c.daclist = prev_dac_list
else:
with pytest.raises(Exception):
d.dacs.DAC0
# valid
d.daclist
d.dacvalues
# remember first dac name and index to test later
dacname = d.daclist[0]
assert dacname
dacIndex = d.getDacList()[0]
# save previous value
prev_val = d.getDAC(dacIndex, False)
if det_type == 'eiger':
from slsdet import Eiger
c = Eiger()
elif det_type == 'jungfrau':
from slsdet import Jungfrau
c = Jungfrau()
elif det_type == 'gotthard2':
from slsdet import Gotthard2
c = Gotthard2()
elif det_type == 'mythen3':
from slsdet import Mythen3
c = Mythen3()
elif det_type == 'moench':
from slsdet import Moench
c = Moench()
else:
raise RuntimeError("Unknown detector type to test dac: " + det_type)
# invalid checks
invalid_assignments = [
(c.dacs, "random", "1200"), # set random dac
(c.dacs, "DAC0", "1200"), # set random dac
(c.dacs, dacname, "-1"),
(c.dacs, dacname, "4096")
]
for obj, attr, value in invalid_assignments:
with pytest.raises(Exception):
setattr(obj, attr, value)
# valid, have to use setattr because c is different for each detector
# and we cannot hardcode the dac name
setattr(c.dacs, dacname, 1200)
assert c.getDAC(dacIndex, False)[0] == 1200
setattr(c.dacs, dacname, 0)
assert getattr(c.dacs, dacname)[0] == 0
# restore previous value
for i in range(len(d)):
d.setDAC(dacIndex, prev_val[i], False, [i])
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@@ -631,6 +631,14 @@
/* Clock Measurement base reg */
#define PLL_FREQ_MEASURE_REG (0x44 << MEM_MAP_SHIFT)
/* SPI */
#define SPI_CTRL_REG (0x48 << MEM_MAP_SHIFT)
#define SPI_CTRL_RX_EMPTY_BIT 2
#define SPI_CTRL_CHIPSELECT_BIT 4
#define SPI_CTRL_NBIT_OFST 16
#define SPI_WRITEDATA_REG (0x49 << MEM_MAP_SHIFT)
#define SPI_READDATA_REG (0x4A << MEM_MAP_SHIFT)
/** I2C Control register */
#define I2C_TRANSFER_COMMAND_FIFO_REG (0x100 << MEM_MAP_SHIFT)
#define I2C_RX_DATA_FIFO_REG (0x101 << MEM_MAP_SHIFT)
@@ -67,7 +67,9 @@ uint32_t transceiverMask = DEFAULT_TRANSCEIVER_MASK;
int32_t clkPhase[NUM_CLOCKS] = {};
uint32_t clkFrequency[NUM_CLOCKS] = {DEFAULT_RUN_CLK, DEFAULT_ADC_CLK, DEFAULT_SYNC_CLK, DEFAULT_DBIT_CLK};
int dacValues[NDAC] = {};
int dacValues[NDAC_ONLY] = {};
int powerValues[NPWR] = {}; // powerIndex (A->IO, Chip)
// software limit that depends on the current chip on the ctb
int vLimit = 0;
int highvoltage = 0;
@@ -524,8 +526,10 @@ void setupDetector() {
clkFrequency[ADC_CLK] = DEFAULT_ADC_CLK;
clkFrequency[SYNC_CLK] = DEFAULT_SYNC_CLK;
clkFrequency[DBIT_CLK] = DEFAULT_DBIT_CLK;
for (int i = 0; i < NDAC; ++i)
for (int i = 0; i != NDAC_ONLY; ++i)
dacValues[i] = -1;
for (int i = 0; i != NPWR; ++i)
powerValues[i] = 0; // to calculate vchip
}
vLimit = DEFAULT_VLIMIT;
highvoltage = 0;
@@ -572,7 +576,7 @@ void setupDetector() {
if (initError == FAIL)
return;
// power off voltage regulators
// power regulators
powerOff();
// adcs
@@ -601,11 +605,11 @@ void setupDetector() {
// power regulators
LOG(logINFOBLUE,
("Setting power dacs to min dac value (power disabled)\n"));
for (int idac = NDAC_ONLY; idac < NDAC; ++idac) {
if (idac == D_PWR_CHIP)
for (int iPower = 0; iPower != NPWR; ++iPower) {
if (iPower == (int)V_POWER_CHIP)
continue;
int min = (idac == D_PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
initError = setDAC(idac, min, true, initErrorMessage);
int min = (iPower == (int)V_POWER_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
initError = setPowerDAC(iPower, min, initErrorMessage);
if (initError == FAIL)
return;
}
@@ -1262,9 +1266,22 @@ int getADCVpp(int mV, int *retval, char *mess) {
return OK;
}
int getVLimit() { return vLimit; }
int setVLimit(int val, char *mess) {
if (val < 0) {
sprintf(mess, "Could not set vlimit. Invalid value %d\n", val);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("Setting vlimit to %d mV\n", val));
vLimit = val;
return OK;
}
int validateDACIndex(enum DACINDEX ind, char *mess) {
if (ind < 0 || ind >= NDAC) {
sprintf(mess, "Could not set DAC. Invalid index %d\n", ind);
if (ind < 0 || ind >= NDAC_ONLY) {
sprintf(mess, "Could not set/get DAC. Invalid index %d\n", ind);
LOG(logERROR, (mess));
return FAIL;
}
@@ -1300,84 +1317,26 @@ int validateDACVoltage(enum DACINDEX ind, int voltage, char *mess) {
return OK;
}
int convertVoltageToDACValue(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess) {
int convertVoltageToDAC(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess) {
*retval_dacval = -1;
// normal dacs
if (ind < NDAC_ONLY) {
if (LTC2620_VoltageToDac(voltage, retval_dacval) == FAIL) {
sprintf(
mess,
"Could not set DAC %d. Could not convert %d mV to dac units.\n",
ind, voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
// vchip
if (ind == D_PWR_CHIP) {
if (ConvertToDifferentRange(
VCHIP_MIN_MV, VCHIP_MAX_MV, LTC2620_GetMaxInput(),
LTC2620_GetMinInput(), voltage, retval_dacval) == FAIL) {
sprintf(mess,
"Could not set DAC %d (vchip). Could not convert %d mV to "
"dac units.\n",
ind, voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
// power dacs
if (ConvertToDifferentRange(POWER_RGLTR_MIN, POWER_RGLTR_MAX,
LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
voltage, retval_dacval) == FAIL) {
if (LTC2620_VoltageToDac(voltage, retval_dacval) == FAIL) {
sprintf(mess,
"Could not set DAC %d. Could not convert %d mV to dac units.\n",
ind, voltage);
(int)ind, voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int convertDACValueToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess) {
int convertDACToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess) {
*retval_voltage = -1;
// normal dacs
if (ind < NDAC_ONLY) {
if (LTC2620_DacToVoltage(dacval, retval_voltage) == FAIL) {
sprintf(
mess,
"Could not get DAC %d. Could not convert %d dac units to mV\n",
ind, dacval);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
// vchip
if (ind == D_PWR_CHIP) {
if (ConvertToDifferentRange(
LTC2620_GetMaxInput(), LTC2620_GetMinInput(), VCHIP_MIN_MV,
VCHIP_MAX_MV, dacval, retval_voltage) == FAIL) {
sprintf(mess,
"Could not get DAC %d (vchip). Could not convert %d dac "
"units to mV\n",
ind, dacval);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
// power dacs
if (ConvertToDifferentRange(LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
POWER_RGLTR_MIN, POWER_RGLTR_MAX, dacval,
retval_voltage) == FAIL) {
if (LTC2620_DacToVoltage(dacval, retval_voltage) == FAIL) {
sprintf(mess,
"Could not get DAC %d. Could not convert %d dac units to mV\n",
ind, dacval);
(int)ind, dacval);
LOG(logERROR, (mess));
return FAIL;
}
@@ -1397,7 +1356,7 @@ int getDAC(enum DACINDEX ind, bool mV, int *retval, char *mess) {
}
if (mV) {
if (convertDACValueToVoltage(ind, dacval, retval, mess) == FAIL)
if (convertDACToVoltage(ind, dacval, retval, mess) == FAIL)
return FAIL;
return OK;
}
@@ -1414,40 +1373,318 @@ int setDAC(enum DACINDEX ind, int val, bool mV, char *mess) {
int dacval = val;
if (mV) {
if (ind < NDAC_ONLY) {
if (validateDACVoltage(ind, val, mess) == FAIL)
return FAIL;
}
if (convertVoltageToDACValue(ind, val, &dacval, mess) == FAIL)
return FAIL;
}
{
char dacName[20] = {0};
snprintf(dacName, sizeof(dacName), "dac %d", ind);
if (LTC2620_SetDacValue((int)ind, dacval, dacName, mess) == FAIL)
if (validateDACVoltage(ind, val, mess) == FAIL)
return FAIL;
if (convertVoltageToDAC(ind, val, &dacval, mess) == FAIL)
return FAIL;
}
char dacName[20] = {0};
snprintf(dacName, sizeof(dacName), "dac %d", ind);
if (LTC2620_SetDacValue((int)ind, dacval, dacName, mess) == FAIL)
return FAIL;
dacValues[ind] = dacval;
return OK;
}
int getVLimit() { return vLimit; }
int setVLimit(int val, char *mess) {
if (val < 0) {
sprintf(mess, "Could not set vlimit. Invalid value %d\n", val);
int validatePowerDACIndex(enum powerIndex ind, char *mess) {
if (ind < 0 || ind > V_POWER_IO) {
sprintf(mess, "Could not set/get Power DAC. Invalid index %d\n", ind);
LOG(logERROR, (mess));
return FAIL;
}
vLimit = val;
return OK;
}
int validateVchip(int val, char *mess) {
if (val < VCHIP_MIN_MV || val > VCHIP_MAX_MV) {
int validatePower(enum powerIndex ind, int voltage, char *mess) {
char *powerNames[] = {PWR_NAMES};
// validate min value
int min = (ind == V_POWER_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
if (voltage < min && voltage != 0) {
sprintf(
mess,
"Could not set %s. Input value %d mV must be greater than %d mV.\n",
powerNames[ind], voltage, min);
LOG(logERROR, (mess));
return FAIL;
}
// validate max value
int max = (VCHIP_MAX_MV - VCHIP_POWER_INCRMNT);
if (voltage > max) {
sprintf(
mess,
"Could not set %s. Input value %d mV must be less than %d mV.\n",
powerNames[ind], voltage, max);
LOG(logERROR, (mess));
return FAIL;
}
// validate vlimit
if (vLimit > 0 && voltage > vLimit) {
sprintf(mess, "Could not set %s. Input %d mV exceeds vLimit %d mV\n",
powerNames[ind], voltage, vLimit);
LOG(logERROR, (mess))
return FAIL;
}
return OK;
}
int convertVoltageToPowerDAC(enum powerIndex ind, int voltage,
int *retval_dacval, char *mess) {
*retval_dacval = -1;
if (ConvertToDifferentRange(POWER_RGLTR_MIN, POWER_RGLTR_MAX,
LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
voltage, retval_dacval) == FAIL) {
char *powerNames[] = {PWR_NAMES};
sprintf(mess,
"Could not set %s. Could not convert %d mV to dac units.\n",
powerNames[ind], voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int convertPowerDACToVoltage(enum powerIndex ind, int dacval,
int *retval_voltage, char *mess) {
*retval_voltage = -1;
if (ConvertToDifferentRange(LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
POWER_RGLTR_MIN, POWER_RGLTR_MAX, dacval,
retval_voltage) == FAIL) {
char *powerNames[] = {PWR_NAMES};
sprintf(mess,
"Could not get %s. Could not convert %d dac units to mV\n",
powerNames[ind], dacval);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPowerDAC(enum powerIndex ind, int *retval, char *mess) {
if (ind == V_POWER_CHIP) {
return getVchip(retval, mess);
}
*retval = -1;
if (validatePowerDACIndex(ind, mess) == FAIL)
return FAIL;
int dacval = powerValues[ind];
if (convertPowerDACToVoltage(ind, dacval, retval, mess) == FAIL)
return FAIL;
return OK;
}
int setPowerDAC(enum powerIndex ind, int voltage, char *mess) {
if (ind == V_POWER_CHIP) {
snprintf(mess, MAX_STR_LENGTH,
"Cannot set power dac for vchip. It is automatically "
"controlled when setting the other power rails (+200mV from "
"highest power regulator voltage).\n");
LOG(logERROR, (mess));
return FAIL;
}
if (validatePowerDACIndex(ind, mess) == FAIL)
return FAIL;
char *powerNames[] = {PWR_NAMES};
LOG(logINFO, ("Setting DAC %s: %d mV\n", powerNames[ind], voltage));
if (validatePower(ind, voltage, mess) == FAIL)
return FAIL;
// to be values
bool pwrEnables[NPWR - 1] = {0};
int pwrValues[NPWR - 1] = {0};
if (getAllPowerValues(pwrEnables, pwrValues, mess) == FAIL)
return FAIL;
// update with current command
pwrValues[ind] = voltage;
// set vchip accordingly
{
int vchip = 0;
if (computeVchip(&vchip, pwrEnables, pwrValues, mess) == FAIL)
return FAIL;
if (setVchip(vchip, mess) == FAIL)
return FAIL;
}
int dacval = -1;
if (convertVoltageToPowerDAC(ind, voltage, &dacval, mess) == FAIL)
return FAIL;
{
enum DACINDEX dacIndex = D_PWR_IO;
if (getDACIndexForPower(ind, &dacIndex, mess) == FAIL) {
return FAIL;
}
if (LTC2620_SetDacValue(dacIndex, dacval, powerNames[ind], mess) ==
FAIL)
return FAIL;
}
powerValues[ind] = dacval;
return OK;
}
int getDACIndexForPower(enum powerIndex pind, enum DACINDEX *dacIndex,
char *mess) {
switch (pind) {
case V_POWER_IO:
*dacIndex = D_PWR_IO;
break;
case V_POWER_A:
*dacIndex = D_PWR_A;
break;
case V_POWER_B:
*dacIndex = D_PWR_B;
break;
case V_POWER_C:
*dacIndex = D_PWR_C;
break;
case V_POWER_D:
*dacIndex = D_PWR_D;
break;
default:
*dacIndex = -1;
sprintf(mess, "Power index %d has no corresponding dac index\n", pind);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPowerMask(enum powerIndex index, uint32_t *mask, char *mess) {
switch (index) {
case V_POWER_IO:
*mask |= POWER_ENBL_VIO_MSK;
break;
case V_POWER_A:
*mask |= POWER_ENBL_VA_MSK;
break;
case V_POWER_B:
*mask |= POWER_ENBL_VB_MSK;
break;
case V_POWER_C:
*mask |= POWER_ENBL_VC_MSK;
break;
case V_POWER_D:
*mask |= POWER_ENBL_VD_MSK;
break;
default:
sprintf(mess, "Index %d has no power rail index\n", index);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
void powerOff() {
LOG(logINFOBLUE, ("Powering OFF all rails\n"));
// cannot call setPowerRailEnabled because of vchip dependency
uint32_t mask = POWER_ENBL_VLTG_RGLTR_MSK;
bus_w(POWER_REG, bus_r(POWER_REG) & ~(mask));
}
int setPowerEnabled(enum powerIndex indices[], int count, bool enable,
char *mess) {
uint32_t mask = 0;
for (int i = 0; i != count; ++i) {
if (getPowerMask(indices[i], &mask, mess) == FAIL)
return FAIL;
}
// log message
{
char *powerNames[] = {PWR_NAMES};
char message[256] = {0};
sprintf(message, "Switching %s power for [", enable ? "on" : "off");
for (int i = 0; i != count; ++i) {
strcat(message, powerNames[indices[i]]);
strcat(message, ", ");
}
strcat(message, "]\n");
LOG(logINFO, ("%s", message));
}
// to be values
bool pwrEnables[NPWR - 1] = {0};
int pwrValues[NPWR - 1] = {0};
if (getAllPowerValues(pwrEnables, pwrValues, mess) == FAIL)
return FAIL;
// update with current command
for (int i = 0; i != count; ++i) {
pwrEnables[indices[i]] = enable;
}
// set vchip accordingly
{
int vchip = 0;
if (computeVchip(&vchip, pwrEnables, pwrValues, mess) == FAIL)
return FAIL;
if (setVchip(vchip, mess) == FAIL)
return FAIL;
}
// enable/disable power rails
uint32_t addr = POWER_REG;
if (enable) {
bus_w(addr, bus_r(addr) | mask);
} else {
bus_w(addr, bus_r(addr) & ~(mask));
}
return OK;
}
int isPowerEnabled(enum powerIndex ind, bool *retval, char *mess) {
uint32_t mask = 0;
if (getPowerMask(ind, &mask, mess) == FAIL)
return FAIL;
*retval = (bus_r(POWER_REG) & mask) != 0;
LOG(logDEBUG1, ("get power %d:%d\n", ind, *retval));
return OK;
}
int validateVchip(int voltage, char *mess) {
if (voltage < VCHIP_MIN_MV || voltage > VCHIP_MAX_MV) {
sprintf(mess,
"Invalid vchip value %d mV. Must be between %d and %d mV\n",
val, VCHIP_MIN_MV, VCHIP_MAX_MV);
voltage, VCHIP_MIN_MV, VCHIP_MAX_MV);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int convertVchipDACToVoltage(int dacval, int *retval_voltage, char *mess) {
*retval_voltage = -1;
if (ConvertToDifferentRange(LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
VCHIP_MIN_MV, VCHIP_MAX_MV, dacval,
retval_voltage) == FAIL) {
sprintf(mess,
"Could not get vchip. Could not convert %d dac units to mV\n",
dacval);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int convertVoltageToVchipDAC(int voltage, int *retval_dacval, char *mess) {
*retval_dacval = -1;
if (ConvertToDifferentRange(VCHIP_MIN_MV, VCHIP_MAX_MV,
LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
voltage, retval_dacval) == FAIL) {
sprintf(mess,
"Could not set vchip. Could not convert %d mV to dac units.\n",
voltage);
LOG(logERROR, (mess));
return FAIL;
}
@@ -1455,38 +1692,53 @@ int validateVchip(int val, char *mess) {
}
int getVchip(int *retval, char *mess) {
if (getDAC(D_PWR_CHIP, true, retval, mess) == FAIL)
*retval = -1;
int dacval = powerValues[V_POWER_CHIP];
if (convertVchipDACToVoltage(dacval, retval, mess) == FAIL)
return FAIL;
LOG(logDEBUG1, ("Vchip: %d\n", *retval));
return OK;
}
int setVchip(int val, char *mess) {
LOG(logINFOBLUE, ("Setting Vchip to %d mV\n", val));
if (validateVchip(val, mess) == FAIL)
int setVchip(int voltage, char *mess) {
LOG(logDEBUG, ("\tSetting Vchip to %d mV\n", voltage));
if (validateVchip(voltage, mess) == FAIL)
return FAIL;
if (setDAC(D_PWR_CHIP, val, true, mess) == FAIL)
int dacval = -1;
if (convertVoltageToVchipDAC(voltage, &dacval, mess) == FAIL)
return FAIL;
{
int dacIndex = D_PWR_CHIP;
char dacName[20] = {0};
snprintf(dacName, sizeof(dacName), "vchip");
if (LTC2620_SetDacValue(dacIndex, dacval, dacName, mess) == FAIL)
return FAIL;
}
powerValues[V_POWER_CHIP] = dacval;
return OK;
}
int getVchipToSet(enum DACINDEX ind, int pwr_val, int *retval_vchip,
char *mess) {
int getAllPowerValues(bool *pwrEnables, int *pwrValues, char *mess) {
for (int ipwr = 0; ipwr != (NPWR - 1); ++ipwr) {
if (isPowerEnabled((enum powerIndex)ipwr, &pwrEnables[ipwr], mess) ==
FAIL)
return FAIL;
if (getPowerDAC((enum powerIndex)ipwr, &pwrValues[ipwr], mess) == FAIL)
return FAIL;
}
return OK;
}
int computeVchip(int *retval_vchip, bool *pwrEnables, int *pwrValues,
char *mess) {
// get the max of all the power regulators
int max = 0;
for (int ipwr = NDAC_ONLY; ipwr <= NDAC; ++ipwr) {
if (ipwr == D_PWR_CHIP)
continue;
for (int ipwr = 0; ipwr != 5; ++ipwr) {
int val = 0;
// current index, use the value to be set
if (ipwr == (int)ind) {
val = pwr_val;
} else {
if (getPower(ind, &val, mess) == FAIL)
return FAIL;
}
if (pwrEnables[ipwr])
val = pwrValues[ipwr];
if (val > max)
max = val;
}
@@ -1498,14 +1750,10 @@ int getVchipToSet(enum DACINDEX ind, int pwr_val, int *retval_vchip,
retval = VCHIP_MIN_MV;
// max checked earlier, should not happen
if (retval > VCHIP_MAX_MV) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
return FAIL;
char *powerNames[] = {PWR_NAMES};
sprintf(
mess,
"Could not set %s. Vchip value to set %d is beyond itsmaximum %d\n",
powerNames[pwrIndex], retval, VCHIP_MAX_MV);
sprintf(mess,
"Could not set power enable. Vchip value to set %d is beyond "
"its maximum %d\n",
retval, VCHIP_MAX_MV);
LOG(logERROR, (mess));
return FAIL;
}
@@ -1515,209 +1763,60 @@ int getVchipToSet(enum DACINDEX ind, int pwr_val, int *retval_vchip,
return OK;
}
int validatePower(enum PWRINDEX ind, int val, char *mess) {
char *powerNames[] = {PWR_NAMES};
// validate min value
int min = (ind == PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
if (val < min && val != 0) {
sprintf(
mess,
"Could not set %s. Input value %d mV must be greater than %d mV.\n",
powerNames[ind], val, min);
LOG(logERROR, (mess));
return FAIL;
}
// validate max value
int max = (VCHIP_MAX_MV - VCHIP_POWER_INCRMNT);
if (val > max) {
sprintf(
mess,
"Could not set %s. Input value %d mV must be less than %d mV.\n",
powerNames[ind], val, max);
LOG(logERROR, (mess));
return FAIL;
}
// validate vlimit
if (vLimit > 0 && val > vLimit) {
sprintf(mess, "Could not set %s. Input %d mV exceeds vLimit %d mV\n",
powerNames[ind], val, vLimit);
LOG(logERROR, (mess))
return FAIL;
}
return OK;
}
int getPowerADC(enum powerIndex index, int *retval, char *mess) {
*retval = -1;
// for power rail index and name debugging
int getPowerIndexFromDACIndex(enum DACINDEX ind, enum PWRINDEX *pwrIndex,
char *mess) {
*pwrIndex = PWR_IO;
switch (ind) {
case D_PWR_IO:
*pwrIndex = PWR_IO;
enum ADCINDEX adcIndex = V_PWR_IO;
switch (index) {
case V_POWER_A:
case I_POWER_A:
adcIndex = V_PWR_A;
break;
case D_PWR_A:
*pwrIndex = PWR_A;
case V_POWER_B:
case I_POWER_B:
adcIndex = V_PWR_B;
break;
case D_PWR_B:
*pwrIndex = PWR_B;
case V_POWER_C:
case I_POWER_C:
adcIndex = V_PWR_C;
break;
case D_PWR_C:
*pwrIndex = PWR_C;
case V_POWER_D:
case I_POWER_D:
adcIndex = V_PWR_D;
break;
case D_PWR_D:
*pwrIndex = PWR_D;
case V_POWER_IO:
case I_POWER_IO:
adcIndex = V_PWR_IO;
break;
default:
sprintf(mess, "Index %d has no power index\n", ind);
sprintf(mess, "Could not get Power ADC. Invalid index %d\n", index);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPowerRailMask(enum PWRINDEX ind, uint32_t *mask, char *mess) {
*mask = 0;
switch (ind) {
case PWR_IO:
*mask = POWER_ENBL_VIO_MSK;
break;
case PWR_A:
*mask = POWER_ENBL_VA_MSK;
break;
case PWR_B:
*mask = POWER_ENBL_VB_MSK;
break;
case PWR_C:
*mask = POWER_ENBL_VC_MSK;
break;
case PWR_D:
*mask = POWER_ENBL_VD_MSK;
break;
default:
sprintf(mess, "Index %d has no power rail index\n", ind);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int EnablePowerRail(enum PWRINDEX ind, char *mess) {
char *powerNames[] = {PWR_NAMES};
uint32_t addr = POWER_REG;
uint32_t mask = 0;
if (getPowerRailMask(ind, &mask, mess) == FAIL)
return FAIL;
LOG(logINFO, ("\tSwitching on power for %s\n", powerNames[ind]));
bus_w(addr, bus_r(addr) | mask);
return OK;
}
int DisablePowerRail(enum PWRINDEX ind, char *mess) {
char *powerNames[] = {PWR_NAMES};
uint32_t addr = POWER_REG;
uint32_t mask = 0;
if (getPowerRailMask(ind, &mask, mess) == FAIL)
return FAIL;
LOG(logINFO, ("\tSwitching off power for %s\n", powerNames[ind]));
bus_w(addr, bus_r(addr) & ~(mask));
return OK;
}
int getPowerRail(enum PWRINDEX ind, int *retval, char *mess) {
char *powerNames[] = {PWR_NAMES};
uint32_t addr = POWER_REG;
uint32_t mask = 0;
if (getPowerRailMask(ind, &mask, mess) == FAIL)
return FAIL;
*retval = (bus_r(addr) & mask);
LOG(logDEBUG1, ("Power rail retval for %s: %s\n", powerNames[ind],
((*retval > 0) ? "Enabled" : "Disabled")));
return OK;
}
int getPower(enum DACINDEX ind, int *retval, char *mess) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
return FAIL;
// if powered off, return 0
if (getPowerRail(pwrIndex, retval, mess) == FAIL)
return FAIL;
if (*retval == 0) {
#ifdef VIRTUAL
return 0;
#endif
int deviceId = I2C_POWER_VIO_DEVICE_ID + (int)adcIndex;
// adc voltage
if (index < I_POWER_A) {
LOG(logDEBUG1, ("Reading I2C Voltage for device Id: %d\n", deviceId));
*retval = INA226_ReadVoltage(deviceId);
return OK;
}
if (getDAC(ind, true, retval, mess) == FAIL)
return FAIL;
// adc current
LOG(logDEBUG1, ("Reading I2C Current for device Id: %d\n", deviceId));
*retval = INA226_ReadCurrent(deviceId);
return OK;
}
int setPower(enum DACINDEX ind, int val, char *mess) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
return FAIL;
char *powerNames[] = {PWR_NAMES};
LOG(logINFOBLUE, ("Setting %s to %d mV\n", powerNames[pwrIndex], val));
if (validatePower(pwrIndex, val, mess) == FAIL)
return FAIL;
// compute vchip to set before powering off
int vchip = 0;
if (getVchipToSet(ind, val, &vchip, mess) == FAIL)
return FAIL;
if (DisablePowerRail(pwrIndex, mess) == FAIL)
return FAIL;
if (setVchip(vchip, mess) == FAIL)
return FAIL;
if (val != 0) {
if (setDAC(ind, val, true, mess) == FAIL)
return FAIL;
if (EnablePowerRail(pwrIndex, mess) == FAIL)
return FAIL;
}
return OK;
}
void powerOff() {
uint32_t addr = POWER_REG;
LOG(logINFO, ("Powering off all voltage regulators\n"));
bus_w(addr, bus_r(addr) & (~POWER_ENBL_VLTG_RGLTR_MSK));
}
int getADC(enum ADCINDEX ind) {
#ifdef VIRTUAL
return 0;
#endif
switch (ind) {
case V_PWR_IO:
case V_PWR_A:
case V_PWR_B:
case V_PWR_C:
case V_PWR_D:
LOG(logDEBUG1, ("Reading I2C Voltage for device Id: %d\n", (int)ind));
return INA226_ReadVoltage(I2C_POWER_VIO_DEVICE_ID + (int)ind);
case I_PWR_IO:
case I_PWR_A:
case I_PWR_B:
case I_PWR_C:
case I_PWR_D:
LOG(logDEBUG1, ("Reading I2C Current for device Id: %d\n", (int)ind));
return INA226_ReadCurrent(I2C_POWER_VIO_DEVICE_ID +
(int)(ind - I_PWR_IO));
// slow adcs
case S_TMP:
LOG(logDEBUG1, ("Reading Slow ADC Temperature\n"));
@@ -124,38 +124,50 @@ enum detectorSettings getSettings();
// parameters - threshold
// parameters - dac, adc, hv
int setADCVpp(int val, int mV, char *mess);
int getADCVpp(int mV, int *retval, char *mess);
int getVLimit();
int setVLimit(int val, char *mess);
int validateDACIndex(enum DACINDEX ind, char *mess);
int validateDACVoltage(enum DACINDEX ind, int voltage, char *mess);
int convertVoltageToDACValue(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess);
int convertDACValueToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess);
int convertVoltageToDAC(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess);
int convertDACToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess);
int getDAC(enum DACINDEX ind, bool mV, int *retval, char *mess);
/** @param val value can be in mV or dac units */
int setDAC(enum DACINDEX ind, int val, bool mV, char *mess);
int getVLimit();
int setVLimit(int val, char *mess);
int setADCVpp(int val, int mV, char *mess);
int getADCVpp(int mV, int *retval, char *mess);
int validatePowerDACIndex(enum powerIndex ind, char *mess);
int validatePower(enum powerIndex ind, int val, char *mess);
int convertVoltageToPowerDAC(enum powerIndex ind, int voltage,
int *retval_dacval, char *mess);
int convertPowerDACToVoltage(enum powerIndex ind, int dacval,
int *retval_voltage, char *mess);
int getPowerDAC(enum powerIndex ind, int *retval, char *mess);
int setPowerDAC(enum powerIndex ind, int voltage, char *mess);
int getDACIndexForPower(enum powerIndex pind, enum DACINDEX *dacIndex,
char *mess);
int getPowerMask(enum powerIndex ind, uint32_t *mask, char *mess);
void powerOff();
int setPowerEnabled(enum powerIndex indices[], int count, bool enable,
char *mess);
int isPowerEnabled(enum powerIndex ind, bool *retval, char *mess);
int validateVchip(int val, char *mess);
int getVchip(int *retval, char *mess);
int setVchip(int val, char *mess);
int getVchipToSet(enum DACINDEX ind, int pwr_val, int *retval_vchip,
char *mess);
int getAllPowerValues(bool *pwrEnable, int *pwrValues, char *mess);
/** pwrEnable and pwrValues are current values
* updated with the current command
* (current cmd: eg. power enable all or only set one power dac) */
int computeVchip(int *retval_vchip, bool *pwrEnable, int *pwrValues,
char *mess);
int validatePower(enum PWRINDEX ind, int val, char *mess);
int getPowerIndexFromDACIndex(enum DACINDEX ind, enum PWRINDEX *pwrIndex,
char *mess);
int getPowerRailMask(enum PWRINDEX ind, uint32_t *mask, char *mess);
int EnablePowerRail(enum PWRINDEX ind, char *mess);
int DisablePowerRail(enum PWRINDEX ind, char *mess);
int getPowerRail(enum PWRINDEX ind, int *retval, char *mess);
int getPower(enum DACINDEX ind, int *retval, char *mess);
int setPower(enum DACINDEX ind, int val, char *mess);
void powerOff();
int getPowerADC(enum powerIndex index, int *retval, char *mess);
int getADC(enum ADCINDEX ind);
int getSlowADC(int ichan);
@@ -47,7 +47,7 @@
#define DEFAULT_PERIOD (1 * 1000 * 1000) // ns
#define DEFAULT_DELAY (0)
#define DEFAULT_HIGH_VOLTAGE (0)
#define DEFAULT_VLIMIT (-100)
#define DEFAULT_VLIMIT (0)
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
#define DEFAULT_TX_UDP_PORT (0x7e9a)
#define DEFAULT_RUN_CLK (80000000) // 80
@@ -174,8 +174,7 @@ enum DACINDEX {
D_PWR_IO
};
enum PWRINDEX { PWR_IO, PWR_A, PWR_B, PWR_C, PWR_D };
#define PWR_NAMES "VIO", "VA", "VB", "VC", "VD"
#define PWR_NAMES "VA", "VB", "VC", "VD", "VIO"
enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS };
#define CLK_NAMES "run", "adc", "sync", "dbit"
@@ -302,8 +302,8 @@ u_int64_t getDetectorMAC() {
char output[255];
#ifdef VIRTUAL
FILE *sysFile =
popen("cat /sys/class/net/$(ip route show default | grep -v vpn | awk "
"'/default/ {print $5}')/address",
popen("ip link show $(ip route show default | grep -v vpn | awk "
"'/default/ {print $5}') | grep link/ether | awk '{print $2}'",
"r");
#else
FILE *sysFile = popen("more /sys/class/net/eth0/address", "r");
@@ -497,7 +497,7 @@ void setupDetector() {
}
// power on chip
initError = powerChip(1, initErrorMessage);
initError = powerChip(true, initErrorMessage);
if (initError == FAIL)
return;
@@ -2352,7 +2352,7 @@ int checkDetectorType(char *mess) {
return OK;
}
int powerChip(int on, char *mess) {
int powerChip(bool on, char *mess) {
if (on) {
LOG(logINFO, ("Powering chip: on\n"));
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_PWR_CHIP_MSK);
@@ -153,7 +153,7 @@ int *getDetectorPosition();
// very detector specific
int checkDetectorType(char *mess);
int powerChip(int on, char *mess);
int powerChip(bool on, char *mess);
int getPowerChip();
int isChipConfigured();
int configureChip(char *mess);
@@ -122,3 +122,6 @@ uint32_t *Blackfin_getBaseAddress();
* Map FPGA
*/
int mapCSP0(void);
/** sleep for only usecs */
void usleep_bf(uint64_t i);
@@ -6,8 +6,9 @@
#include "sls/sls_detector_defs.h"
#include <stdbool.h>
#define GOODBYE (-200)
#define REBOOT (-400)
#define GOODBYE (-200)
#define REBOOT (-400)
#define BFIN_SPI_WAIT_uSECONDS 25
// initialization functions
int updateModeAllowedFunction(int file_des);
@@ -341,3 +342,10 @@ int get_pattern_wait_interval(int);
int set_pattern_wait_interval(int);
int spi_read(int);
int spi_write(int);
int get_power(int);
int set_power(int);
int get_power_dac(int);
int set_power_dac(int);
int get_power_adc(int);
int get_voltage_limit(int);
int set_voltage_limit(int);
@@ -250,7 +250,7 @@ int LTC2620_SetDacValue(int dacnum, int val, char *dacname, char *mess) {
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tSetting DAC %s [%d]: %d dac\n", dacname, dacnum, val));
LOG(logINFOBLUE, ("\tSetting DAC %s [%d]: %d dac\n", dacname, dacnum, val));
#ifndef VIRTUAL
LTC2620_SetDAC(dacnum, val);
#endif
@@ -86,7 +86,7 @@ int LTC2620_D_SetDacValue(int dacnum, int val, char *dacname, char *mess) {
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tSetting DAC %s [%d]: %d dac\n", dacname, dacnum, val));
LOG(logINFOBLUE, ("\tSetting DAC %s [%d]: %d dac\n", dacname, dacnum, val));
#ifdef VIRTUAL
return OK;
@@ -11,12 +11,13 @@
#include <sys/mman.h> // mmap
/* global variables */
const uint64_t BFIN_CYCLES_1uSECOND = 20;
u_int32_t *csp0base = 0;
#define CSP0 0x20200000
#define MEM_SIZE 0x100000
#ifdef JUNGFRAUD
extern void configureChip();
#endif
@@ -131,3 +132,11 @@ int mapCSP0(void) {
}
uint32_t *Blackfin_getBaseAddress() { return csp0base; }
// usleep is not viable on blackfin
void usleep_bf(uint64_t i) {
uint64_t j = i * BFIN_CYCLES_1uSECOND;
while (--j) {
asm volatile("");
}
}
@@ -523,6 +523,14 @@ void function_table() {
flist[F_SET_PATTERN_WAIT_INTERVAL] = &set_pattern_wait_interval;
flist[F_SPI_READ] = &spi_read;
flist[F_SPI_WRITE] = &spi_write;
flist[F_GET_POWER] = &get_power;
flist[F_SET_POWER] = &set_power;
flist[F_GET_POWER_DAC] = &get_power_dac;
flist[F_SET_POWER_DAC] = &set_power_dac;
flist[F_GET_POWER_ADC] = &get_power_adc;
flist[F_GET_VOLTAGE_LIMIT] = &get_voltage_limit;
flist[F_SET_VOLTAGE_LIMIT] = &set_voltage_limit;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
LOG(logERROR, ("The last detector function enum has reached its "
@@ -957,41 +965,6 @@ enum DACINDEX getDACIndex(enum dacIndex ind) {
case VISHAPER:
serverDacIndex = E_VISHAPER;
break;
#elif CHIPTESTBOARDD
case V_POWER_A:
serverDacIndex = D_PWR_A;
break;
case V_POWER_B:
serverDacIndex = D_PWR_B;
break;
case V_POWER_C:
serverDacIndex = D_PWR_C;
break;
case V_POWER_D:
serverDacIndex = D_PWR_D;
break;
case V_POWER_IO:
serverDacIndex = D_PWR_IO;
break;
case V_POWER_CHIP:
serverDacIndex = D_PWR_CHIP;
break;
#elif XILINX_CHIPTESTBOARDD
case V_POWER_A:
serverDacIndex = D_PWR_A;
break;
case V_POWER_B:
serverDacIndex = D_PWR_B;
break;
case V_POWER_C:
serverDacIndex = D_PWR_C;
break;
case V_POWER_D:
serverDacIndex = D_PWR_D;
break;
case V_POWER_IO:
serverDacIndex = D_PWR_IO;
break;
#elif MYTHEN3D
case VCASSH:
serverDacIndex = M_VCASSH;
@@ -1353,61 +1326,11 @@ int processDACEnums(enum dacIndex ind, int val, bool mV) {
ret = getHighVoltage(&retval, mess);
return retval;
case V_POWER_CHIP:
if (val != GET_FLAG) {
ret = FAIL;
sprintf(
mess,
"Can not set Vchip. Can only be set automatically in the "
"background (+200mV from highest power regulator voltage).\n");
LOG(logERROR, (mess));
return retval;
}
ret = getVchip(&retval, mess);
return retval;
case V_LIMIT:
if (val != GET_FLAG) {
if (!mV) {
ret = FAIL;
strcpy(mess, "Could not set vlimit. VLimit should be in "
"mV and not dac units.\n");
LOG(logERROR, (mess));
return retval;
}
ret = setVLimit(val, mess);
} else
retval = getVLimit();
return retval;
case V_POWER_A:
case V_POWER_B:
case V_POWER_C:
case V_POWER_D:
case V_POWER_IO:
serverDacIndex = getDACIndex(ind);
if (ret == FAIL)
return retval;
if (val != GET_FLAG) {
if (!mV) {
ret = FAIL;
sprintf(mess,
"Could not set power. Power regulator %d should be in "
"mV and not dac units.\n",
ind);
LOG(logERROR, (mess));
return retval;
}
ret = setPower(serverDacIndex, val, mess);
} else
ret = getPower(serverDacIndex, &retval, mess);
return retval;
// actual dacs
default:
serverDacIndex = getDACIndex(ind);
if (ret == FAIL)
return retval;
if (val != GET_FLAG)
ret = setDAC(serverDacIndex, val, mV, mess);
else
@@ -1420,57 +1343,16 @@ int processDACEnums(enum dacIndex ind, int val, bool mV) {
#if XILINX_CHIPTESTBOARDD
int processDACEnums(enum dacIndex ind, int val, bool mV) {
int retval = -1;
enum DACINDEX serverDacIndex = 0;
switch (ind) {
case V_LIMIT:
if (val != GET_FLAG) {
if (!mV) {
ret = FAIL;
strcpy(mess, "Could not set vlimit. VLimit should be in "
"mV and not dac units.\n");
LOG(logERROR, (mess));
return retval;
}
ret = setVLimit(val, mess);
} else
retval = getVLimit();
enum DACINDEX serverDacIndex = getDACIndex(ind);
if (ret == FAIL)
return retval;
case V_POWER_A:
case V_POWER_B:
case V_POWER_C:
case V_POWER_D:
case V_POWER_IO:
serverDacIndex = getDACIndex(ind);
if (ret == FAIL)
return retval;
if (val != GET_FLAG) {
if (!mV) {
ret = FAIL;
sprintf(mess,
"Could not set power. Power regulator %d should be in "
"mV and not dac units.\n",
ind);
LOG(logERROR, (mess));
return retval;
}
ret = setPower(serverDacIndex, val, mess);
} else
ret = getPower(serverDacIndex, &retval, mess);
return retval;
// actual dacs
default:
serverDacIndex = getDACIndex(ind);
if (ret == FAIL)
return retval;
if (val != GET_FLAG)
ret = setDAC(serverDacIndex, val, mV, mess);
else
ret = getDAC(serverDacIndex, mV, &retval, mess);
return retval;
}
if (val != GET_FLAG)
ret = setDAC(serverDacIndex, val, mV, mess);
else
ret = getDAC(serverDacIndex, mV, &retval, mess);
return retval;
}
#endif
@@ -1547,36 +1429,6 @@ int get_adc(int file_des) {
serverAdcIndex = TEMP_FPGAFEBR;
break;
#elif CHIPTESTBOARDD
case V_POWER_A:
serverAdcIndex = V_PWR_A;
break;
case V_POWER_B:
serverAdcIndex = V_PWR_B;
break;
case V_POWER_C:
serverAdcIndex = V_PWR_C;
break;
case V_POWER_D:
serverAdcIndex = V_PWR_D;
break;
case V_POWER_IO:
serverAdcIndex = V_PWR_IO;
break;
case I_POWER_A:
serverAdcIndex = I_PWR_A;
break;
case I_POWER_B:
serverAdcIndex = I_PWR_B;
break;
case I_POWER_C:
serverAdcIndex = I_PWR_C;
break;
case I_POWER_D:
serverAdcIndex = I_PWR_D;
break;
case I_POWER_IO:
serverAdcIndex = I_PWR_IO;
break;
case SLOW_ADC0:
serverAdcIndex = S_ADC0;
break;
@@ -1960,7 +1812,7 @@ int acquire(int blocking, int file_des) {
}
// only set
if (Server_VerifyLock() == OK) {
#if defined(XILINX_CHIPTESTBOARDD) || defined(GOTTHARD2D)
#if defined(GOTTHARD2D)
if (!isChipConfigured()) {
ret = FAIL;
strcpy(mess, "Could not start acquisition. Chip is not configured. "
@@ -4009,7 +3861,7 @@ int power_chip(int file_des) {
LOG(logDEBUG1, ("Powering chip to %d\n", arg));
#if !defined(JUNGFRAUD) && !defined(MOENCHD) && !defined(MYTHEN3D) && \
!defined(GOTTHARD2D) && !defined(XILINX_CHIPTESTBOARDD)
!defined(GOTTHARD2D)
functionNotImplemented();
#else
// set & get
@@ -4028,7 +3880,7 @@ int power_chip(int file_des) {
}
}
#endif
#if defined(XILINX_CHIPTESTBOARDD) || defined(GOTTHARD2D)
#if defined(GOTTHARD2D)
if (ret == OK) {
if (arg != -1) {
if (arg != 0 && arg != 1) {
@@ -4041,7 +3893,6 @@ int power_chip(int file_des) {
}
if (ret == OK) {
retval = getPowerChip();
LOG(logDEBUG1, ("Power chip: %d\n", retval));
validate(&ret, mess, arg, retval, "power on/off chip", DEC);
}
}
@@ -10853,17 +10704,9 @@ int config_transceiver(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#if !defined(XILINX_CHIPTESTBOARDD)
// currently not implemented anymore.
functionNotImplemented();
#else
if (Server_VerifyLock() == OK) {
LOG(logINFO, ("Configuring Transceiver\n"));
ret = configureTransceiver(mess);
if (ret == FAIL) {
LOG(logERROR, (mess));
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
@@ -11056,7 +10899,7 @@ int set_pattern_wait_interval(int file_des) {
*/
int spi_read(int file_des) {
#if !defined(XILINX_CHIPTESTBOARDD)
#if !defined(XILINX_CHIPTESTBOARDD) && !defined(CHIPTESTBOARDD)
functionNotImplemented();
return sendError(file_des);
#endif
@@ -11106,7 +10949,7 @@ int spi_read(int file_des) {
for (int i = 0; i < n_bytes; i++) {
fake_register[i] = (uint8_t)((i * 2) % 256);
}
#else
#elif defined(XILINX_CHIPTESTBOARDD)
int spifd = open("/dev/spidev2.0", O_RDWR);
LOG(logINFO, ("SPI Read: opened spidev2.0 with fd=%d\n", spifd));
if (spifd < 0) {
@@ -11115,7 +10958,7 @@ int spi_read(int file_des) {
}
#endif
// Allocate dummy data to shif in, we keep a copy of this
// Allocate dummy data to shift in, we keep a copy of this
// to double check that we access a register of the correct size
uint8_t *dummy_data = malloc(n_bytes);
if (dummy_data == NULL) {
@@ -11182,7 +11025,7 @@ int spi_read(int file_des) {
fake_register[i] = local_tx[i + 1];
}
#else
#elif defined(XILINX_CHIPTESTBOARDD)
// For the real detector we do the transfer here
if (ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd) < 0) {
// cleanup since we return early
@@ -11196,6 +11039,17 @@ int spi_read(int file_des) {
sprintf(mess, "SPI write failed with %d:%s\n", errno, strerror(errno));
return sendError(file_des);
}
#elif defined(CHIPTESTBOARDD)
// set spi to 8 bit per word (-1 comes from the firmware), set chipselect
bus_w(SPI_CTRL_REG,
((8 - 1) << SPI_CTRL_NBIT_OFST) + (1 << SPI_CTRL_CHIPSELECT_BIT));
for (int i = 0; i < n_bytes + 1; ++i) {
// TODO: should we make bus_w to this address blocking in the firmware
// to remove usleep ?
bus_w(SPI_WRITEDATA_REG, local_tx[i]);
usleep_bf(BFIN_SPI_WAIT_uSECONDS);
local_rx[i] = (uint8_t)bus_r(SPI_READDATA_REG);
}
#endif
// Copy everything but the first received byte to the user. First byte
@@ -11216,7 +11070,7 @@ int spi_read(int file_des) {
local_rx[i + 1] = fake_register[i];
}
free(fake_register); // we are done with the fake register
#else
#elif defined(XILINX_CHIPTESTBOARDD)
if (ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd) < 0) {
// cleanup since we return early
close(spifd);
@@ -11230,6 +11084,13 @@ int spi_read(int file_des) {
return sendError(file_des);
}
close(spifd);
#elif defined(CHIPTESTBOARDD)
for (int i = 0; i < n_bytes + 1; ++i) {
bus_w(SPI_WRITEDATA_REG, local_tx[i]);
usleep_bf(BFIN_SPI_WAIT_uSECONDS);
local_rx[i] = (uint8_t)bus_r(SPI_READDATA_REG);
}
bus_w(SPI_CTRL_REG, (8 - 1) << SPI_CTRL_NBIT_OFST); // remove chip-select
#endif
ret = OK;
LOG(logDEBUG1, ("SPI Read Complete\n"));
@@ -11247,7 +11108,7 @@ int spi_read(int file_des) {
* Write to SPI register.
*/
int spi_write(int file_des) {
#if !defined(XILINX_CHIPTESTBOARDD)
#if !defined(XILINX_CHIPTESTBOARDD) && !defined(CHIPTESTBOARDD)
functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0);
#endif
@@ -11328,7 +11189,7 @@ int spi_write(int file_des) {
for (int i = 0; i < n_bytes + 1; i++) {
local_rx[i] = local_tx[i];
}
#else
#elif defined(XILINX_CHIPTESTBOARDD)
int spifd = open("/dev/spidev2.0", O_RDWR);
LOG(logINFO, ("SPI Read: opened spidev2.0 with fd=%d\n", spifd));
if (spifd < 0) {
@@ -11347,6 +11208,16 @@ int spi_write(int file_des) {
return sendError(file_des);
}
close(spifd);
#elif defined(CHIPTESTBOARDD)
// set spi to 8 bit per word (-1 comes from firmware), set chip-select
bus_w(SPI_CTRL_REG,
((8 - 1) << SPI_CTRL_NBIT_OFST) + (1 << SPI_CTRL_CHIPSELECT_BIT));
for (int i = 0; i < n_bytes + 1; ++i) {
bus_w(SPI_WRITEDATA_REG, local_tx[i]);
usleep_bf(BFIN_SPI_WAIT_uSECONDS);
local_rx[i] = (uint8_t)bus_r(SPI_READDATA_REG);
}
bus_w(SPI_CTRL_REG, (8 - 1) << SPI_CTRL_NBIT_OFST); // remove chip-select
#endif
ret = OK;
@@ -11358,4 +11229,144 @@ int spi_write(int file_des) {
free(local_tx);
free(local_rx);
return ret;
}
}
int get_power(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented();
#else
// index
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Getting power enable for power %d\n", arg));
enum powerIndex index = (enum powerIndex)arg;
bool b_retval = false;
ret = isPowerEnabled(index, &b_retval, mess);
retval = (int)b_retval;
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_power(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented();
#else
int count = 0;
if (receiveData(file_des, &count, sizeof(count), INT32) < 0)
return printSocketReadError();
int args[count];
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
bool enable = (arg != 0);
LOG(logDEBUG1, ("Setting %d Power rails to %d\n", count, enable));
if (Server_VerifyLock() == OK) {
enum powerIndex indices[count];
for (int iPower = 0; iPower != count; ++iPower) {
indices[iPower] = (enum powerIndex)args[iPower];
}
ret = setPowerEnabled(indices, count, enable, mess);
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_power_dac(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented();
#else
// index
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Getting power DAC value for DAC %d\n", arg));
ret = getPowerDAC((enum powerIndex)arg, &retval, mess);
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_power_dac(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented();
#else
int args[2] = {-1, -1};
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
// index
enum powerIndex ind = (enum powerIndex)args[0];
int value = args[1];
LOG(logDEBUG1, ("Setting power DAC value for DAC %d to %d\n", ind, value));
if (Server_VerifyLock() == OK) {
ret = setPowerDAC(ind, value, mess);
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_power_adc(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
#if !defined(CHIPTESTBOARDD)
functionNotImplemented();
#else
// index
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Getting ADC value for ADC %d\n", arg));
ret = getPowerADC((enum powerIndex)arg, &retval, mess);
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int get_voltage_limit(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented();
#else
retval = getVLimit();
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_voltage_limit(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented();
#else
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Setting voltage limit to %d mV\n", arg));
if (Server_VerifyLock() == OK) {
ret = setVLimit(arg, mess);
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
@@ -41,11 +41,11 @@ char initErrorMessage[MAX_STR_LENGTH];
int detPos[2] = {0, 0};
uint32_t clkFrequency[NUM_CLOCKS] = {};
int chipConfigured = 0;
int analogEnable = 0;
int digitalEnable = 0;
int transceiverEnable = 0;
int dacValues[NDAC] = {};
int dacValues[NDAC_ONLY] = {};
int powerValues[NPWR - 1] = {}; // powerIndex (A->IO)
// software limit that depends on the current chip on the ctb
int vLimit = 0;
@@ -379,12 +379,13 @@ void setupDetector() {
clkFrequency[ADC_CLK] = DEFAULT_ADC_CLK;
clkFrequency[SYNC_CLK] = DEFAULT_SYNC_CLK;
clkFrequency[DBIT_CLK] = DEFAULT_DBIT_CLK;
chipConfigured = 0;
analogEnable = 0;
digitalEnable = 0;
transceiverEnable = 0;
for (int i = 0; i < NDAC; ++i)
for (int i = 0; i != NDAC_ONLY; ++i)
dacValues[i] = -1;
for (int i = 0; i != NPWR - 1; ++i)
powerValues[i] = -1;
vLimit = DEFAULT_VLIMIT;
#ifdef VIRTUAL
@@ -397,11 +398,8 @@ void setupDetector() {
if (initError == FAIL) {
return;
}
// power off chip
initError = powerChip(0, initErrorMessage);
if (initError == FAIL) {
return;
}
powerOff();
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC,
NPWR, DAC_POWERDOWN_DRIVER_FILE_NAME);
@@ -422,11 +420,9 @@ void setupDetector() {
// power regulators
LOG(logINFOBLUE,
("Setting power dacs to min dac value (power disabled)\n"));
for (int idac = NDAC_ONLY; idac < NDAC; ++idac) {
if (idac == D_PWR_EMPTY)
continue;
int min = (idac == D_PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
initError = setDAC(idac, min, true, initErrorMessage);
for (int iPower = 0; iPower != (NPWR - 1); ++iPower) {
int min = (iPower == (int)V_POWER_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
initError = setPowerDAC(iPower, min, initErrorMessage);
if (initError == FAIL)
return;
}
@@ -510,18 +506,6 @@ int waitTransceiverReset(char *mess) {
return OK;
}
#ifdef VIRTUAL
void setTransceiverAlignment(int align) {
if (align) {
bus_w(TRANSCEIVERSTATUS,
(bus_r(TRANSCEIVERSTATUS) | RXBYTEISALIGNED_MSK));
} else {
bus_w(TRANSCEIVERSTATUS,
(bus_r(TRANSCEIVERSTATUS) & ~RXBYTEISALIGNED_MSK));
}
}
#endif
int isTransceiverAligned() {
#ifdef VIRTUAL
return 1;
@@ -538,276 +522,6 @@ int isTransceiverAligned() {
return retval;
}
int waitTransceiverAligned(char *mess) {
#ifdef VIRTUAL
setTransceiverAlignment(1);
#else
// no module: transceiver will never get aligned
if (!checkModuleFlag) {
LOG(logWARNING, ("No module: Transceiver will never get aligned. "
"Ignoring alignment check.\n"));
return OK;
}
int transceiverWordAligned = isTransceiverAligned();
int times = 0;
while (transceiverWordAligned == 0) {
if (times++ > WAIT_TIME_OUT_0US_TIMES) {
sprintf(mess, "Transceiver alignment timed out. Check connection, "
"p-n inversions, LSB-MSB inversions, link error "
"counters and channel enable settings\n");
LOG(logERROR, (mess));
return FAIL;
}
usleep(0);
transceiverWordAligned = isTransceiverAligned();
}
#endif
LOG(logINFOBLUE, ("Transceiver alignment done\n"));
return OK;
}
int configureTransceiver(char *mess) {
LOG(logINFOBLUE, ("\tConfiguring transceiver\n"));
if (chipConfigured == 0) {
sprintf(mess,
"Chip not configured. Use powerchip to power on chip first.\n");
LOG(logERROR, (mess));
return FAIL;
}
return waitTransceiverAligned(mess);
}
int isChipConfigured() { return chipConfigured; }
// TODO powerchip and configurechip should be separate commands (not
// requirement) in the future
// TODO differentiate between power on board (va, vb, vc, vd, vio) and power
// chip (only chip with voltage vchip)?
int powerChip(int on, char *mess) {
uint32_t addr = CTRL_REG;
uint32_t mask = POWER_VIO_MSK | POWER_VCC_A_MSK | POWER_VCC_B_MSK |
POWER_VCC_C_MSK | POWER_VCC_D_MSK;
if (on) {
LOG(logINFOBLUE, ("Powering chip: on\n"));
bus_w(addr, bus_r(addr) | mask);
if (configureChip(mess) == FAIL)
return FAIL;
} else {
LOG(logINFOBLUE, ("Powering chip: off\n"));
bus_w(addr, bus_r(addr) & ~mask);
chipConfigured = 0;
}
return OK;
}
int getPowerChip() {
uint32_t addr = CTRL_REG;
uint32_t mask = POWER_VIO_MSK | POWER_VCC_A_MSK | POWER_VCC_B_MSK |
POWER_VCC_C_MSK | POWER_VCC_D_MSK;
return (((bus_r(addr) & mask) == mask) ? 1 : 0);
}
int configureChip(char *mess) {
LOG(logINFOBLUE, ("\tConfiguring chip\n"));
chipConfigured = 0;
if (readConfigFile(mess, CONFIG_CHIP_FILE, "chip config") == FAIL) {
return FAIL;
}
if (readConfigFile(mess, RESET_CHIP_FILE, "reset chip") == FAIL) {
return FAIL;
}
LOG(logINFOBLUE, ("Chip configured.\n"));
chipConfigured = 1;
return OK;
}
int readConfigFile(char *mess, char *fileName, char *fileType) {
const int fileNameSize = 128;
char fname[fileNameSize];
if (getAbsPath(fname, fileNameSize, fileName) == FAIL) {
sprintf(mess, "Could not get full path for %s file [%s].\n", fileType,
fname);
LOG(logERROR, (mess));
return FAIL;
}
if (access(fname, F_OK) != 0) {
sprintf(mess, "Could not find %s file [%s].\n", fileType, fname);
LOG(logERROR, (mess));
return FAIL;
}
FILE *fd = fopen(fname, "r");
if (fd == NULL) {
sprintf(mess, "Could not open on-board detector server %s file [%s].\n",
fileType, fname);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFOBLUE, ("Reading %s file %s\n", fileType, fname));
const size_t LZ = 256;
char line[LZ];
memset(line, 0, LZ);
char command[LZ];
// keep reading a line
while (fgets(line, LZ, fd)) {
// ignore comments
if (line[0] == '#') {
LOG(logDEBUG1, ("Ignoring Comment\n"));
continue;
}
// ignore empty lines
if (strlen(line) <= 1) {
LOG(logDEBUG1, ("Ignoring Empty line\n"));
continue;
}
// removing leading spaces
if (line[0] == ' ' || line[0] == '\t') {
int len = strlen(line);
// find first valid character
int i = 0;
for (i = 0; i < len; ++i) {
if (line[i] != ' ' && line[i] != '\t') {
break;
}
}
// ignore the line full of spaces (last char \n)
if (i >= len - 1) {
LOG(logDEBUG1, ("Ignoring line full of spaces\n"));
continue;
}
// copying only valid char
char temp[LZ];
memset(temp, 0, LZ);
memcpy(temp, line + i, strlen(line) - i);
memset(line, 0, LZ);
memcpy(line, temp, strlen(temp));
LOG(logDEBUG1, ("Removing leading spaces.\n"));
}
LOG(logDEBUG1, ("Command to process: (size:%d) %.*s\n", strlen(line),
strlen(line) - 1, line));
memset(command, 0, LZ);
// reg command
if (!strncmp(line, "reg", strlen("reg"))) {
uint32_t addr = 0;
uint32_t val = 0;
if (sscanf(line, "%s %x %x", command, &addr, &val) != 3) {
sprintf(mess, "Could not scan reg command. Line:[%s].\n", line);
LOG(logERROR, (mess));
return FAIL;
}
bus_w(addr, val);
LOG(logINFOBLUE, ("Wrote 0x%x to 0x%x\n", val, addr));
}
// setbit command
else if (!strncmp(line, "setbit", strlen("setbit"))) {
uint32_t addr = 0;
uint32_t bit = 0;
if (sscanf(line, "%s %x %d", command, &addr, &bit) != 3) {
sprintf(mess, "Could not scan setbit command. Line:[%s].\n",
line);
LOG(logERROR, (mess));
return FAIL;
}
bus_w(addr, bus_r(addr) | (1 << bit));
LOG(logINFOBLUE, ("Set bit %d in 0x%x\n", bit, addr));
}
// clearbit command
else if (!strncmp(line, "clearbit", strlen("clearbit"))) {
uint32_t addr = 0;
uint32_t bit = 0;
if (sscanf(line, "%s %x %d", command, &addr, &bit) != 3) {
sprintf(mess, "Could not scan clearbit command. Line:[%s].\n",
line);
LOG(logERROR, (mess));
return FAIL;
}
bus_w(addr, bus_r(addr) & ~(1 << bit));
LOG(logINFOBLUE, ("Cleared bit %d in 0x%x\n", bit, addr));
}
// pollbit command
else if (!strncmp(line, "pollbit", strlen("pollbit"))) {
uint32_t addr = 0;
uint32_t bit = 0;
uint32_t val = 0;
if (sscanf(line, "%s %x %d %d", command, &addr, &bit, &val) != 4) {
sprintf(mess, "Could not scan pollbit command. Line:[%s].\n",
line);
LOG(logERROR, (mess));
return FAIL;
}
#ifndef VIRTUAL
int times = 0;
while (((bus_r(addr) >> bit) & 0x1) != val) {
if (times++ > WAIT_TIME_OUT_0US_TIMES) {
sprintf(mess, "Polling bit %d in 0x%x timed out\n", bit,
addr);
LOG(logERROR, (mess));
return FAIL;
}
usleep(0);
}
#endif
LOG(logINFOBLUE, ("Polled bit %d in 0x%x\n", bit, addr));
}
// pattern command
else if (!strncmp(line, "pattern", strlen("pattern"))) {
// take a file name and call loadPatterFile
char patternFileName[LZ];
if (sscanf(line, "%s %s", command, patternFileName) != 2) {
sprintf(mess, "Could not scan pattern command. Line:[%s].\n",
line);
LOG(logERROR, (mess));
return FAIL;
}
if (loadPatternFile(patternFileName, mess) == FAIL) {
return FAIL;
}
LOG(logINFOBLUE, ("loaded pattern [%s].\n", patternFileName));
}
// sleep command
else if (!strncmp(line, "sleep", strlen("sleep"))) {
int time = 0;
if (sscanf(line, "%s %d", command, &time) != 2) {
sprintf(mess, "Could not scan sleep command. Line:[%s].\n",
line);
LOG(logERROR, (mess));
return FAIL;
}
usleep(time * 1000 * 1000);
LOG(logINFOBLUE, ("Slept for %d s\n", time));
}
// other commands
else {
sprintf(mess,
"Could not scan command from on-board server "
"%s file. Line:[%s].\n",
fileType, line);
break;
}
memset(line, 0, LZ);
}
fclose(fd);
LOG(logINFOBLUE, ("Successfully read %s file.\n", fileType));
return OK;
}
/* set parameters - dr */
int setDynamicRange(int dr) {
@@ -1147,8 +861,22 @@ int64_t getMeasurementTime() {
}
/* parameters - dac, adc, hv */
int getVLimit() { return vLimit; }
int setVLimit(int val, char *mess) {
if (val < 0) {
sprintf(mess, "Could not set vlimit. Invalid value %d\n", val);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("Setting vlimit to %d mV\n", val));
vLimit = val;
return OK;
}
int validateDACIndex(enum DACINDEX ind, char *mess) {
if (ind < 0 || ind >= NDAC) {
if (ind < 0 || ind >= NDAC_ONLY) {
sprintf(mess, "Could not set DAC. Invalid index %d\n", ind);
LOG(logERROR, (mess));
return FAIL;
@@ -1185,56 +913,26 @@ int validateDACVoltage(enum DACINDEX ind, int voltage, char *mess) {
return OK;
}
int convertVoltageToDACValue(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess) {
int convertVoltageToDAC(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess) {
*retval_dacval = -1;
// normal dacs
if (ind < NDAC_ONLY) {
if (LTC2620_D_VoltageToDac(voltage, retval_dacval) == FAIL) {
sprintf(
mess,
"Could not set DAC %d. Could not convert %d mV to dac units.\n",
ind, voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
// power dacs
if (ConvertToDifferentRange(
POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(),
LTC2620_D_GetMinInput(), voltage, retval_dacval) == FAIL) {
if (LTC2620_D_VoltageToDac(voltage, retval_dacval) == FAIL) {
sprintf(mess,
"Could not set DAC %d. Could not convert %d mV to dac units.\n",
ind, voltage);
(int)ind, voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int convertDACValueToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess) {
int convertDACToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess) {
*retval_voltage = -1;
// normal dacs
if (ind < NDAC_ONLY) {
if (LTC2620_D_DacToVoltage(dacval, retval_voltage) == FAIL) {
sprintf(
mess,
"Could not get DAC %d. Could not convert %d dac units to mV\n",
ind, dacval);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
// power dacs
if (ConvertToDifferentRange(
LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), POWER_RGLTR_MIN,
POWER_RGLTR_MAX, dacval, retval_voltage) == FAIL) {
if (LTC2620_D_DacToVoltage(dacval, retval_voltage) == FAIL) {
sprintf(mess,
"Could not get DAC %d. Could not convert %d dac units to mV\n",
ind, dacval);
(int)ind, dacval);
LOG(logERROR, (mess));
return FAIL;
}
@@ -1254,7 +952,7 @@ int getDAC(enum DACINDEX ind, bool mV, int *retval, char *mess) {
}
if (mV) {
if (convertDACValueToVoltage(ind, dacval, retval, mess) == FAIL)
if (convertDACToVoltage(ind, dacval, retval, mess) == FAIL)
return FAIL;
return OK;
}
@@ -1266,18 +964,19 @@ int getDAC(enum DACINDEX ind, bool mV, int *retval, char *mess) {
int setDAC(enum DACINDEX ind, int val, bool mV, char *mess) {
LOG(logINFO,
("Setting DAC %d: %d %s \n", ind, val, (mV ? "mV" : "dac units")));
if (validateDACIndex(ind, mess) == FAIL)
return FAIL;
int dacval = val;
if (mV) {
if (ind < NDAC_ONLY) {
if (validateDACVoltage(ind, val, mess) == FAIL)
return FAIL;
}
if (convertVoltageToDACValue(ind, val, &dacval, mess) == FAIL)
if (validateDACVoltage(ind, val, mess) == FAIL)
return FAIL;
if (convertVoltageToDAC(ind, val, &dacval, mess) == FAIL)
return FAIL;
}
{
char dacName[20] = {0};
snprintf(dacName, sizeof(dacName), "dac %d", ind);
@@ -1288,179 +987,216 @@ int setDAC(enum DACINDEX ind, int val, bool mV, char *mess) {
return OK;
}
int getVLimit() { return vLimit; }
int setVLimit(int val, char *mess) {
if (val < 0) {
sprintf(mess, "Could not set vlimit. Invalid value %d\n", val);
int validatePowerDACIndex(enum powerIndex ind, char *mess) {
if (ind < 0 || ind > V_POWER_IO) {
sprintf(mess, "Could not set Power DAC. Invalid index %d\n", ind);
LOG(logERROR, (mess));
return FAIL;
}
vLimit = val;
return OK;
}
int validatePower(enum PWRINDEX ind, int val, char *mess) {
int validatePower(enum powerIndex ind, int voltage, char *mess) {
char *powerNames[] = {PWR_NAMES};
// validate min value
int min = (ind == PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
if (val < min && val != 0) {
int min = (ind == V_POWER_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
if (voltage < min && voltage != 0) {
sprintf(
mess,
"Could not set %s. Input value %d mV must be greater than %d mV.\n",
powerNames[ind], val, min);
powerNames[ind], voltage, min);
LOG(logERROR, (mess));
return FAIL;
}
// validate max value
if (val > POWER_RGLTR_MAX) {
if (voltage > POWER_RGLTR_MAX) {
sprintf(
mess,
"Could not set %s. Input value %d mV must be less than %d mV.\n",
powerNames[ind], val, POWER_RGLTR_MAX);
powerNames[ind], voltage, POWER_RGLTR_MAX);
LOG(logERROR, (mess));
return FAIL;
}
// validate vlimit
if (vLimit > 0 && val > vLimit) {
if (vLimit > 0 && voltage > vLimit) {
sprintf(mess, "Could not set %s. Input %d mV exceeds vLimit %d mV\n",
powerNames[ind], val, vLimit);
powerNames[ind], voltage, vLimit);
LOG(logERROR, (mess))
return FAIL;
}
return OK;
}
// for power rail index and name debugging
int getPowerIndexFromDACIndex(enum DACINDEX ind, enum PWRINDEX *pwrIndex,
char *mess) {
*pwrIndex = PWR_IO;
switch (ind) {
case D_PWR_IO:
*pwrIndex = PWR_IO;
break;
case D_PWR_A:
*pwrIndex = PWR_A;
break;
case D_PWR_B:
*pwrIndex = PWR_B;
break;
case D_PWR_C:
*pwrIndex = PWR_C;
break;
case D_PWR_D:
*pwrIndex = PWR_D;
break;
default:
sprintf(mess, "Index %d has no power index\n", ind);
int convertVoltageToPowerDAC(enum powerIndex ind, int voltage,
int *retval_dacval, char *mess) {
*retval_dacval = -1;
if (ConvertToDifferentRange(
POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(),
LTC2620_D_GetMinInput(), voltage, retval_dacval) == FAIL) {
char *powerNames[] = {PWR_NAMES};
sprintf(mess,
"Could not set %s. Could not convert %d mV to dac units.\n",
powerNames[ind], voltage);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPowerRailMask(enum PWRINDEX ind, uint32_t *mask, char *mess) {
*mask = 0;
switch (ind) {
case PWR_IO:
*mask = POWER_VIO_MSK;
break;
case PWR_A:
*mask = POWER_VCC_A_MSK;
break;
case PWR_B:
*mask = POWER_VCC_B_MSK;
break;
case PWR_C:
*mask = POWER_VCC_C_MSK;
break;
case PWR_D:
*mask = POWER_VCC_D_MSK;
break;
default:
sprintf(mess, "Index %d has no power rail index\n", ind);
int convertPowerDACToVoltage(enum powerIndex ind, int dacval,
int *retval_voltage, char *mess) {
*retval_voltage = -1;
if (ConvertToDifferentRange(
LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), POWER_RGLTR_MIN,
POWER_RGLTR_MAX, dacval, retval_voltage) == FAIL) {
char *powerNames[] = {PWR_NAMES};
sprintf(mess,
"Could not get %s. Could not convert %d dac units to mV\n",
powerNames[ind], dacval);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int EnablePowerRail(enum PWRINDEX ind, char *mess) {
char *powerNames[] = {PWR_NAMES};
uint32_t addr = CTRL_REG;
uint32_t mask = 0;
if (getPowerRailMask(ind, &mask, mess) == FAIL)
int getPowerDAC(enum powerIndex ind, int *retval, char *mess) {
*retval = -1;
if (validatePowerDACIndex(ind, mess) == FAIL)
return FAIL;
LOG(logINFO, ("\tSwitching on power for %s\n", powerNames[ind]));
bus_w(addr, bus_r(addr) | mask);
return OK;
}
int DisablePowerRail(enum PWRINDEX ind, char *mess) {
char *powerNames[] = {PWR_NAMES};
uint32_t addr = CTRL_REG;
uint32_t mask = 0;
if (getPowerRailMask(ind, &mask, mess) == FAIL)
int dacval = powerValues[ind];
if (convertPowerDACToVoltage(ind, dacval, retval, mess) == FAIL)
return FAIL;
LOG(logINFO, ("\tSwitching off power for %s\n", powerNames[ind]));
bus_w(addr, bus_r(addr) & ~(mask));
return OK;
}
int getPowerRail(enum PWRINDEX ind, int *retval, char *mess) {
char *powerNames[] = {PWR_NAMES};
uint32_t addr = CTRL_REG;
uint32_t mask = 0;
if (getPowerRailMask(ind, &mask, mess) == FAIL)
return FAIL;
*retval = (bus_r(addr) & mask);
LOG(logDEBUG1, ("Power rail retval for %s: %s\n", powerNames[ind],
((*retval > 0) ? "Enabled" : "Disabled")));
return OK;
}
int getPower(enum DACINDEX ind, int *retval, char *mess) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
return FAIL;
// if powered off, return 0
if (getPowerRail(pwrIndex, retval, mess) == FAIL)
return FAIL;
if (*retval == 0) {
return OK;
}
if (getDAC(ind, true, retval, mess) == FAIL)
return FAIL;
return OK;
}
int setPower(enum DACINDEX ind, int val, char *mess) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
int setPowerDAC(enum powerIndex ind, int voltage, char *mess) {
if (validatePowerDACIndex(ind, mess) == FAIL)
return FAIL;
char *powerNames[] = {PWR_NAMES};
LOG(logINFOBLUE, ("Setting %s to %d mV\n", powerNames[pwrIndex], val));
LOG(logINFO, ("Setting DAC %s: %d mV\n", powerNames[ind], voltage));
if (validatePower(pwrIndex, val, mess) == FAIL)
if (validatePower(ind, voltage, mess) == FAIL)
return FAIL;
if (DisablePowerRail(pwrIndex, mess) == FAIL)
int dacval = -1;
if (convertVoltageToPowerDAC(ind, voltage, &dacval, mess) == FAIL)
return FAIL;
if (val != 0) {
if (setDAC(ind, val, true, mess) == FAIL)
{
enum DACINDEX dacIndex = D_PWR_IO;
if (getDACIndexForPower(ind, &dacIndex, mess) == FAIL) {
return FAIL;
if (EnablePowerRail(pwrIndex, mess) == FAIL)
}
if (LTC2620_D_SetDacValue(dacIndex, dacval, powerNames[ind], mess) ==
FAIL)
return FAIL;
}
powerValues[ind] = dacval;
return OK;
}
int getDACIndexForPower(enum powerIndex pind, enum DACINDEX *dacIndex,
char *mess) {
switch (pind) {
case V_POWER_IO:
*dacIndex = D_PWR_IO;
break;
case V_POWER_A:
*dacIndex = D_PWR_A;
break;
case V_POWER_B:
*dacIndex = D_PWR_B;
break;
case V_POWER_C:
*dacIndex = D_PWR_C;
break;
case V_POWER_D:
*dacIndex = D_PWR_D;
break;
default:
*dacIndex = -1;
sprintf(mess, "Power index %d has no corresponding dac index\n", pind);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPowerMask(enum powerIndex index, uint32_t *mask, char *mess) {
switch (index) {
case V_POWER_IO:
*mask |= POWER_VIO_MSK;
break;
case V_POWER_A:
*mask |= POWER_VCC_A_MSK;
break;
case V_POWER_B:
*mask |= POWER_VCC_B_MSK;
break;
case V_POWER_C:
*mask |= POWER_VCC_C_MSK;
break;
case V_POWER_D:
*mask |= POWER_VCC_D_MSK;
break;
default:
sprintf(mess, "Index %d has no power rail index\n", index);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
void powerOff() {
LOG(logINFOBLUE, ("Powering OFF all rails\n"));
uint32_t mask = POWER_VIO_MSK | POWER_VCC_A_MSK | POWER_VCC_B_MSK |
POWER_VCC_C_MSK | POWER_VCC_D_MSK;
bus_w(CTRL_REG, bus_r(CTRL_REG) & ~(mask));
}
int setPowerEnabled(enum powerIndex indices[], int count, bool enable,
char *mess) {
uint32_t mask = 0;
for (int i = 0; i != count; ++i) {
if (getPowerMask(indices[i], &mask, mess) == FAIL)
return FAIL;
}
// log message
{
char *powerNames[] = {PWR_NAMES};
char message[256] = {0};
sprintf(message, "Switching %s power for [", enable ? "on" : "off");
for (int i = 0; i != count; ++i) {
strcat(message, powerNames[indices[i]]);
strcat(message, ", ");
}
strcat(message, "]\n");
LOG(logINFO, ("%s", message));
}
// enable/disable power rails
uint32_t addr = CTRL_REG;
if (enable) {
bus_w(addr, bus_r(addr) | mask);
} else {
bus_w(addr, bus_r(addr) & ~(mask));
}
return OK;
}
int isPowerEnabled(enum powerIndex ind, bool *retval, char *mess) {
uint32_t mask = 0;
if (getPowerMask(ind, &mask, mess) == FAIL)
return FAIL;
*retval = (bus_r(CTRL_REG) & mask) != 0;
LOG(logDEBUG1, ("get power %d:%d\n", ind, *retval));
return OK;
}
@@ -63,18 +63,7 @@ void setupDetector();
void cleanFifos();
void resetFlow();
int waitTransceiverReset(char *mess);
#ifdef VIRTUAL
void setTransceiverAlignment(int align);
#endif
int isTransceiverAligned();
int waitTransceiverAligned(char *mess);
int configureTransceiver(char *mess);
int isChipConfigured();
int powerChip(int on, char *mess);
int getPowerChip();
int configureChip(char *mess);
int readConfigFile(char *mess, char *fileName, char *fileType);
int resetChip(char *mess);
// parameters - dr, roi
int setDynamicRange(int dr);
@@ -120,28 +109,35 @@ int64_t getMeasurementTime();
int setModule(sls_detector_module myMod, char *mess);
// parameters - dac, adc, hv
int getVLimit();
int setVLimit(int val, char *mess);
int validateDACIndex(enum DACINDEX ind, char *mess);
int validateDACVoltage(enum DACINDEX ind, int voltage, char *mess);
int convertVoltageToDACValue(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess);
int convertDACValueToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess);
int convertVoltageToDAC(enum DACINDEX ind, int voltage, int *retval_dacval,
char *mess);
int convertDACToVoltage(enum DACINDEX ind, int dacval, int *retval_voltage,
char *mess);
int getDAC(enum DACINDEX ind, bool mV, int *retval, char *mess);
/** @param val value can be in mV or dac units */
int setDAC(enum DACINDEX ind, int val, bool mV, char *mess);
int getVLimit();
int setVLimit(int val, char *mess);
int validatePowerDACIndex(enum powerIndex ind, char *mess);
int validatePower(enum powerIndex ind, int val, char *mess);
int convertVoltageToPowerDAC(enum powerIndex ind, int voltage,
int *retval_dacval, char *mess);
int convertPowerDACToVoltage(enum powerIndex ind, int dacval,
int *retval_voltage, char *mess);
int getPowerDAC(enum powerIndex ind, int *retval, char *mess);
int setPowerDAC(enum powerIndex ind, int voltage, char *mess);
int getDACIndexForPower(enum powerIndex pind, enum DACINDEX *dacIndex,
char *mess);
int validatePower(enum PWRINDEX ind, int val, char *mess);
int getPowerIndexFromDACIndex(enum DACINDEX ind, enum PWRINDEX *pwrIndex,
char *mess);
int getPowerRailMask(enum PWRINDEX ind, uint32_t *mask, char *mess);
int EnablePowerRail(enum PWRINDEX ind, char *mess);
int DisablePowerRail(enum PWRINDEX ind, char *mess);
int getPowerRail(enum PWRINDEX ind, int *retval, char *mess);
int getPower(enum DACINDEX ind, int *retval, char *mess);
int setPower(enum DACINDEX ind, int val, char *mess);
int getPowerMask(enum powerIndex ind, uint32_t *mask, char *mess);
void powerOff();
int setPowerEnabled(enum powerIndex indices[], int count, bool enable,
char *mess);
int isPowerEnabled(enum powerIndex ind, bool *retval, char *mess);
int getADC(enum ADCINDEX ind, int *value, char *mess);
int getSlowADC(int ichan, int *retval, char *mess);
@@ -56,7 +56,7 @@
#define DEFAULT_NUM_DSAMPLES (1)
#define DEFAULT_NUM_TSAMPLES (200)
#define DEFAULT_STARTING_FRAME_NUMBER (1)
#define DEFAULT_VLIMIT (-100)
#define DEFAULT_VLIMIT (0)
#define DEFAULT_DELAY (0)
#define MAX_TRANSCEIVER_MASK (0xF)
@@ -121,8 +121,7 @@ enum DACINDEX {
D_PWR_C
};
enum PWRINDEX { PWR_IO, PWR_A, PWR_B, PWR_C, PWR_D };
#define PWR_NAMES "VIO", "VA", "VB", "VC", "VD"
#define PWR_NAMES "VA", "VB", "VC", "VD", "VIO"
/* Struct Definitions */
// For arm has to be multiple of 16
+11
View File
@@ -5,6 +5,7 @@
#include "sls/Detector.h"
#include <iostream>
#include <optional>
#include <string>
#include <vector>
namespace sls {
@@ -67,6 +68,7 @@ class Caller {
private:
bool ReplaceIfDeprecated(std::string &command);
void SuggestIfRemoved(const std::string &command);
using FunctionMap = std::map<std::string, std::string (Caller::*)(int)>;
using StringMap = std::map<std::string, std::string>;
Detector *ptr; // pointer to the detector that executes the command
@@ -91,6 +93,9 @@ class Caller {
// applicable
RegisterAddress getRegisterAddress(const std::string &saddr) const;
BitAddress getBitAddress() const;
defs::dacIndex parseDacIndex(int argIndex, bool isCtb);
bool parseMV(int argIndex);
defs::powerIndex parsePowerIndex(int argIndex);
FunctionMap functions{
{"list", &Caller::list},
@@ -104,6 +109,12 @@ class Caller {
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (3)
};
StringMap removed_functions{
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (4)
};
};
} // namespace sls
@@ -80,7 +80,7 @@ _sd() {
local IS_PATH=0
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port power powerchip powerdac powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -524,21 +524,21 @@ __dac() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN="mV mv"
FCN_RETURN="0 1"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "4" ]]; then
FCN_RETURN="mV mv"
FCN_RETURN="0 1"
fi
fi
return 0
@@ -1843,6 +1843,10 @@ fi
fi
return 0
}
__power() {
FCN_RETURN=""
return 0
}
__powerchip() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
@@ -1852,6 +1856,23 @@ fi
fi
return 0
}
__powerdac() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__powerindex() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
@@ -1874,12 +1895,12 @@ __powername() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN="v_a v_b v_c v_chip v_d v_io"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN="v_a v_b v_c v_chip v_d v_io"
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
@@ -3117,60 +3138,6 @@ __user() {
FCN_RETURN=""
return 0
}
__v_a() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_b() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_c() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_chip() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_d() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_io() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_limit() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -4,7 +4,7 @@
_sd() {
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port power powerchip powerdac powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -448,21 +448,21 @@ __dac() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN="mV mv"
FCN_RETURN="0 1"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "4" ]]; then
FCN_RETURN="mV mv"
FCN_RETURN="0 1"
fi
fi
return 0
@@ -1767,6 +1767,10 @@ fi
fi
return 0
}
__power() {
FCN_RETURN=""
return 0
}
__powerchip() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
@@ -1776,6 +1780,23 @@ fi
fi
return 0
}
__powerdac() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__powerindex() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
@@ -1798,12 +1819,12 @@ __powername() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN="v_a v_b v_c v_chip v_d v_io"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
FCN_RETURN="v_a v_b v_c v_chip v_d v_io"
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
@@ -3041,60 +3062,6 @@ __user() {
FCN_RETURN=""
return 0
}
__v_a() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_b() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_c() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_chip() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_d() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_io() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__v_limit() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
+105 -203
View File
@@ -186,29 +186,6 @@ INTEGER_COMMAND_NOID:
input_types: [ int ]
output: [ 'args.front()' ]
INTEGER_IND_COMMAND:
template: true
infer_action: true
help: ""
actions:
GET:
# extra variable to store the index
require_det_id: true
function: ''
argc: 0
input: [ 'INDEX' ]
input_types: [ int ]
cast_input: [ false ]
output: [ OutString(t) ]
PUT:
# extra variable to store the index
function: ''
require_det_id: true
argc: 1
input: [ 'INDEX', 'args[0]' ]
input_types: [ int, int ]
cast_input: [ false, true ]
output: [ 'args.front()' ]
INTEGER_USER_IND_COMMAND:
template: true
@@ -306,6 +283,20 @@ GET_IND_COMMAND:
input_types: [ int ]
output: [ OutString(t) ]
GET_IND_COMMAND_NOID:
template: true
infer_action: true
help: ""
actions:
GET:
check_det_id: true
function: ''
argc: 0
input: [ 'VAL' ]
cast_input: [ false ]
input_types: [ int ]
output: [ OutString(t) ]
CTB_NAMED_LIST:
template: true
infer_action: true
@@ -345,10 +336,7 @@ CTB_SINGLE_DACNAME:
extra_variables:
- name: index
type: defs::dacIndex
value: 0
exceptions:
- condition: 'det->getDetectorType().squash(defs::GENERIC) != defs::CHIPTESTBOARD && det->getDetectorType().squash(defs::GENERIC) != defs::XILINX_CHIPTESTBOARD'
message: 'cmd + " only allowed for CTB."'
value: defs::DAC_0
check_det_id: true
argc: 1
input: [ "static_cast<defs::dacIndex>(StringTo<int>(args[0]) + index)" ]
@@ -359,10 +347,7 @@ CTB_SINGLE_DACNAME:
extra_variables:
- name: index
type: defs::dacIndex
value: 0
exceptions:
- condition: 'det->getDetectorType().squash(defs::GENERIC) != defs::CHIPTESTBOARD && det->getDetectorType().squash(defs::GENERIC) != defs::XILINX_CHIPTESTBOARD'
message: 'cmd + " only allowed for CTB."'
value: defs::DAC_0
check_det_id: true
argc: 2
input: [ "static_cast<defs::dacIndex>(StringTo<int>(args[0]) + index)","args[1]" ]
@@ -377,12 +362,8 @@ CTB_GET_DACINDEX:
extra_variables:
- name: index
type: defs::dacIndex
value: 0
value: defs::DAC_0
check_det_id: true
exceptions:
- condition: 'det->getDetectorType().squash(defs::GENERIC) != defs::CHIPTESTBOARD && det->getDetectorType().squash(defs::GENERIC) != defs::XILINX_CHIPTESTBOARD'
message: 'cmd + " only allowed for CTB."'
argc: 1
input: [ 'args[0]' ]
input_types: [ std::string ]
@@ -394,9 +375,6 @@ CTB_SINGLE_NAME:
actions:
GET:
check_det_id: true
exceptions:
- condition: 'det->getDetectorType().squash(defs::GENERIC) != defs::CHIPTESTBOARD && det->getDetectorType().squash(defs::GENERIC) != defs::XILINX_CHIPTESTBOARD'
message: 'cmd + " only allowed for CTB."'
argc: 1
input: [ "args[0]" ]
cast_input: [ true ]
@@ -404,9 +382,6 @@ CTB_SINGLE_NAME:
output: [ 'args[0]',"' '", 't' ]
PUT:
check_det_id: true
exceptions:
- condition: 'det->getDetectorType().squash(defs::GENERIC) != defs::CHIPTESTBOARD && det->getDetectorType().squash(defs::GENERIC) != defs::XILINX_CHIPTESTBOARD'
message: 'cmd + " only allowed for CTB."'
argc: 2
cast_input: [ true, false ]
input: [ "args[0]","args[1]" ]
@@ -419,9 +394,6 @@ CTB_GET_INDEX:
actions:
GET:
check_det_id: true
exceptions:
- condition: 'det->getDetectorType().squash(defs::GENERIC) != defs::CHIPTESTBOARD && det->getDetectorType().squash(defs::GENERIC) != defs::XILINX_CHIPTESTBOARD'
message: 'cmd + " only allowed for CTB."'
argc: 1
input: [ 'args[0]' ]
input_types: [ std::string ]
@@ -700,7 +672,7 @@ highvoltage:
function: setHighVoltage
powerchip:
help: "[0, 1]\n\t[Jungfrau][Moench][Mythen3][Gotthard2][Xilinx Ctb] Power the chip. \n\t[Jungfrau][Moench] Default is 0. Get will return power status. Can be off if temperature event occured (temperature over temp_threshold with temp_control enabled. Will configure chip (only chip v1.1)\n\t[Mythen3][Gotthard2] Default is 1. If module not connected or wrong module, powerchip will fail.\n\t[Xilinx Ctb] Default is 0. Also configures the chip if powered on."
help: "[0, 1]\n\t[Jungfrau][Moench][Mythen3][Gotthard2] Power the chip. \n\t[Jungfrau][Moench] Default is 0. Get will return power status. Can be off if temperature event occured (temperature over temp_threshold with temp_control enabled. Will configure chip (only chip v1.1)\n\t[Mythen3][Gotthard2] Default is 1. If module not connected or wrong module, powerchip will fail."
inherit_actions: INTEGER_COMMAND_VEC_ID
actions:
GET:
@@ -1565,83 +1537,15 @@ fmaster:
function: setMasterFileWrite
input_types: [ bool ]
################# INTEGER_IND_COMMAND #######################
v_limit:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Soft limit for power supplies (ctb only) and DACS in mV."
inherit_actions: INTEGER_COMMAND_NOID
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Soft limit for power supplies and DACS in mV."
actions:
GET:
function: getPower
input: [ 'defs::V_LIMIT' ]
function: getVoltageLimit
PUT:
function: setPower
input: [ 'defs::V_LIMIT', 'args[0]' ]
v_a:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Power supply a in mV."
actions:
GET:
function: getPower
input: [ 'defs::V_POWER_A' ]
PUT:
function: setPower
input: [ 'defs::V_POWER_A', 'args[0]' ]
v_b:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Power supply b in mV."
actions:
GET:
function: getPower
input: [ 'defs::V_POWER_B' ]
PUT:
function: setPower
input: [ 'defs::V_POWER_B', 'args[0]' ]
v_c:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Power supply c in mV."
actions:
GET:
function: getPower
input: [ 'defs::V_POWER_C' ]
PUT:
function: setPower
input: [ 'defs::V_POWER_C', 'args[0]' ]
v_d:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Power supply d in mV."
actions:
GET:
function: getPower
input: [ 'defs::V_POWER_D' ]
PUT:
function: setPower
input: [ 'defs::V_POWER_D', 'args[0]' ]
v_io:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb][Xilinx Ctb] Power supply io in mV. Minimum 1200 mV. Must be the first power regulator to be set after fpga reset (on-board detector server start up)."
actions:
GET:
function: getPower
input: [ 'defs::V_POWER_IO' ]
PUT:
function: setPower
input: [ 'defs::V_POWER_IO', 'args[0]' ]
v_chip:
inherit_actions: INTEGER_IND_COMMAND
help: "[n_value]\n\t[Ctb] Power supply chip in mV. Do not use it unless you are completely sure you will not fry the board."
actions:
GET:
function: getPower
input: [ 'defs::V_POWER_CHIP' ]
PUT:
function: setPower
input: [ 'defs::V_POWER_CHIP', 'args[0]' ]
function: setVoltageLimit
input_types: [ int ]
################# INTEGER_USER_IND_COMMAND ###################
vchip_comp_fe:
@@ -2179,85 +2083,99 @@ temp_slowadc:
input: [ 'defs::SLOW_ADC_TEMP' ]
output: [ OutString(t), '" °C"' ]
################# GET_IND_COMMAND_NOID #######################
vm_a:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured voltage of power supply a in mV."
actions:
GET:
function: getMeasuredPower
input: [ 'defs::V_POWER_A' ]
output: [ OutString(t), '" mV"' ]
vm_b:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured voltage of power supply b in mV."
actions:
GET:
function: getMeasuredPower
input: [ 'defs::V_POWER_B' ]
output: [ OutString(t), '" mV"' ]
vm_c:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured voltage of power supply c in mV."
actions:
GET:
function: getMeasuredPower
input: [ 'defs::V_POWER_C' ]
output: [ OutString(t), '" mV"' ]
vm_d:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured voltage of power supply d in mV."
actions:
GET:
function: getMeasuredPower
input: [ 'defs::V_POWER_D' ]
output: [ OutString(t), '" mV"' ]
vm_io:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured voltage of power supply io in mV."
actions:
GET:
function: getMeasuredPower
input: [ 'defs::V_POWER_IO' ]
output: [ OutString(t), '" mV"' ]
im_a:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured current of power supply a in mA."
actions:
GET:
function: getMeasuredCurrent
input: [ 'defs::I_POWER_A' ]
output: [ OutString(t), '" mA"' ]
im_b:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured current of power supply b in mA."
actions:
GET:
function: getMeasuredCurrent
input: [ 'defs::I_POWER_B' ]
output: [ OutString(t), '" mA"' ]
im_c:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured current of power supply c in mA."
actions:
GET:
function: getMeasuredCurrent
input: [ 'defs::I_POWER_C' ]
output: [ OutString(t), '" mA"' ]
im_d:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured current of power supply d in mA."
actions:
GET:
function: getMeasuredCurrent
input: [ 'defs::I_POWER_D' ]
output: [ OutString(t), '" mA"' ]
im_io:
inherit_actions: GET_IND_COMMAND
inherit_actions: GET_IND_COMMAND_NOID
help: "\n\t[Ctb] Measured current of power supply io in mA."
actions:
GET:
function: getMeasuredCurrent
input: [ 'defs::I_POWER_IO' ]
output: [ OutString(t), '" mA"' ]
################# CTB_NAMED_LIST #############################
daclist:
@@ -2306,17 +2224,6 @@ slowadclist:
function: setSlowADCNames
################# CTB_VALUES ################################
powervalues:
help: "[name] \n\t\t[Ctb][Xilinx_Ctb] Get values of all powers."
actions:
GET:
argc: 0
ctb_output_list:
GETFCNLIST: getPowerList
GETFCNNAME: getPowerNames
GETFCN: getPower
suffix: "mV"
printable_name: "*name_it++"
slowadcvalues:
help: "[name] \n\t\t[Ctb][Xilinx_Ctb] Get values of all slow adcs."
@@ -2361,21 +2268,24 @@ dacname:
value: defs::DAC_0
powername:
inherit_actions: CTB_SINGLE_DACNAME
help: "[0-4][name] \n\t\t[Ctb][Xilinx_Ctb] Set the power at the given position to the given name."
infer_action: true
actions:
GET:
argc: 1
check_det_id: true
function: getPowerName
extra_variables:
- name: index
type: defs::dacIndex
value: defs::V_POWER_A
input: [ 'static_cast<defs::powerIndex>(StringTo<int>(args[0]))' ]
input_types: [ defs::powerIndex ]
output: [ 'args[0]',"' '", 't' ]
PUT:
argc: 2
check_det_id: true
function: setPowerName
extra_variables:
- name: index
type: defs::dacIndex
value: defs::V_POWER_A
input: [ 'static_cast<defs::powerIndex>(StringTo<int>(args[0]))', 'args[1]' ]
input_types: [ defs::powerIndex, std::string ]
output: [ 'ToString(args)' ]
slowadcname:
inherit_actions: CTB_SINGLE_DACNAME
@@ -2412,10 +2322,7 @@ powerindex:
actions:
GET:
function: getPowerIndex
extra_variables:
- name: index
type: defs::dacIndex
value: defs::V_POWER_A
output: [ 'ToString(static_cast<int>(t))' ]
slowadcindex:
inherit_actions: CTB_GET_DACINDEX
@@ -2853,6 +2760,51 @@ clearbit:
arg_types: [ std::string, std::string, special::validate ]
dac:
is_description: true
actions:
PUT:
args:
- argc: 2
arg_types: [ std::string, int ]
- argc: 3
arg_types: [ std::string, int, bool ]
GET:
args:
- argc: 1
arg_types: [ std::string ]
- argc: 2
arg_types: [ std::string, bool ]
powerdac:
is_description: true
actions:
PUT:
argc: 2
arg_types: [ std::string, int ]
GET:
argc: 1
arg_types: [ std::string ]
power:
is_description: true
actions:
GET:
argc: 0
PUT:
argc: -1
arg_types: [ std::string ]
powervalues:
is_description: true
actions:
GET:
args:
- argc: 0
################# special commands ##########################
virtual:
@@ -3333,56 +3285,6 @@ extsig:
cast_input: [ true, true ]
output: [ 'args[0]', "' '", 'args[1]' ]
dac:
help: "code: return GetHelpDacWrapper(cmd, args);\n" # this is a special case
actions:
GET:
exceptions:
- condition: "is_int(args[0]) && det->getDetectorType().squash() != defs::CHIPTESTBOARD && det->getDetectorType().squash() != defs::XILINX_CHIPTESTBOARD"
message: '"Dac indices can only be used for chip test board. Use daclist to get list of dac names for current detector."'
extra_variables:
- name: dacIndex
type: defs::dacIndex
value: "((det->getDetectorType().squash() == defs::CHIPTESTBOARD || det->getDetectorType().squash() == defs::XILINX_CHIPTESTBOARD) && !is_int(args[0])) ? det->getDacIndex(args[0]) : StringTo<defs::dacIndex>(args[0])"
function: getDAC
require_det_id: true
input_types: [ defs::dacIndex, bool ]
cast_input: [ false, true ]
args:
- argc: 1
arg_types: [defs::dacIndex]
input: [ dacIndex, '"0"' ]
output: [ 'args[0]', "' '", OutString(t) ]
- argc: 2
exceptions:
- condition: "is_int(args[0]) && det->getDetectorType().squash() != defs::CHIPTESTBOARD && det->getDetectorType().squash() != defs::XILINX_CHIPTESTBOARD"
message: '"Dac indices can only be used for chip test board. Use daclist to get list of dac names for current detector."'
- condition: 'args[1] != "mv" && args[1] != "mV"'
message: '"Unknown argument " + args[1] + ". Did you mean mV?"'
arg_types: [defs::dacIndex, special::mv]
input: [ dacIndex, '"1"' ]
output: [ 'args[0]', "' '" , OutString(t), '" mV"' ]
PUT:
exceptions:
- condition: "is_int(args[0]) && det->getDetectorType().squash() != defs::CHIPTESTBOARD && det->getDetectorType().squash() != defs::XILINX_CHIPTESTBOARD"
message: '"Dac indices can only be used for chip test board. Use daclist to get list of dac names for current detector."'
extra_variables:
- name: dacIndex
type: defs::dacIndex
value: "((det->getDetectorType().squash() == defs::CHIPTESTBOARD || det->getDetectorType().squash() == defs::XILINX_CHIPTESTBOARD) && !is_int(args[0])) ? det->getDacIndex(args[0]) : StringTo<defs::dacIndex>(args[0])"
function: setDAC
require_det_id: true
input_types: [ defs::dacIndex, int, bool ]
cast_input: [ false, true, true ]
args:
- argc: 2
arg_types: [defs::dacIndex, int]
input: [ dacIndex, "args[1]", '"0"' ]
output: [ "args[0]", "' '", "args[1]" ]
- argc: 3
arg_types: [defs::dacIndex, int, special::mv]
input: [ dacIndex, "args[1]", '"1"' ]
output: [ "args[0]", "' '", "args[1]", '" mV"' ]
resetdacs:
help: "[(optional) hard] \n\t[Eiger][Jungfrau][Moench][Gotthard2][Mythen3]Reset dac values to the defaults. A 'hard' optional reset will reset the dacs to the hardcoded defaults in on-board detector server."
@@ -36,7 +36,7 @@ class CodeGenerator:
self.file.write(line)
self.template_file.close()
def write_header(self, in_path, out_path, commands, deprecated_commands):
def write_header(self, in_path, out_path, commands, deprecated_commands, removed_commands):
"""Write the header file for the caller.h file"""
with out_path.open('w') as fp:
with in_path.open('r') as fp2:
@@ -59,6 +59,11 @@ class CodeGenerator:
fp.write(f'{{"{key}", "{value}"}},\n')
continue
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (4)" in line:
for key, value in removed_commands.items():
fp.write(f'{{"{key}", "{value}"}},\n')
continue
fp.write(line)
def write_infer_header(self, in_path, out_path, commands):
@@ -94,6 +94,7 @@ vcasc_sfp: dac
vipre_cds: dac
ibias_sfp: dac
defaultdacs: resetdacs
#acquisition
File diff suppressed because it is too large Load Diff
@@ -14,6 +14,7 @@ GEN_PATH = Path(__file__).parent
COMMANDS_PATH = GEN_PATH / 'extended_commands.yaml'
DEPRECATED_COMMANDS_PATH = GEN_PATH / 'deprecated_commands.yaml'
REMOVED_COMMANDS_PATH = GEN_PATH / 'removed_commands.yaml'
CPP_INPUT_PATH = GEN_PATH / 'Caller.in.cpp'
HEADER_INPUT_PATH = GEN_PATH / 'Caller.in.h'
CPP_OUTPUT_PATH = GEN_PATH.parent / 'src' / 'Caller.cpp'
@@ -39,6 +40,8 @@ def generate(
):
commands_config = yaml.unsafe_load(commands_path.open('r'))
deprecated_commands_config = yaml.unsafe_load(DEPRECATED_COMMANDS_PATH.open('r'))
removed_commands_config = yaml.unsafe_load(REMOVED_COMMANDS_PATH.open('r'))
type_dist, non_dist = check_infer(commands=commands_config)
codegen.open(cpp_output_path)
@@ -167,7 +170,8 @@ def generate(
codegen.close()
print('[X] .cpp code generated')
deprecated_commands = []
codegen.write_header(header_input_path, header_output_path, commands_config, deprecated_commands_config)
removed_commands = []
codegen.write_header(header_input_path, header_output_path, commands_config, deprecated_commands_config, removed_commands_config)
print('[X] header code generated')
+1 -1
View File
@@ -9,7 +9,7 @@ If any changes to enums in slsDetectorDefs
```sh
# to generate the dump.json file
cd slsSupportLib/src
clang++ -Xclang -ast-dump=json -Xclang -ast-dump-filter -Xclang StringTo -c ToString.cpp -I ../include/ -std=gnu++11 > ../../slsDetectorSoftware/generator/autocomplete/dump.json
clang++ -Xclang -ast-dump=json -Xclang -ast-dump-filter -Xclang StringTo -c ToString.cpp -I ../include/ -std=gnu++17 > ../../slsDetectorSoftware/generator/autocomplete/dump.json
cd ../../slsDetectorSoftware/generator/autocomplete
python autocomplete.py -f
```
@@ -0,0 +1,6 @@
v_a: "'dac v_a' and 'power v_a'"
v_b: "'dac v_b' and 'power v_b'"
v_c: "'dac v_c' and 'power v_c'"
v_d: "'dac v_d' and 'power v_d'"
v_io: "'dac v_io' and 'power v_io'"
v_chip: "'dac v_chip'"
+43 -29
View File
@@ -474,17 +474,16 @@ class Detector {
*/
void setHighVoltage(int value, Positions pos = {});
/** [Jungfrau][Moench][Mythen3][Gotthard2][Xilinx Ctb] */
/** [Jungfrau][Moench][Mythen3][Gotthard2] */
Result<bool> getPowerChip(Positions pos = {}) const;
/** [Jungfrau][Moench][Mythen3][Gotthard2][Xilinx Ctb] Power the chip. \n
/** [Jungfrau][Moench][Mythen3][Gotthard2] Power the chip. \n
* Default is disabled. \n
* [Jungfrau][Moench] Default is disabled. Get will return power status. Can
* be off if temperature event occured (temperature over temp_threshold with
* temp_control enabled. Will configure chip (only chip v1.1)\n
* [Mythen3][Gotthard2] Default is 1. If module not connected or wrong
* module, powerchip will fail.\n
* [Xilinx CTB] Default is 0. Also configures chip if powered on.
*/
void setPowerChip(bool on, Positions pos = {});
@@ -535,6 +534,7 @@ class Detector {
Result<int> getDAC(defs::dacIndex index, bool mV = false,
Positions pos = {}) const;
/** Sets dac in dac units or mV1 */
void setDAC(defs::dacIndex index, int value, bool mV = false,
Positions pos = {});
@@ -1629,20 +1629,49 @@ class Detector {
Result<int> getSYNCClock(Positions pos = {}) const;
/** gets list of power enums */
std::vector<defs::dacIndex> getPowerList() const;
std::vector<defs::powerIndex> getPowerList() const;
/** gets list of slow adc enums */
std::vector<defs::dacIndex> getSlowADCList() const;
/** [CTB] Options: V_POWER_A, V_POWER_B, V_POWER_C,
* V_POWER_D, V_POWER_IO, V_POWER_CHIP
* [Xilinx CTB] Options: V_POWER_A, V_POWER_B, V_POWER_C,
* V_POWER_D, V_POWER_IO */
int getPowerDAC(defs::powerIndex index) const;
/** [CTB][Xilinx CTB] Options: V_POWER_A, V_POWER_B, V_POWER_C,
* V_POWER_D, V_POWER_IO */
void setPowerDAC(defs::powerIndex index, int value);
/** [CTB][Xilinx CTB] */
Result<int> getPower(defs::dacIndex index, Positions pos = {}) const;
bool isPowerEnabled(defs::powerIndex index) const;
/**
* [CTB][Xilinx CTB] mV
* [Ctb][Xilinx CTB] Options: V_LIMIT, V_POWER_A, V_POWER_B, V_POWER_C,
* V_POWER_D, V_POWER_IO, V_POWER_CHIP
* [Ctb][Xilinx CTB] Options: V_POWER_A, V_POWER_B, V_POWER_C,
* V_POWER_D, V_POWER_IO
*/
void setPower(defs::dacIndex index, int value, Positions pos = {});
void setPowerEnabled(const std::vector<defs::powerIndex> &indices,
bool enable);
/**
* [CTB] mV
* Options: V_POWER_A, V_POWER_B, V_POWER_C, V_POWER_D, V_POWER_IO */
int getMeasuredPower(defs::powerIndex index) const;
/**
* [CTB] mA
* Options: I_POWER_A, I_POWER_B, I_POWER_C, I_POWER_D, I_POWER_IO */
int getMeasuredCurrent(defs::powerIndex index) const;
/** [CTB][Xilinx CTB] */
int getVoltageLimit() const;
/** [CTB][Xilinx CTB] set a voltage limit for dacs and power dacs */
void setVoltageLimit(const int limit_in_mV);
/** [CTB][Xilinx CTB] gets list of slow adc enums */
std::vector<defs::dacIndex> getSlowADCList() const;
/** [CTB][Xilinx CTB] Options: SLOW_ADC0 - SLOW_ADC7 in uV */
Result<int> getSlowADC(defs::dacIndex index, Positions pos = {}) const;
/**
* [CTB] Options: [0- 4] or [1V, 1.14V, 1.33V, 1.6V, 2V]
@@ -1698,21 +1727,6 @@ class Detector {
/** [CTB] in Hz, [XCTB] in Hz */
void setDBITClock(int value_in_Hz, Positions pos = {});
/**
* [CTB] mV
* Options: V_POWER_A, V_POWER_B, V_POWER_C, V_POWER_D, V_POWER_IO */
Result<int> getMeasuredPower(defs::dacIndex index,
Positions pos = {}) const;
/**
* [CTB] mA
* Options: I_POWER_A, I_POWER_B, I_POWER_C, I_POWER_D, I_POWER_IO */
Result<int> getMeasuredCurrent(defs::dacIndex index,
Positions pos = {}) const;
/** [CTB][Xilinx CTB] Options: SLOW_ADC0 - SLOW_ADC7 in uV */
Result<int> getSlowADC(defs::dacIndex index, Positions pos = {}) const;
/** [CTB] */
Result<int> getExternalSamplingSource(Positions pos = {}) const;
@@ -1815,13 +1829,13 @@ class Detector {
std::vector<std::string> getPowerNames() const;
/** [CTB][Xilinx CTB] */
defs::dacIndex getPowerIndex(const std::string &name) const;
defs::powerIndex getPowerIndex(const std::string &name) const;
/** [CTB][Xilinx CTB] */
void setPowerName(const defs::dacIndex i, const std::string &name);
void setPowerName(const defs::powerIndex i, const std::string &name);
/** [CTB][Xilinx CTB] */
std::string getPowerName(const defs::dacIndex i) const;
std::string getPowerName(const defs::powerIndex i) const;
/** [CTB][Xilinx CTB] */
void setSlowADCNames(const std::vector<std::string> names);
File diff suppressed because it is too large Load Diff
+20 -12
View File
@@ -5,6 +5,7 @@
#include "sls/Detector.h"
#include <iostream>
#include <optional>
#include <string>
#include <vector>
namespace sls {
@@ -215,7 +216,9 @@ class Caller {
std::string periodl(int action);
std::string polarity(int action);
std::string port(int action);
std::string power(int action);
std::string powerchip(int action);
std::string powerdac(int action);
std::string powerindex(int action);
std::string powerlist(int action);
std::string powername(int action);
@@ -358,12 +361,6 @@ class Caller {
std::string updatekernel(int action);
std::string updatemode(int action);
std::string user(int action);
std::string v_a(int action);
std::string v_b(int action);
std::string v_c(int action);
std::string v_chip(int action);
std::string v_d(int action);
std::string v_io(int action);
std::string v_limit(int action);
std::string vchip_comp_adc(int action);
std::string vchip_comp_fe(int action);
@@ -396,6 +393,7 @@ class Caller {
private:
bool ReplaceIfDeprecated(std::string &command);
void SuggestIfRemoved(const std::string &command);
using FunctionMap = std::map<std::string, std::string (Caller::*)(int)>;
using StringMap = std::map<std::string, std::string>;
Detector *ptr; // pointer to the detector that executes the command
@@ -420,6 +418,9 @@ class Caller {
// applicable
RegisterAddress getRegisterAddress(const std::string &saddr) const;
BitAddress getBitAddress() const;
defs::dacIndex parseDacIndex(int argIndex, bool isCtb);
bool parseMV(int argIndex);
defs::powerIndex parsePowerIndex(int argIndex);
FunctionMap functions{
{"list", &Caller::list},
@@ -585,7 +586,9 @@ class Caller {
{"periodl", &Caller::periodl},
{"polarity", &Caller::polarity},
{"port", &Caller::port},
{"power", &Caller::power},
{"powerchip", &Caller::powerchip},
{"powerdac", &Caller::powerdac},
{"powerindex", &Caller::powerindex},
{"powerlist", &Caller::powerlist},
{"powername", &Caller::powername},
@@ -729,12 +732,6 @@ class Caller {
{"updatekernel", &Caller::updatekernel},
{"updatemode", &Caller::updatemode},
{"user", &Caller::user},
{"v_a", &Caller::v_a},
{"v_b", &Caller::v_b},
{"v_c", &Caller::v_c},
{"v_chip", &Caller::v_chip},
{"v_d", &Caller::v_d},
{"v_io", &Caller::v_io},
{"v_limit", &Caller::v_limit},
{"vchip_comp_adc", &Caller::vchip_comp_adc},
{"vchip_comp_fe", &Caller::vchip_comp_fe},
@@ -902,6 +899,17 @@ class Caller {
{"frameindex", "rx_frameindex"},
};
StringMap removed_functions{
{"v_a", "'dac v_a' and 'power v_a'"},
{"v_b", "'dac v_b' and 'power v_b'"},
{"v_c", "'dac v_c' and 'power v_c'"},
{"v_d", "'dac v_d' and 'power v_d'"},
{"v_io", "'dac v_io' and 'power v_io'"},
{"v_chip", "'dac v_chip'"},
};
};
} // namespace sls
+307
View File
@@ -4,8 +4,10 @@
#include "sls/file_utils.h"
#include "sls/logger.h"
#include "sls/string_utils.h"
#include <iostream>
#include <thread>
namespace sls {
// some helper functions to print
@@ -25,6 +27,7 @@ void Caller::call(const std::string &command,
int action, std::ostream &os, int receiver_id) {
cmd = command;
args = arguments; // copy args before replacing
SuggestIfRemoved(cmd);
std::string temp;
while (temp != cmd) {
temp = cmd;
@@ -66,6 +69,16 @@ bool Caller::ReplaceIfDeprecated(std::string &command) {
return false;
}
void Caller::SuggestIfRemoved(const std::string &command) {
auto r_it = removed_functions.find(command);
if (r_it != removed_functions.end()) {
std::ostringstream oss;
oss << command << " is removed and is no longer available. Please use: "
<< r_it->second;
throw RuntimeError(oss.str());
}
}
std::string Caller::list(int action) {
if (action == defs::HELP_ACTION) {
return "[deprecated(optional)]\n\tlists all available commands, list "
@@ -1798,4 +1811,298 @@ BitAddress Caller::getBitAddress() const {
throw RuntimeError("Invalid number of parameters for bit address.");
}
std::string Caller::dac(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {
if (args.size() == 0)
os << GetHelpDac("");
else
os << args[0] << GetHelpDac(args[0]) << '\n';
return os.str();
}
bool isCtb = false;
auto detType = det->getDetectorType().squash(defs::GENERIC);
if (detType == defs::CHIPTESTBOARD ||
detType == defs::XILINX_CHIPTESTBOARD) {
isCtb = true;
}
if (action == defs::GET_ACTION) {
auto index = parseDacIndex(0, isCtb);
auto mV = parseMV(1);
auto t = det->getDAC(index, mV, std::vector<int>{det_id});
os << args[0] << ' ' << OutString(t) << (mV ? " mV" : "") << '\n';
}
else if (action == defs::PUT_ACTION) {
auto index = parseDacIndex(0, isCtb);
if (args.size() < 2) {
WrongNumberOfParameters(2);
}
auto val = StringTo<int>(args[1]);
auto mV = parseMV(2);
det->setDAC(index, val, mV, std::vector<int>{det_id});
os << args[0] << ' ' << args[1] << (mV ? " mV" : "") << '\n';
}
else {
throw RuntimeError("Unknown action");
}
return os.str();
}
defs::dacIndex Caller::parseDacIndex(int argIndex, bool isCtb) {
if (argIndex >= (int)args.size()) {
throw RuntimeError("Invalid arguments. DAC index is required.");
}
auto arg = args[argIndex];
if (isCtb) {
// dac index
if (is_int(arg)) {
return StringTo<defs::dacIndex>(arg);
}
// dac name
return det->getDacIndex(arg);
}
// not ctb
if (is_int(arg)) {
throw RuntimeError("DAC index is not supported for your detector. "
"Please use dac name. Use daclist command to get "
"the list of dac names for your detector.");
}
return StringTo<defs::dacIndex>(arg);
}
bool Caller::parseMV(int argIndex) {
if (argIndex < (int)args.size()) {
auto arg = args[argIndex];
if (arg != "mv" && arg != "mV") {
throw RuntimeError("Unknown argument " + arg +
". Did you mean mV?");
}
return true;
}
return false;
}
std::string Caller::powerdac(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {
os << "[powername][mV value]\n\t[Ctb][Xilinx Ctb] Controls the dac "
"used for Power supply. Default names for powername are v_a, "
"v_b, v_c, v_d, v_io, v_chip(v_chip only applies to Ctb, not "
"Xilinx_Ctb). If custom names are assigned using the 'powername' "
"command, those names could be used instead instead of the "
"defaults. By default, all are set to minimum values. \n\t[Ctb] "
"v_chip can also be queried to get the vchip dac value, although "
"its rail cannot be enabled or disabled by the user. It is "
"enabled by default. Its dac value is automatically updated "
"whenever a power dac is modified. It is then set to the max of "
"power dacs + 200mV."
<< '\n';
return os.str();
}
auto detType = det->getDetectorType().squash(defs::GENERIC);
if (detType != defs::CHIPTESTBOARD &&
detType != defs::XILINX_CHIPTESTBOARD) {
throw RuntimeError("This command is only applicable for ChipTestBoard "
"and Xilinx ChipTestBoard.");
}
if (det_id != -1) {
throw RuntimeError("Cannot use powerdac at module level.");
}
auto index = parsePowerIndex(0);
if (action == defs::GET_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
auto t = det->getPowerDAC(index);
os << args[0] << ' ' << OutString(t) << '\n';
}
else if (action == defs::PUT_ACTION) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
auto val = StringTo<int>(args[1]);
det->setPowerDAC(index, val);
os << args[0] << ' ' << args[1] << '\n';
} else {
throw RuntimeError("Unknown action");
}
return os.str();
}
defs::powerIndex Caller::parsePowerIndex(int argIndex) {
if (argIndex >= (int)args.size()) {
throw RuntimeError("Invalid arguments. Power name is required.");
}
auto arg = args[argIndex];
// power default names
if (is_int(arg) || arg == "v_a" || arg == "v_b" || arg == "v_c" ||
arg == "v_d" || arg == "v_io" || arg == "v_chip") {
return StringTo<defs::powerIndex>(arg);
}
// power name
auto names = det->getPowerNames();
auto it = std::find(names.begin(), names.end(), arg);
if (it != names.end()) {
return det->getPowerIndex(arg);
}
throw RuntimeError(
"Unknown power name '" + arg +
"'. Use 'powername' command to see defined power names.");
}
std::string Caller::power(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {
os << "[all|list of power names] [on|off]\n\t[Ctb][Xilinx Ctb] Enable "
"or "
"disable power rails. Power name can be all, v_a, v_b, v_c, v_d "
"or "
"v_io or any defines using 'powername'. If power name is set to "
"'all', the command applies to all 'powers'. Enabling the power "
"rails is in parallel, whereas retrieving the states of multiple "
"power rails, they are queried sequentially "
"(one after another), not in parallel."
<< '\n';
return os.str();
}
auto detType = det->getDetectorType().squash(defs::GENERIC);
if (detType != defs::CHIPTESTBOARD &&
detType != defs::XILINX_CHIPTESTBOARD) {
throw RuntimeError("This command is only applicable for ChipTestBoard "
"and Xilinx ChipTestBoard.");
}
// 'all' argument
bool all = false;
if (std::find(args.begin(), args.end(), "all") != args.end()) {
all = true;
}
// number of args
if (action == defs::GET_ACTION && args.size() != 1)
WrongNumberOfParameters(1);
if (all) {
if (action == defs::PUT_ACTION && args.size() != 2) {
WrongNumberOfParameters(2);
}
} else {
if (args.size() < 1 || args.size() > 6)
WrongNumberOfParameters(1);
}
if (action == defs::GET_ACTION) {
if (!all) {
auto t = det->isPowerEnabled(parsePowerIndex(0));
os << args[0] << ' ' << ToString(t, defs::OnOff) << '\n';
} else {
// get each state and store in map
std::map<std::string, std::string> m;
auto powerIndices = det->getPowerList();
for (const auto &index : powerIndices) {
auto name = ToString(index);
auto state = det->isPowerEnabled(index);
m[name] = ToString(state, defs::OnOff);
}
if (m.empty()) {
throw RuntimeError("Could not get power states.");
}
auto first = m.begin()->second;
// if all the same, print in short form, else print all states
if (std::all_of(m.begin(), m.end(),
[&](const auto &p) { return p.second == first; })) {
os << "all " << first << '\n';
} else {
os << ToString(m) << '\n';
}
}
}
else if (action == defs::PUT_ACTION) {
// enable arg
std::string lastArg = args.back();
if (lastArg != "on" && lastArg != "off") {
throw RuntimeError("Last argument '" + lastArg +
"' is enable. Options: 'on' or 'off'");
}
bool enable = StringTo(lastArg, defs::OnOff);
// power indices
std::vector<defs::powerIndex> powerIndices;
if (all) {
powerIndices = det->getPowerList();
} else {
// push back indices from command line
for (size_t i = 0; i < args.size() - 1; ++i) {
powerIndices.push_back(parsePowerIndex(i));
}
}
det->setPowerEnabled(powerIndices, enable);
args.pop_back();
os << ToString(args) << ' ' << ToString(enable, defs::OnOff) << '\n';
} else {
throw RuntimeError("Unknown action");
}
return os.str();
}
std::string Caller::powervalues(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {
os << "\n\t\t[Ctb][Xilinx_Ctb] Get dac values of all powers if "
"enabled, else '0'."
<< '\n';
return os.str();
}
auto detType = det->getDetectorType().squash(defs::GENERIC);
if (detType != defs::CHIPTESTBOARD &&
detType != defs::XILINX_CHIPTESTBOARD) {
throw RuntimeError("This command is only applicable for ChipTestBoard "
"and Xilinx ChipTestBoard.");
}
if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getPowerList();
auto names = det->getPowerNames();
auto name_it = names.begin();
os << '[';
auto it = t.cbegin();
while (it != t.cend()) {
if (it != t.cbegin())
os << ", ";
os << ToString(*name_it++) << ": [";
os << ToString(det->isPowerEnabled(*it), defs::OnOff) << ", ";
os << det->getPowerDAC(*it) << " mV ]";
++it;
}
os << "]" << '\n';
} else if (action == defs::PUT_ACTION) {
throw RuntimeError("Cannot put");
} else {
throw RuntimeError("Unknown action");
}
return os.str();
}
} // namespace sls
+14 -5
View File
@@ -20,11 +20,11 @@ CtbConfig::CtbConfig() {
for (size_t i = 0; i != num_signals; ++i) {
setSignalName(i, "BIT" + ToString(i));
}
setPowerName(0, "VA");
setPowerName(1, "VB");
setPowerName(2, "VC");
setPowerName(3, "VD");
setPowerName(4, "VIO");
setPowerName(static_cast<int>(defs::V_POWER_A), "VA");
setPowerName(static_cast<int>(defs::V_POWER_B), "VB");
setPowerName(static_cast<int>(defs::V_POWER_C), "VC");
setPowerName(static_cast<int>(defs::V_POWER_D), "VD");
setPowerName(static_cast<int>(defs::V_POWER_IO), "VIO");
for (size_t i = 0; i != num_slowADCs; ++i) {
setSlowADCName(i, "SLOWADC" + ToString(i));
}
@@ -80,6 +80,15 @@ CtbConfig::getNames(size_t expected_size,
void CtbConfig::setDacName(size_t index, const std::string &name) {
check_index(index, num_dacs, "DAC");
std::vector<std::string> powers = {"v_a", "v_b", "v_c", "v_d", "v_io",
"va", "vb", "vc", "vd", "vio"};
std::string lower = name;
std::transform(lower.begin(), lower.end(), lower.begin(),
[](unsigned char c) { return std::tolower(c); });
if (std::find(powers.begin(), powers.end(), lower) != powers.end()) {
throw RuntimeError("DAC name cannot be a power name (VA, VB, VC, VD, "
"VIO, V_A, V_B, V_C, V_D, V_IO)");
}
set_name(name, dacnames, index);
}
+88 -72
View File
@@ -2166,15 +2166,80 @@ Result<int> Detector::getSYNCClock(Positions pos) const {
return pimpl->Parallel(&Module::getClockFrequency, pos, defs::SYNC_CLOCK);
}
std::vector<defs::dacIndex> Detector::getPowerList() const {
std::vector<defs::powerIndex> Detector::getPowerList() const {
auto dettype = getDetectorType().squash();
if (dettype != defs::CHIPTESTBOARD &&
dettype != defs::XILINX_CHIPTESTBOARD) {
throw RuntimeError("Power list not implemented for this detector");
}
return std::vector<defs::dacIndex>{defs::V_POWER_A, defs::V_POWER_B,
defs::V_POWER_C, defs::V_POWER_D,
defs::V_POWER_IO};
return std::vector<defs::powerIndex>{defs::V_POWER_A, defs::V_POWER_B,
defs::V_POWER_C, defs::V_POWER_D,
defs::V_POWER_IO};
}
int Detector::getPowerDAC(defs::powerIndex index) const {
pimpl->verifyChipTestBoard(__func__);
return pimpl->Parallel(&Module::getPowerDAC, {0}, index)[0];
}
void Detector::setPowerDAC(defs::powerIndex index, int value) {
pimpl->verifyChipTestBoard(__func__);
pimpl->Parallel(&Module::setPowerDAC, {0}, index, value);
}
bool Detector::isPowerEnabled(defs::powerIndex index) const {
pimpl->verifyChipTestBoard(__func__);
return pimpl->Parallel(&Module::isPowerEnabled, {0}, index)[0];
}
void Detector::setPowerEnabled(const std::vector<defs::powerIndex> &indices,
bool enable) {
pimpl->verifyChipTestBoard(__func__);
if (indices.empty()) {
throw RuntimeError("No Power Index provided");
}
pimpl->Parallel(&Module::setPowerEnabled, {0}, indices, enable);
}
int Detector::getMeasuredPower(defs::powerIndex index) const {
pimpl->verifyChipTestBoard(__func__);
switch (index) {
case defs::V_POWER_A:
case defs::V_POWER_B:
case defs::V_POWER_C:
case defs::V_POWER_D:
case defs::V_POWER_IO:
case defs::V_POWER_CHIP:
break;
default:
throw RuntimeError("Unknown Power Index " + std::to_string(index));
}
return pimpl->Parallel(&Module::getPowerADC, {0}, index)[0];
}
int Detector::getMeasuredCurrent(defs::powerIndex index) const {
pimpl->verifyChipTestBoard(__func__);
switch (index) {
case defs::I_POWER_A:
case defs::I_POWER_B:
case defs::I_POWER_C:
case defs::I_POWER_D:
case defs::I_POWER_IO:
break;
default:
throw RuntimeError("Unknown Current Index " + std::to_string(index));
}
return pimpl->Parallel(&Module::getPowerADC, {0}, index)[0];
}
int Detector::getVoltageLimit() const {
pimpl->verifyChipTestBoard(__func__);
return pimpl->Parallel(&Module::getVoltageLimit, {0})[0];
}
void Detector::setVoltageLimit(int value) {
pimpl->verifyChipTestBoard(__func__);
pimpl->Parallel(&Module::setVoltageLimit, {0}, value);
}
std::vector<defs::dacIndex> Detector::getSlowADCList() const {
@@ -2188,38 +2253,6 @@ std::vector<defs::dacIndex> Detector::getSlowADCList() const {
defs::SLOW_ADC4, defs::SLOW_ADC5, defs::SLOW_ADC6, defs::SLOW_ADC7};
}
Result<int> Detector::getPower(defs::dacIndex index, Positions pos) const {
switch (index) {
case defs::V_LIMIT:
case defs::V_POWER_A:
case defs::V_POWER_B:
case defs::V_POWER_C:
case defs::V_POWER_D:
case defs::V_POWER_IO:
case defs::V_POWER_CHIP:
break;
default:
throw RuntimeError("Unknown Power Index");
}
return pimpl->Parallel(&Module::getDAC, pos, index, true);
}
void Detector::setPower(defs::dacIndex index, int value, Positions pos) {
switch (index) {
case defs::V_LIMIT:
case defs::V_POWER_A:
case defs::V_POWER_B:
case defs::V_POWER_C:
case defs::V_POWER_D:
case defs::V_POWER_IO:
case defs::V_POWER_CHIP:
break;
default:
throw RuntimeError("Unknown Power Index");
}
pimpl->Parallel(&Module::setDAC, pos, value, index, true);
}
Result<int> Detector::getADCVpp(bool mV, Positions pos) const {
return pimpl->Parallel(&Module::getDAC, pos, defs::ADC_VPP, mV);
}
@@ -2286,37 +2319,6 @@ void Detector::setDBITClock(int value_in_Hz, Positions pos) {
value_in_Hz);
}
Result<int> Detector::getMeasuredPower(defs::dacIndex index,
Positions pos) const {
switch (index) {
case defs::V_POWER_A:
case defs::V_POWER_B:
case defs::V_POWER_C:
case defs::V_POWER_D:
case defs::V_POWER_IO:
case defs::V_POWER_CHIP:
break;
default:
throw RuntimeError("Unknown Power Index");
}
return pimpl->Parallel(&Module::getADC, pos, index);
}
Result<int> Detector::getMeasuredCurrent(defs::dacIndex index,
Positions pos) const {
switch (index) {
case defs::I_POWER_A:
case defs::I_POWER_B:
case defs::I_POWER_C:
case defs::I_POWER_D:
case defs::I_POWER_IO:
break;
default:
throw RuntimeError("Unknown Current Index");
}
return pimpl->Parallel(&Module::getADC, pos, index);
}
Result<int> Detector::getSlowADC(defs::dacIndex index, Positions pos) const {
if (index < defs::SLOW_ADC0 || index > defs::SLOW_ADC7) {
throw RuntimeError("Unknown Slow ADC Index");
@@ -2398,7 +2400,14 @@ defs::dacIndex Detector::getDacIndex(const std::string &name) const {
throw RuntimeError("Dac name not found");
return static_cast<defs::dacIndex>(it - names.begin());
}
return StringTo<defs::dacIndex>(name);
auto retval = StringTo<defs::dacIndex>(name);
auto list = getDacList();
if (std::find(list.begin(), list.end(), retval) == list.end()) {
throw RuntimeError("Dac name not found in dac list. Use 'daclist' or "
"Detector::getDacNames() to get the list of dac "
"names for this detector.");
}
return retval;
}
void Detector::setDacName(const defs::dacIndex i, const std::string &name) {
@@ -2408,6 +2417,13 @@ void Detector::setDacName(const defs::dacIndex i, const std::string &name) {
std::string Detector::getDacName(const defs::dacIndex i) const {
if (pimpl->isChipTestBoard())
return pimpl->getCtbDacName(i);
auto list = getDacList();
if (std::find(list.begin(), list.end(), i) == list.end()) {
auto count = getDacList().size();
throw RuntimeError(
"Dac index not found in dac list. Use an index from 0 to " +
std::to_string(count - 1) + ".");
}
return ToString(i);
}
@@ -2467,20 +2483,20 @@ std::vector<std::string> Detector::getPowerNames() const {
return pimpl->getCtbPowerNames();
}
defs::dacIndex Detector::getPowerIndex(const std::string &name) const {
defs::powerIndex Detector::getPowerIndex(const std::string &name) const {
auto names = getPowerNames();
auto it = std::find(names.begin(), names.end(), name);
if (it == names.end())
throw RuntimeError("Power name not found");
return static_cast<defs::dacIndex>(it - names.begin() + defs::V_POWER_A);
return static_cast<defs::powerIndex>(it - names.begin());
}
void Detector::setPowerName(const defs::dacIndex index,
void Detector::setPowerName(const defs::powerIndex index,
const std::string &name) {
pimpl->setCtbPowerName(index, name);
}
std::string Detector::getPowerName(const defs::dacIndex i) const {
std::string Detector::getPowerName(const defs::powerIndex i) const {
return pimpl->getCtbPowerName(i);
}
+3 -3
View File
@@ -2026,17 +2026,17 @@ void DetectorImpl::setCtbPowerNames(const std::vector<std::string> &names) {
ctb_shm()->setPowerNames(names);
}
std::string DetectorImpl::getCtbPowerName(const defs::dacIndex i) const {
std::string DetectorImpl::getCtbPowerName(const defs::powerIndex i) const {
if (!isChipTestBoard())
throw RuntimeError("Named Powers only for CTB");
return ctb_shm()->getPowerName(static_cast<int>(i - defs::V_POWER_A));
}
void DetectorImpl::setCtbPowerName(const defs::dacIndex index,
void DetectorImpl::setCtbPowerName(const defs::powerIndex index,
const std::string &name) {
if (!isChipTestBoard())
throw RuntimeError("Named Powers only for CTB");
ctb_shm()->setPowerName(static_cast<int>(index - defs::V_POWER_A), name);
ctb_shm()->setPowerName(static_cast<int>(index), name);
}
std::vector<std::string> DetectorImpl::getCtbSlowADCNames() const {
+13 -2
View File
@@ -188,6 +188,17 @@ class DetectorImpl : public virtual slsDetectorDefs {
shm()->detType == defs::XILINX_CHIPTESTBOARD);
}
inline void verifyChipTestBoard(const std::string &funcName) const {
if (!isChipTestBoard())
throw RuntimeError(funcName +
" is not implemented for this detector. It is "
"only valid for chip test board");
if (size() != 1)
throw RuntimeError(
funcName +
" is only valid for single module setup (chip test board).");
}
/** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag);
@@ -324,9 +335,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
void setCtbSignalName(const int index, const std::string &name);
std::vector<std::string> getCtbPowerNames() const;
std::string getCtbPowerName(const defs::dacIndex i) const;
std::string getCtbPowerName(const defs::powerIndex i) const;
void setCtbPowerNames(const std::vector<std::string> &names);
void setCtbPowerName(const defs::dacIndex index, const std::string &name);
void setCtbPowerName(const defs::powerIndex index, const std::string &name);
std::vector<std::string> getCtbSlowADCNames() const;
std::string getCtbSlowADCName(const defs::dacIndex i) const;
+4 -18
View File
@@ -7,7 +7,7 @@
namespace sls {
std::string GetHelpDac(std::string dac) {
if (sls::is_int(dac)) {
if (dac.empty() || sls::is_int(dac)) {
return std::string("[dac name] [dac or mV value] [(optional unit) mV] "
"\n\t[Ctb] Use dac index for dac name.");
}
@@ -280,24 +280,10 @@ std::string GetHelpDac(std::string dac) {
return std::string(
"[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 7");
}
// clang-format off
if (dac == "vtgstv") { return std::string(""); }
// clang-format on
if (dac == "vtgstv") {
return std::string("");
}
throw sls::RuntimeError("Unknown dac command");
}
std::string GetHelpDacWrapper(const std::string &cmd,
const std::vector<std::string> &args) {
std::ostringstream os;
os << cmd << ' ';
if (args.size() == 0) {
os << GetHelpDac(std::to_string(0)) << '\n';
} else {
os << args[0] << ' ' << GetHelpDac(args[0]) << '\n';
}
return os.str();
}
} // namespace sls
-3
View File
@@ -7,7 +7,4 @@ namespace sls {
std::string GetHelpDac(std::string dac);
std::string GetHelpDacWrapper(const std::string &cmd,
const std::vector<std::string> &args);
} // namespace sls
+44
View File
@@ -819,6 +819,50 @@ void Module::setPowerChip(bool on) {
sendToDetector<int>(F_POWER_CHIP, static_cast<int>(on));
}
int Module::getPowerDAC(defs::powerIndex index) const {
return sendToDetector<int>(F_GET_POWER_DAC, static_cast<int>(index));
}
void Module::setPowerDAC(defs::powerIndex index, int value) {
int args[]{static_cast<int>(index), value};
sendToDetector(F_SET_POWER_DAC, args, nullptr);
}
bool Module::isPowerEnabled(defs::powerIndex index) const {
return sendToDetector<int>(F_GET_POWER, static_cast<int>(index));
}
void Module::setPowerEnabled(const std::vector<defs::powerIndex> &indices,
bool enable) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SET_POWER);
client.setFnum(F_SET_POWER);
int count = indices.size();
client.Send(count);
std::vector<int> indices_int(count);
for (size_t i = 0; i < indices.size(); ++i) {
indices_int[i] = static_cast<int>(indices[i]);
}
client.Send(indices_int);
client.Send(static_cast<int>(enable));
if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
}
int Module::getPowerADC(defs::powerIndex index) const {
return sendToDetector<int>(F_GET_POWER_ADC, static_cast<int>(index));
}
int Module::getVoltageLimit() const {
return sendToDetector<int>(F_GET_VOLTAGE_LIMIT);
}
void Module::setVoltageLimit(const int limit_in_mV) {
sendToDetector(F_SET_VOLTAGE_LIMIT, limit_in_mV, nullptr);
}
int Module::getImageTestMode() const {
return sendToDetector<int>(F_GET_IMAGE_TEST_MODE);
}
+8
View File
@@ -177,6 +177,14 @@ class Module : public virtual slsDetectorDefs {
void setDAC(int val, dacIndex index, bool mV);
bool getPowerChip() const;
void setPowerChip(bool on);
int getPowerDAC(defs::powerIndex index) const;
void setPowerDAC(defs::powerIndex index, int value);
bool isPowerEnabled(defs::powerIndex index) const;
void setPowerEnabled(const std::vector<defs::powerIndex> &indices,
bool enable);
int getPowerADC(defs::powerIndex index) const;
int getVoltageLimit() const;
void setVoltageLimit(const int limit_in_mV);
int getImageTestMode() const;
void setImageTestMode(const int value);
/* temperature in millidegrees */
+22 -96
View File
@@ -2256,6 +2256,12 @@ int InferAction::port() {
}
}
int InferAction::power() {
throw RuntimeError("sls_detector is disabled for command: power. Use "
"sls_detector_get or sls_detector_put");
}
int InferAction::powerchip() {
if (args.size() == 0) {
@@ -2272,6 +2278,22 @@ int InferAction::powerchip() {
}
}
int InferAction::powerdac() {
if (args.size() == 1) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 2) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::powerindex() {
if (args.size() == 1) {
@@ -4253,102 +4275,6 @@ int InferAction::user() {
}
}
int InferAction::v_a() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::v_b() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::v_c() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::v_chip() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::v_d() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::v_io() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::v_limit() {
if (args.size() == 0) {
+4 -12
View File
@@ -170,7 +170,9 @@ class InferAction {
int periodl();
int polarity();
int port();
int power();
int powerchip();
int powerdac();
int powerindex();
int powerlist();
int powername();
@@ -313,12 +315,6 @@ class InferAction {
int updatekernel();
int updatemode();
int user();
int v_a();
int v_b();
int v_c();
int v_chip();
int v_d();
int v_io();
int v_limit();
int vchip_comp_adc();
int vchip_comp_fe();
@@ -510,7 +506,9 @@ class InferAction {
{"periodl", &InferAction::periodl},
{"polarity", &InferAction::polarity},
{"port", &InferAction::port},
{"power", &InferAction::power},
{"powerchip", &InferAction::powerchip},
{"powerdac", &InferAction::powerdac},
{"powerindex", &InferAction::powerindex},
{"powerlist", &InferAction::powerlist},
{"powername", &InferAction::powername},
@@ -654,12 +652,6 @@ class InferAction {
{"updatekernel", &InferAction::updatekernel},
{"updatemode", &InferAction::updatemode},
{"user", &InferAction::user},
{"v_a", &InferAction::v_a},
{"v_b", &InferAction::v_b},
{"v_c", &InferAction::v_c},
{"v_chip", &InferAction::v_chip},
{"v_d", &InferAction::v_d},
{"v_io", &InferAction::v_io},
{"v_limit", &InferAction::v_limit},
{"vchip_comp_adc", &InferAction::vchip_comp_adc},
{"vchip_comp_fe", &InferAction::vchip_comp_fe},
@@ -46,6 +46,12 @@ TEST_CASE("dacname", "[.detectorintegration]") {
REQUIRE(oss.str() ==
std::string("dacname ") + str_dac_index + " bname\n");
}
REQUIRE_THROWS(caller.call("dacname", {str_dac_index, "v_a"}, -1, PUT));
REQUIRE_THROWS(caller.call("dacname", {str_dac_index, "v_b"}, -1, PUT));
REQUIRE_THROWS(caller.call("dacname", {str_dac_index, "v_c"}, -1, PUT));
REQUIRE_THROWS(caller.call("dacname", {str_dac_index, "v_d"}, -1, PUT));
REQUIRE_THROWS(
caller.call("dacname", {str_dac_index, "v_io"}, -1, PUT));
det.setDacName(ind, prev);
} else {
@@ -309,7 +315,7 @@ TEST_CASE("powername", "[.detectorintegration]") {
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
defs::dacIndex ind = static_cast<defs::dacIndex>(2 + defs::V_POWER_A);
defs::powerIndex ind = static_cast<defs::powerIndex>(2);
std::string str_power_index = "2";
auto prev = det.getPowerName(ind);
@@ -344,7 +350,7 @@ TEST_CASE("powerindex", "[.detectorintegration]") {
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
defs::dacIndex ind = static_cast<defs::dacIndex>(2 + defs::V_POWER_A);
defs::powerIndex ind = static_cast<defs::powerIndex>(2);
std::string str_power_index = "2";
// 1 arg throw
@@ -356,8 +362,7 @@ TEST_CASE("powerindex", "[.detectorintegration]") {
std::ostringstream oss;
REQUIRE_NOTHROW(
caller.call("powerindex", {powername}, -1, GET, oss));
REQUIRE(oss.str() ==
std::string("powerindex ") + str_power_index + '\n');
REQUIRE(oss.str() == "powerindex 2\n");
}
} else {
REQUIRE_THROWS(caller.call("powerindex", {"2"}, -1, GET));
@@ -496,35 +501,8 @@ TEST_CASE("dac", "[.detectorintegration][dacs]") {
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
for (int i = 0; i < 18; ++i) {
SECTION("dac " + std::to_string(i)) {
test_dac_caller(static_cast<defs::dacIndex>(i), "dac", 0);
}
}
// normal dacs
{
defs::dacIndex idac = defs::DAC_5;
auto previous = det.getDAC(idac, false);
REQUIRE_THROWS(
caller.call("dac", {std::to_string(idac), "-2"}, -1, PUT));
REQUIRE_THROWS(
caller.call("dac", {std::to_string(idac), "-1"}, -1, PUT));
REQUIRE_NOTHROW(
caller.call("dac", {std::to_string(idac), "-100"}, -1, PUT));
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
det.setDAC(idac, previous[i], false, {i});
}
}
REQUIRE_THROWS(caller.call("dac", {"18"}, -1, GET));
REQUIRE_THROWS(caller.call("dac", {"5", "4096"}, -1, PUT));
if (det_type == defs::CHIPTESTBOARD)
REQUIRE_THROWS(caller.call("dac", {"5", "2501", "mV"}, -1, PUT));
else
REQUIRE_THROWS(caller.call("dac", {"5", "2049", "mV"}, -1, PUT));
// eiger
// REQUIRE_THROWS(caller.call("dac", {"vthreshold"}, -1, GET));
// REQUIRE_THROWS(caller.call("dac", {"vsvp"}, -1, GET));
@@ -584,6 +562,250 @@ TEST_CASE("dac", "[.detectorintegration][dacs]") {
REQUIRE_THROWS(caller.call("dac", {"vb_cs"}, -1, GET));
REQUIRE_THROWS(caller.call("dac", {"vb_opa_fd"}, -1, GET));
REQUIRE_THROWS(caller.call("dac", {"vcom_adc2"}, -1, GET));
// ctb and xilinx
REQUIRE_THROWS(caller.call("dac", {"18"}, -1, GET));
REQUIRE_THROWS(caller.call("dac", {"5", "4096"}, -1, PUT));
if (det_type == defs::CHIPTESTBOARD)
REQUIRE_THROWS(caller.call("dac", {"5", "2501", "mV"}, -1, PUT));
else
REQUIRE_THROWS(caller.call("dac", {"5", "2049", "mV"}, -1, PUT));
for (int idac = 0; idac < 18; ++idac) {
SECTION("dac " + std::to_string(idac)) {
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", 0);
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", 1200);
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", 1200,
true);
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", -100);
// dac name
det.setDacName(static_cast<defs::dacIndex>(idac),
"dacname" + std::to_string(idac));
test_dac_caller(defs::DAC_0, "dacname" + std::to_string(idac),
-100);
}
REQUIRE_THROWS(
caller.call("dac", {std::to_string(idac), "-2"}, -1, PUT));
REQUIRE_THROWS(
caller.call("dac", {std::to_string(idac), "-1"}, -1, PUT));
}
// power dacs (shouldnt work anymore. TODO: remove after testing)
REQUIRE_THROWS(caller.call("dac", {"v_a", "mV"}, -1, GET));
}
}
TEST_CASE("powerdac", "[.detectorintegration][dacs]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
if (det.isVirtualDetectorServer().tsquash(
"Inconsistent virtual servers")) {
// test only get of vchip
if (det_type == defs::CHIPTESTBOARD) {
REQUIRE_THROWS(
caller.call("powerdac", {"v_chip", "1700", "mV"}, -1, PUT));
REQUIRE_THROWS(
caller.call("powerdac", {"v_chip", "mV"}, -1, GET));
REQUIRE_NOTHROW(caller.call("powerdac", {"v_chip"}, -1, GET));
} else {
REQUIRE_THROWS(caller.call("powerdac", {"v_chip"}, -1, GET));
}
// other power dacs
std::vector<std::string> names{"v_a", "v_b", "v_c", "v_d", "v_io"};
std::vector<defs::powerIndex> indices{
defs::V_POWER_A, defs::V_POWER_B, defs::V_POWER_C,
defs::V_POWER_D, defs::V_POWER_IO};
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
auto prev_val = det.getPowerDAC(indices[iPower]);
auto prev_val_power = det.isPowerEnabled(indices[iPower]);
// this is the first command touching power dacs, should not be
// -100
REQUIRE(prev_val != -100);
REQUIRE(prev_val != -1);
REQUIRE(prev_val != 0);
REQUIRE_THROWS(
caller.call("powerdac", {names[iPower], "-2"}, -1, PUT));
REQUIRE_THROWS(
caller.call("powerdac", {names[iPower], "-100"}, -1, PUT));
REQUIRE_THROWS(
caller.call("powerdac", {names[iPower], "-1"}, -1, PUT));
REQUIRE_THROWS(
caller.call("powerdac", {names[iPower], "0"}, -1, PUT));
REQUIRE_THROWS(
caller.call("powerdac", {names[iPower], "4096"}, -1, PUT));
// dont need mV
REQUIRE_THROWS(caller.call(
"powerdac", {names[iPower], "1200", "mV"}, -1, PUT));
REQUIRE_THROWS(
caller.call("powerdac", {names[iPower], "mV"}, -1, GET));
// min
if (names[iPower] == "v_io")
REQUIRE_THROWS(caller.call(
"powerdac", {names[iPower], "1199"}, -1, PUT));
else {
if (det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(caller.call(
"powerdac", {names[iPower], "1040"}, -1, PUT));
} else {
REQUIRE_THROWS(caller.call(
"powerdac", {names[iPower], "635"}, -1, PUT));
}
}
// max
if (det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(caller.call(
"powerdac", {names[iPower], "2662"}, -1, PUT));
} else {
REQUIRE_THROWS(caller.call(
"powerdac", {names[iPower], "2469"}, -1, PUT));
}
{
std::ostringstream oss1, oss2;
caller.call("powerdac", {names[iPower], "1200"}, -1, PUT,
oss1);
REQUIRE(oss1.str() ==
"powerdac " + names[iPower] + " 1200\n");
caller.call("powerdac", {names[iPower]}, -1, GET, oss2);
REQUIRE(oss2.str() ==
"powerdac " + names[iPower] + " 1200\n");
}
{
// power name
det.setPowerName(indices[iPower],
"pwrname_" + names[iPower]);
std::ostringstream oss1, oss2;
caller.call("powerdac",
{"pwrname_" + names[iPower], "1200"}, -1, PUT,
oss1);
REQUIRE(oss1.str() ==
"powerdac pwrname_" + names[iPower] + " 1200\n");
caller.call("powerdac", {"pwrname_" + names[iPower]}, -1,
GET, oss2);
REQUIRE(oss2.str() ==
"powerdac pwrname_" + names[iPower] + " 1200\n");
}
// trying to set dac when power is on
{
det.setPowerEnabled(std::vector{indices[iPower]}, true);
std::ostringstream oss1, oss2;
caller.call("powerdac", {names[iPower], "1200"}, -1, PUT,
oss1);
REQUIRE(oss1.str() ==
"powerdac " + names[iPower] + " 1200\n");
caller.call("powerdac", {names[iPower]}, -1, GET, oss2);
REQUIRE(oss2.str() ==
"powerdac " + names[iPower] + " 1200\n");
}
// Reset all dacs to previous value
det.setPowerDAC(indices[iPower], prev_val);
det.setPowerEnabled(std::vector{indices[iPower]},
prev_val_power);
}
// all
{
int prev_val[5] = {0};
int prev_power_val[5] = {0};
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
prev_val[iPower] = det.getPowerDAC(indices[iPower]);
prev_power_val[iPower] =
det.isPowerEnabled(indices[iPower]);
}
// all off
REQUIRE_NOTHROW(caller.call("power", {"all", "off"}, -1, PUT));
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
REQUIRE(det.isPowerEnabled(indices[iPower]) == false);
}
// all on
REQUIRE_NOTHROW(caller.call("power", {"all", "on"}, -1, PUT));
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
REQUIRE(det.isPowerEnabled(indices[iPower]) == true);
}
// all off
REQUIRE_NOTHROW(caller.call("power", {"all", "off"}, -1, PUT));
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
REQUIRE(det.isPowerEnabled(indices[iPower]) == false);
}
// reset it to previous value
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
det.setPowerDAC(indices[iPower], prev_val[iPower]);
det.setPowerEnabled({indices[iPower]},
prev_power_val[iPower]);
}
}
// vchip val
if (det_type == defs::CHIPTESTBOARD) {
const int min_vchip_val = 1673;
int prev_val[5] = {0};
int prev_power_val[5] = {0};
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
prev_val[iPower] = det.getPowerDAC(indices[iPower]);
prev_power_val[iPower] =
det.isPowerEnabled(indices[iPower]);
}
// all off, vchip = min
REQUIRE_NOTHROW(caller.call("power", {"all", "off"}, -1, PUT));
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == min_vchip_val);
// change dacs
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_a", "1500"}, -1, PUT));
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_b", "1200"}, -1, PUT));
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_c", "1200"}, -1, PUT));
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_d", "1200"}, -1, PUT));
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_io", "1200"}, -1, PUT));
// vchip = min
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == min_vchip_val);
// all on, vchip changes
REQUIRE_NOTHROW(caller.call("power", {"all", "on"}, -1, PUT));
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == 1700);
// change dac, vchip changes to max + 200
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_a", "1700"}, -1, PUT));
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == 1900);
REQUIRE_NOTHROW(
caller.call("powerdac", {"v_b", "1500"}, -1, PUT));
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == 1900);
// switch off v_a, vchip = max + 200 of those enabled
REQUIRE_NOTHROW(caller.call("power", {"v_a", "off"}, -1, PUT));
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == 1700);
// all off, vchip = min
REQUIRE_NOTHROW(caller.call("power", {"all", "off"}, -1, PUT));
REQUIRE(det.getPowerDAC(defs::V_POWER_CHIP) == min_vchip_val);
// reset it to previous value
for (size_t iPower = 0; iPower < names.size(); ++iPower) {
det.setPowerDAC(indices[iPower], prev_val[iPower]);
det.setPowerEnabled({indices[iPower]},
prev_power_val[iPower]);
}
}
}
} else {
REQUIRE_THROWS(caller.call("powerdac", {"v_a"}, -1, GET));
}
}
@@ -815,32 +1037,32 @@ TEST_CASE("v_limit", "[.detectorintegration]") {
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
auto prev_val = det.getPower(defs::V_LIMIT);
auto prev_val = det.getVoltageLimit();
auto prev_dac_val = det.getDAC(defs::DAC_0, false);
auto prev_power_dac_val = det.getPowerDAC(defs::V_POWER_A);
REQUIRE_THROWS(caller.call("v_limit", {"1200", "mV"}, -1, PUT));
REQUIRE_THROWS(caller.call("v_limit", {"-100"}, -1, PUT));
{
std::ostringstream oss, oss2;
caller.call("v_limit", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "v_limit 0\n");
caller.call("v_limit", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "v_limit 0\n");
REQUIRE_NOTHROW(caller.call("dac", {"0", "1200", "mV"}, -1, PUT));
REQUIRE_NOTHROW(caller.call("powerdac", {"v_a", "1200"}, -1, PUT));
}
{
std::ostringstream oss;
caller.call("v_limit", {"1500"}, -1, PUT, oss);
REQUIRE(oss.str() == "v_limit 1500\n");
REQUIRE_THROWS(caller.call("dac", {"0", "1501", "mV"}, -1, PUT));
REQUIRE_THROWS(caller.call("powerdac", {"v_a", "1501"}, -1, PUT));
}
{
std::ostringstream oss;
caller.call("v_limit", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "v_limit 0\n");
}
{
std::ostringstream oss;
caller.call("v_limit", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "v_limit 0\n");
}
{
std::ostringstream oss;
caller.call("v_limit", {}, -1, GET, oss);
REQUIRE(oss.str() == "v_limit 0\n");
}
det.setVoltageLimit(prev_val);
det.setPowerDAC(defs::V_POWER_A, prev_power_dac_val);
for (int i = 0; i != det.size(); ++i) {
if (prev_val[i] == -100) {
prev_val[i] = 0;
}
det.setPower(defs::V_LIMIT, prev_val[i], {i});
det.setDAC(defs::DAC_0, prev_dac_val[i], false, {i});
}
} else {
REQUIRE_THROWS(caller.call("v_limit", {}, -1, GET));
@@ -1116,102 +1338,119 @@ TEST_CASE("dbitclk", "[.detectorintegration]") {
TEST_CASE("v_abcd", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
std::vector<std::string> cmds{"v_a", "v_b", "v_c", "v_d"};
std::vector<defs::dacIndex> indices{defs::V_POWER_A, defs::V_POWER_B,
defs::V_POWER_C, defs::V_POWER_D};
if (det.isVirtualDetectorServer().tsquash("Inconsistent virtual servers")) {
cmds.push_back("v_io");
indices.push_back(defs::V_POWER_IO);
}
// removed in favor of "dac" and "power" commands
std::vector<std::string> cmds{"v_a", "v_b", "v_c", "v_d", "v_io", "v_chip"};
for (size_t i = 0; i < cmds.size(); ++i) {
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
auto prev_val = det.getPower(indices[i]);
// this is the first command touching power dacs, should not be
// -100
if (det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE(prev_val.any(-100) == false);
REQUIRE(prev_val.any(-1) == false);
}
REQUIRE_THROWS(caller.call(cmds[i], {"-2"}, -1, PUT));
REQUIRE_THROWS(caller.call(cmds[i], {"-100"}, -1, PUT));
REQUIRE_THROWS(caller.call(cmds[i], {"-1"}, -1, PUT));
if (cmds[i] == "v_io")
REQUIRE_THROWS(caller.call(cmds[i], {"1199"}, -1, PUT)); // min
else {
if (det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(
caller.call(cmds[i], {"1040"}, -1, PUT)); // min v_a
} else {
REQUIRE_THROWS(
caller.call(cmds[i], {"635"}, -1, PUT)); // min v_a
}
}
if (det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(caller.call(cmds[i], {"2662"}, -1, PUT)); // max
} else {
REQUIRE_THROWS(caller.call(cmds[i], {"2469"}, -1, PUT)); // max
}
{
std::ostringstream oss;
caller.call(cmds[i], {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == cmds[i] + " 0\n");
}
{
std::ostringstream oss1, oss2;
caller.call(cmds[i], {"1200"}, -1, PUT, oss1);
REQUIRE(oss1.str() == cmds[i] + " 1200\n");
caller.call(cmds[i], {}, -1, GET, oss2);
REQUIRE(oss2.str() == cmds[i] + " 1200\n");
}
{
auto vlimit = det.getDAC(defs::V_LIMIT)[0];
det.setDAC(defs::V_LIMIT, 1500, true, {0});
REQUIRE_NOTHROW(caller.call(cmds[i], {"1200"}, -1, PUT));
if (vlimit < 0)
vlimit = 0;
det.setDAC(defs::V_LIMIT, vlimit, true, {0});
}
for (int imod = 0; imod != det.size(); ++imod) {
if (det_type == defs::XILINX_CHIPTESTBOARD &&
prev_val[imod] == -100) {
prev_val[imod] = 0;
}
det.setPower(indices[i], prev_val[imod], {imod});
}
} else {
REQUIRE_THROWS(caller.call(cmds[i], {}, -1, GET));
try {
caller.call(cmds[i], {}, -1, GET);
} catch (const std::exception &e) {
REQUIRE(std::string(e.what()).find(
"removed and is no longer available") !=
std::string::npos);
}
}
}
TEST_CASE("v_io", "[.detectorintegration]") {
TEST_CASE("power", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
// better not to play with setting it
REQUIRE_NOTHROW(caller.call("v_io", {}, -1, GET));
} else {
REQUIRE_THROWS(caller.call("v_io", {}, -1, GET));
}
}
TEST_CASE("v_chip", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) {
// better not to play with setting it
REQUIRE_NOTHROW(caller.call("v_chip", {}, -1, GET));
std::vector<std::string> cmds{"v_a", "v_b", "v_c", "v_d", "v_io"};
auto indices = det.getPowerList();
std::vector<bool> prev_val(cmds.size());
for (size_t iPower = 0; iPower < cmds.size(); ++iPower) {
prev_val[iPower] = det.isPowerEnabled(indices[iPower]);
}
REQUIRE_THROWS(caller.call("power", {"vrandom"}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"v_chip"}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"on", "v_a"}, -1, PUT));
{
std::ostringstream oss;
caller.call("power", {"v_a", "on"}, -1, PUT, oss);
REQUIRE(oss.str() == "power [v_a] on\n");
}
{
std::ostringstream oss;
caller.call("power", {"v_a"}, -1, GET, oss);
REQUIRE(oss.str() == "power v_a on\n");
}
{
std::ostringstream oss;
caller.call("power", {"v_a", "v_c", "on"}, -1, PUT, oss);
REQUIRE(oss.str() == "power [v_a, v_c] on\n");
}
{
std::ostringstream oss1, oss2, oss3;
caller.call("power", {"v_a", "v_b", "off"}, -1, PUT);
caller.call("power", {"v_a"}, -1, GET, oss1);
caller.call("power", {"v_b"}, -1, GET, oss2);
caller.call("power", {"v_c"}, -1, GET, oss3);
REQUIRE(oss1.str() == "power v_a off\n");
REQUIRE(oss2.str() == "power v_b off\n");
REQUIRE(oss3.str() == "power v_c on\n");
}
{
// power name
std::ostringstream oss1;
det.setPowerName(defs::V_POWER_B, "pwrname_v_b");
det.setPowerName(defs::V_POWER_C, "pwrname_v_c");
det.setPowerName(defs::V_POWER_D, "pwrname_v_d");
caller.call("power", {"pwrname_v_c", "pwrname_v_d", "on"}, -1, PUT,
oss1);
std::ostringstream oss[8];
caller.call("power", {"v_a"}, -1, GET, oss[0]);
caller.call("power", {"pwrname_v_b"}, -1, GET, oss[1]);
caller.call("power", {"v_b"}, -1, GET, oss[2]);
caller.call("power", {"pwrname_v_c"}, -1, GET, oss[3]);
caller.call("power", {"v_c"}, -1, GET, oss[4]);
caller.call("power", {"pwrname_v_d"}, -1, GET, oss[5]);
caller.call("power", {"v_d"}, -1, GET, oss[6]);
caller.call("power", {"v_io"}, -1, GET, oss[7]);
REQUIRE(oss[0].str() == "power v_a off\n");
REQUIRE(oss[1].str() == "power pwrname_v_b off\n");
REQUIRE(oss[2].str() == "power v_b off\n");
REQUIRE(oss[3].str() == "power pwrname_v_c on\n");
REQUIRE(oss[4].str() == "power v_c on\n");
REQUIRE(oss[5].str() == "power pwrname_v_d on\n");
REQUIRE(oss[6].str() == "power v_d on\n");
REQUIRE(oss[7].str() == "power v_io off\n");
}
// all
{
std::ostringstream oss;
caller.call("power", {"all"}, -1, GET, oss);
REQUIRE(
oss.str() ==
"power {v_a: off, v_b: off, v_c: on, v_d: on, v_io: off}\n");
}
{ // power on all
caller.call("power", {"all", "on"}, -1, PUT);
std::ostringstream oss1, oss2, oss3, oss4, oss5;
caller.call("power", {"v_a"}, -1, GET, oss1);
caller.call("power", {"v_b"}, -1, GET, oss2);
caller.call("power", {"v_c"}, -1, GET, oss3);
caller.call("power", {"v_d"}, -1, GET, oss4);
caller.call("power", {"v_io"}, -1, GET, oss5);
REQUIRE(oss1.str() == "power v_a on\n");
REQUIRE(oss2.str() == "power v_b on\n");
REQUIRE(oss3.str() == "power v_c on\n");
REQUIRE(oss4.str() == "power v_d on\n");
REQUIRE(oss5.str() == "power v_io on\n");
std::ostringstream oss;
caller.call("power", {"all"}, -1, GET, oss);
REQUIRE(oss.str() == "power all on\n");
}
for (size_t iPower = 0; iPower < cmds.size(); ++iPower) {
det.setPowerEnabled(std::vector{indices[iPower]}, prev_val[iPower]);
}
} else {
REQUIRE_THROWS(caller.call("v_chip", {}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"v_a"}, -1, GET));
}
}
@@ -33,28 +33,34 @@ void test_valid_port_caller(const std::string &command,
}
void test_dac_caller(defs::dacIndex index, const std::string &dacname,
int dacvalue) {
int dacvalue, bool mV) {
Detector det;
Caller caller(&det);
std::ostringstream oss_set, oss_get;
auto dacstr = std::to_string(dacvalue);
std::string dac = dacname;
auto value = std::to_string(dacvalue);
auto previous = det.getDAC(index, false);
// chip test board
if (dacname == "dac") {
auto dacIndexstr = std::to_string(static_cast<int>(index));
caller.call(dacname, {dacIndexstr, dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() ==
dacname + " " + dacIndexstr + " " + dacstr + "\n");
caller.call(dacname, {dacIndexstr}, -1, GET, oss_get);
REQUIRE(oss_get.str() ==
dacname + " " + dacIndexstr + " " + dacstr + "\n");
dac = std::to_string(static_cast<int>(index));
}
// other detectors
else {
caller.call("dac", {dacname, dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == "dac " + dacname + " " + dacstr + "\n");
caller.call("dac", {dacname}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "dac " + dacname + " " + dacstr + "\n");
{
std::ostringstream oss;
std::vector<std::string> args = {dac, value};
if (mV)
args.push_back("mV");
std::cout << "args:" << ToString(args) << std::endl;
caller.call("dac", args, -1, PUT, oss);
REQUIRE(oss.str() == std::string("dac ") + dac + " " + value +
(mV ? " mV\n" : "\n"));
}
{
std::ostringstream oss;
std::vector<std::string> args = {dac};
if (mV)
args.push_back("mV");
caller.call("dac", args, -1, GET, oss);
REQUIRE(oss.str() ==
"dac " + dac + " " + value + (mV ? " mV\n" : "\n"));
}
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
@@ -78,7 +78,7 @@ void test_valid_port_caller(const std::string &command,
int detector_id, int action);
void test_dac_caller(slsDetectorDefs::dacIndex index,
const std::string &dacname, int dacvalue);
const std::string &dacname, int dacvalue, bool mV = false);
void test_onchip_dac_caller(slsDetectorDefs::dacIndex index,
const std::string &dacname, int dacvalue);
@@ -19,17 +19,11 @@ using test::PUT;
/* dacs */
// not implemented at the moment
TEST_CASE("configtransceiver", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(caller.call("configtransceiver", {}, -1, GET));
REQUIRE_NOTHROW(caller.call("configtransceiver", {}, -1, PUT));
} else {
REQUIRE_THROWS(caller.call("configtransceiver", {}, -1, PUT));
REQUIRE_THROWS(caller.call("configtransceiver", {}, -1, GET));
}
REQUIRE_THROWS(caller.call("configtransceiver", {}, -1, PUT));
REQUIRE_THROWS(caller.call("configtransceiver", {}, -1, GET));
}
} // namespace sls
@@ -1547,9 +1547,9 @@ TEST_CASE("powerchip", "[.detectorintegration]") {
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH ||
det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2 ||
det_type == defs::XILINX_CHIPTESTBOARD) {
auto prev_val = det.getPowerChip();
det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
auto prev_val =
det.getPowerChip().tsquash("Inconsistent power chip values");
{
std::ostringstream oss;
caller.call("powerchip", {"1"}, -1, PUT, oss);
@@ -1583,10 +1583,7 @@ TEST_CASE("powerchip", "[.detectorintegration]") {
REQUIRE(oss.str() == "powerchip 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPowerChip(prev_val[i], {i});
if (det_type == defs::XILINX_CHIPTESTBOARD) {
det.configureTransceiver();
}
det.setPowerChip(prev_val, {i});
}
} else {
REQUIRE_THROWS(caller.call("powerchip", {}, -1, GET));
+5
View File
@@ -37,6 +37,8 @@ std::string ToString(const defs::externalSignalFlag s);
std::string ToString(const defs::readoutMode s);
std::string ToString(const defs::dacIndex s);
std::string ToString(const std::vector<defs::dacIndex> &vec);
std::string ToString(const defs::powerIndex s);
std::string ToString(const std::vector<defs::powerIndex> &vec);
std::string ToString(const defs::burstMode s);
std::string ToString(const defs::timingSourceType s);
std::string ToString(const defs::M3_GainCaps s);
@@ -49,6 +51,7 @@ std::string ToString(const defs::timingInfoDecoder s);
std::string ToString(const defs::collectionMode s);
std::string ToString(bool value);
std::string ToString(bool value, defs::boolFormat format);
std::string ToString(const slsDetectorDefs::xy &coord);
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
@@ -316,6 +319,7 @@ template <> defs::fileFormat StringTo(const std::string &s);
template <> defs::externalSignalFlag StringTo(const std::string &s);
template <> defs::readoutMode StringTo(const std::string &s);
template <> defs::dacIndex StringTo(const std::string &s);
template <> defs::powerIndex StringTo(const std::string &s);
template <> defs::burstMode StringTo(const std::string &s);
template <> defs::timingSourceType StringTo(const std::string &s);
template <> defs::M3_GainCaps StringTo(const std::string &s);
@@ -335,6 +339,7 @@ template <> uint32_t StringTo(const std::string &s);
template <> uint64_t StringTo(const std::string &s);
template <> int StringTo(const std::string &s);
template <> bool StringTo(const std::string &s);
bool StringTo(const std::string &s, defs::boolFormat format);
template <> int64_t StringTo(const std::string &s);
/** For types with a .str() method use this for conversion */
+16 -12
View File
@@ -104,6 +104,8 @@ class slsDetectorDefs {
/** return values */
enum { OK, FAIL };
enum boolFormat { TrueFalse, OnOff, OneZero };
/** staus mask */
enum runStatus {
IDLE,
@@ -394,18 +396,6 @@ typedef struct {
TEMPERATURE_FPGA2,
TEMPERATURE_FPGA3,
TRIMBIT_SCAN,
V_POWER_A = 100,
V_POWER_B = 101,
V_POWER_C = 102,
V_POWER_D = 103,
V_POWER_IO = 104,
V_POWER_CHIP = 105,
I_POWER_A = 106,
I_POWER_B = 107,
I_POWER_C = 108,
I_POWER_D = 109,
I_POWER_IO = 110,
V_LIMIT = 111,
SLOW_ADC0 = 1000,
SLOW_ADC1,
SLOW_ADC2,
@@ -417,6 +407,20 @@ typedef struct {
SLOW_ADC_TEMP
};
enum powerIndex {
V_POWER_A,
V_POWER_B,
V_POWER_C,
V_POWER_D,
V_POWER_IO,
V_POWER_CHIP,
I_POWER_A,
I_POWER_B,
I_POWER_C,
I_POWER_D,
I_POWER_IO
};
/**
detector settings indexes
*/
@@ -301,6 +301,13 @@ enum detFuncs {
F_SET_PATTERN_WAIT_INTERVAL,
F_SPI_READ,
F_SPI_WRITE,
F_GET_POWER,
F_SET_POWER,
F_GET_POWER_DAC,
F_SET_POWER_DAC,
F_GET_POWER_ADC,
F_GET_VOLTAGE_LIMIT,
F_SET_VOLTAGE_LIMIT,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 512, /**< detector function should not exceed this
@@ -713,6 +720,13 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_PATTERN_WAIT_INTERVAL: return "F_SET_PATTERN_WAIT_INTERVAL";
case F_SPI_READ: return "F_SPI_READ";
case F_SPI_WRITE: return "F_SPI_WRITE";
case F_GET_POWER: return "F_GET_POWER";
case F_SET_POWER: return "F_SET_POWER";
case F_GET_POWER_DAC: return "F_GET_POWER_DAC";
case F_SET_POWER_DAC: return "F_SET_POWER_DAC";
case F_GET_POWER_ADC: return "F_GET_POWER_ADC";
case F_GET_VOLTAGE_LIMIT: return "F_GET_VOLTAGE_LIMIT";
case F_SET_VOLTAGE_LIMIT: return "F_SET_VOLTAGE_LIMIT";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
+7 -7
View File
@@ -3,10 +3,10 @@
/** API versions */
#define APILIB "0.0.0 0x250909"
#define APIRECEIVER "0.0.0 0x250822"
#define APICTB "0.0.0 0x260317"
#define APIGOTTHARD2 "0.0.0 0x260227"
#define APIMOENCH "0.0.0 0x260227"
#define APIEIGER "0.0.0 0x260227"
#define APIXILINXCTB "0.0.0 0x260317"
#define APIJUNGFRAU "0.0.0 0x260227"
#define APIMYTHEN3 "0.0.0 0x260227"
#define APICTB "0.0.0 0x260421"
#define APIGOTTHARD2 "0.0.0 0x260420"
#define APIMOENCH "0.0.0 0x260420"
#define APIEIGER "0.0.0 0x260420"
#define APIXILINXCTB "0.0.0 0x260420"
#define APIJUNGFRAU "0.0.0 0x260420"
#define APIMYTHEN3 "0.0.0 0x260420"
+90 -7
View File
@@ -7,6 +7,17 @@ namespace sls {
std::string ToString(bool value) { return value ? "1" : "0"; }
std::string ToString(bool value, defs::boolFormat format) {
switch (format) {
case defs::boolFormat::TrueFalse:
return value ? "true" : "false";
case defs::boolFormat::OnOff:
return value ? "on" : "off";
default:
return value ? "1" : "0";
}
}
std::string ToString(const slsDetectorDefs::xy &coord) {
std::ostringstream oss;
oss << '[' << coord.x << ", " << coord.y << ']';
@@ -552,6 +563,38 @@ std::string ToString(const std::vector<defs::dacIndex> &vec) {
return os.str();
}
std::string ToString(const defs::powerIndex s) {
switch (s) {
case defs::V_POWER_A:
return std::string("v_a");
case defs::V_POWER_B:
return std::string("v_b");
case defs::V_POWER_C:
return std::string("v_c");
case defs::V_POWER_D:
return std::string("v_d");
case defs::V_POWER_IO:
return std::string("v_io");
case defs::V_POWER_CHIP:
return std::string("v_chip");
default:
return std::string("Unknown");
}
}
std::string ToString(const std::vector<defs::powerIndex> &vec) {
std::ostringstream os;
os << '[';
if (!vec.empty()) {
auto it = vec.begin();
os << ToString(*it++);
while (it != vec.end())
os << ", " << ToString(*it++);
}
os << ']';
return os.str();
}
std::string ToString(const defs::burstMode s) {
switch (s) {
case defs::BURST_INTERNAL:
@@ -1018,6 +1061,22 @@ template <> defs::dacIndex StringTo(const std::string &s) {
throw RuntimeError("Unknown dac Index " + s);
}
template <> defs::powerIndex StringTo(const std::string &s) {
if (s == "v_a")
return defs::V_POWER_A;
if (s == "v_b")
return defs::V_POWER_B;
if (s == "v_c")
return defs::V_POWER_C;
if (s == "v_d")
return defs::V_POWER_D;
if (s == "v_io")
return defs::V_POWER_IO;
if (s == "v_chip")
return defs::V_POWER_CHIP;
throw RuntimeError("Unknown power Index " + s);
}
template <> defs::burstMode StringTo(const std::string &s) {
if (s == "burst_internal")
return defs::BURST_INTERNAL;
@@ -1165,14 +1224,38 @@ template <> int StringTo(const std::string &s) {
}
template <> bool StringTo(const std::string &s) {
int i = std::stoi(s, nullptr, 10);
switch (i) {
case 0:
return false;
case 1:
return true;
return StringTo(s, defs::boolFormat::OneZero);
}
bool StringTo(const std::string &s, defs::boolFormat format) {
switch (format) {
case defs::boolFormat::TrueFalse: {
if (s == "true")
return true;
if (s == "false")
return false;
throw RuntimeError("Unknown boolean. Expecting 'true' or 'false'.");
}
case defs::boolFormat::OnOff: {
if (s == "on")
return true;
if (s == "off")
return false;
throw RuntimeError("Unknown boolean. Expecting 'on' or 'off'.");
}
case defs::boolFormat::OneZero: {
int i = std::stoi(s, nullptr, 10);
switch (i) {
case 0:
return false;
case 1:
return true;
default:
throw RuntimeError("Unknown boolean. Expecting 0 or 1.");
}
}
default:
throw RuntimeError("Unknown boolean. Expecting be 0 or 1.");
throw RuntimeError("Unknown boolean format.");
}
}
+18
View File
@@ -26,6 +26,24 @@ TEST_CASE("Convert string to bool", "[support]") {
REQUIRE(StringTo<bool>("0") == false);
}
TEST_CASE("Convert bool format to string", "[support]") {
REQUIRE(ToString(true, defs::boolFormat::TrueFalse) == "true");
REQUIRE(ToString(false, defs::boolFormat::TrueFalse) == "false");
REQUIRE(ToString(true, defs::boolFormat::OnOff) == "on");
REQUIRE(ToString(false, defs::boolFormat::OnOff) == "off");
REQUIRE(ToString(true, defs::boolFormat::OneZero) == "1");
REQUIRE(ToString(false, defs::boolFormat::OneZero) == "0");
}
TEST_CASE("Convert string to bool format", "[support]") {
REQUIRE(StringTo("1", defs::boolFormat::OneZero) == true);
REQUIRE(StringTo("0", defs::boolFormat::OneZero) == false);
REQUIRE(StringTo("true", defs::boolFormat::TrueFalse) == true);
REQUIRE(StringTo("false", defs::boolFormat::TrueFalse) == false);
REQUIRE(StringTo("on", defs::boolFormat::OnOff) == true);
REQUIRE(StringTo("off", defs::boolFormat::OnOff) == false);
}
TEST_CASE("Integer conversions", "[support]") {
REQUIRE(ToString(0) == "0");
REQUIRE(ToString(1) == "1");
+3 -3
View File
@@ -305,11 +305,11 @@ def loadConfig(name, rx_hostname = 'localhost', settingsdir = None, log_file_fp
if num_interfaces == 2:
d.udp_dstip2 = 'auto'
if name == "jungfrau" or name == "moench" or name == "xilinx_ctb":
if name == "jungfrau" or name == "moench":
d.powerchip = 1
if name == "xilinx_ctb":
d.configureTransceiver()
#if name == "xilinx_ctb":
# d.configureTransceiver()
if settingsdir is not None and name in ['eiger', 'mythen3']:
d.settingspath = settingsdir + '/' + name + '/'