mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-05-08 00:52:05 +02:00
CTB frequency rounding, CTB frequency measurement, CTB frequency units (#1423)
* round CTB clocks to next closest possible value, added freq measurement * added time for firmware to measrue actual value after frequency change * add check for backwards compatibility * change CTB and XCTB clock values to MHz, TODO: units and validation errors * changed runclk command to use units and float, TODO: dbit, adcclk, why is everything called StringTo ? * do the same for dbit and adcclk * added tolerance to exptime, fixed test * update default values in server defs * added virtual check in Altera_PLL, update testcases * change python and pyctbgui to accept and return floating point MHz * update help and comments * Dev/ctb clocks fix (#1434) * introduced new type Hz, typetraits, String conversions, command generation (not yet generated) * incorrect unit typo * cmd generation and compiles * default to MHz, removed space between units for consistency with timers, min and max checks for clks * in python, but need to change the default to Hz again for clean code and intuition * allow ints, doubles, implicit conversions * dont allow raw ints, doubles and implicit conversions * fixed tests * added operators for Hz in python * fix test for min clk for xilinx ctb * fix test * fix python tests * fixed xilinx period and default clks * test fix * removed the 3 clock cycle check for ctb and implemented properly the max adc clk frq for altera ctb * removing 3 clock cycle code from xilinx as well * formatting * loadpattern before 3 clk cycles code * actualtime and measurement time to be implemented in 100ns already in fw * fix tests * pyzmq dependency forthe tests * fixed pyctbgui for freq * insert tolerance check again * also added tolerance check for patwaittime * formatting * minor: rounding test * removed Rep redundant in ToString for freq * intro frequency unit enums, removed unnecessary template behavior for ToString with freq unit, switching from parsing string unit argument to the enum argument for ToString, adding parsing string to unit at CLI boundary * minor, and binaries * minor, default clk vals are 0 but set up at detector setup * get frequency only for that unit * tolerance process * missed in previous commit * some more changes to exptime and validations * ctb is probably done * periodleft and delayleft * fixed xilinx freq conv as well * fixed m3 bug, binaries * xilinx: setup also done in stop server so that the clk is not 0 * missed a test marker * binaries in * review fixes, simpler validation of timers in ctb and xilinx ctb * typo fix * format * fix tests --------- Co-authored-by: Martin Mueller <martin.mueller@psi.ch> Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
This commit is contained in:
@@ -34,6 +34,7 @@ jobs:
|
||||
python3.12 -m pip install pytest
|
||||
python3.12 -m pip install colorama
|
||||
python3.12 -m pip install numpy
|
||||
python3.12 -m pip install pyzmq
|
||||
|
||||
- name: Python unit tests
|
||||
working-directory: ${{gitea.workspace}}
|
||||
|
||||
@@ -32,6 +32,7 @@ jobs:
|
||||
python3.12 -m pip install pytest
|
||||
python3.12 -m pip install colorama
|
||||
python3.12 -m pip install numpy
|
||||
python3.12 -m pip install pyzmq
|
||||
|
||||
- name: Python unit tests
|
||||
working-directory: ${{gitea.workspace}}
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: 'pip'
|
||||
- run: pip install pytest numpy colorama
|
||||
- run: pip install pytest numpy colorama pyzmq
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
|
||||
@@ -7,7 +7,7 @@ import zmq
|
||||
from PyQt5 import QtWidgets, uic
|
||||
import logging
|
||||
|
||||
from slsdet import readoutMode, runStatus, detectorType
|
||||
from slsdet import readoutMode, runStatus, detectorType, Hz, MHz, kHz
|
||||
from pyctbgui.utils.defines import Defines
|
||||
from pyctbgui.utils.numpyWriter.npy_writer import NumpyFileManager
|
||||
from pyctbgui.utils.numpyWriter.npz_writer import NpzFileWriter
|
||||
@@ -58,12 +58,6 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
self.view.spinBoxADCPipeline.setDisabled(True)
|
||||
self.view.spinBoxDBITPhase.setDisabled(True)
|
||||
self.view.spinBoxDBITPipeline.setDisabled(True)
|
||||
self.view.labelRunF.setText("Run Clock Frequency (kHz):")
|
||||
self.view.labelDBITF.setText("DBIT Clock Frequency (kHz):")
|
||||
self.view.labelADCF.setText("ADC Clock Frequency (kHz):")
|
||||
self.view.spinBoxRunF.setMaximum(250000)
|
||||
self.view.spinBoxDBITF.setMaximum(250000)
|
||||
self.view.spinBoxADCF.setMaximum(250000)
|
||||
|
||||
def connect_ui(self):
|
||||
# For Acquistions Tab
|
||||
@@ -74,8 +68,11 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
|
||||
if self.det.type in [detectorType.CHIPTESTBOARD, detectorType.XILINX_CHIPTESTBOARD]:
|
||||
self.view.spinBoxRunF.editingFinished.connect(self.setRunFrequency)
|
||||
self.view.comboBoxRunF.currentIndexChanged.connect(self.getRunFrequency)
|
||||
self.view.spinBoxADCF.editingFinished.connect(self.setADCFrequency)
|
||||
self.view.comboBoxADCF.currentIndexChanged.connect(self.getADCFrequency)
|
||||
self.view.spinBoxDBITF.editingFinished.connect(self.setDBITFrequency)
|
||||
self.view.comboBoxDBITF.currentIndexChanged.connect(self.getDBITFrequency)
|
||||
if self.det.type == detectorType.CHIPTESTBOARD:
|
||||
self.view.spinBoxADCPhase.editingFinished.connect(self.setADCPhase)
|
||||
self.view.spinBoxADCPipeline.editingFinished.connect(self.setADCPipeline)
|
||||
@@ -195,20 +192,43 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
self.view.comboBoxROMode.currentIndexChanged.connect(self.setReadOut)
|
||||
self.getReadout()
|
||||
|
||||
|
||||
def _getFrequency(self, det_attr, spinbox, spinSetter, combobox):
|
||||
spinbox.editingFinished.disconnect()
|
||||
f = getattr(self.det, det_attr).value
|
||||
unit = combobox.currentIndex()
|
||||
|
||||
if unit == 2: #Hz
|
||||
spinbox.setValue(f)
|
||||
elif unit == 1: #kHz
|
||||
spinbox.setValue(f / 1e3)
|
||||
else:
|
||||
spinbox.setValue(f / 1e6)
|
||||
|
||||
spinbox.editingFinished.connect(spinSetter)
|
||||
|
||||
def _setFrequency(self, det_attr, spinbox, combobox, title, getter):
|
||||
value = spinbox.value()
|
||||
idx = combobox.currentIndex()
|
||||
|
||||
if idx == 0:
|
||||
val = MHz(value)
|
||||
elif idx == 1:
|
||||
val = kHz(value)
|
||||
else:
|
||||
val = Hz((int)(value))
|
||||
|
||||
try:
|
||||
setattr(self.det, det_attr, val)
|
||||
except Exception as e:
|
||||
QtWidgets.QMessageBox.warning(self.mainWindow, title + " Fail", str(e), QtWidgets.QMessageBox.Ok)
|
||||
getter()
|
||||
|
||||
def getRunFrequency(self):
|
||||
self.view.spinBoxRunF.editingFinished.disconnect()
|
||||
self.view.spinBoxRunF.setValue(self.det.runclk)
|
||||
self.view.spinBoxRunF.editingFinished.connect(self.setRunFrequency)
|
||||
self._getFrequency('runclk', self.view.spinBoxRunF, self.setRunFrequency, self.view.comboBoxRunF)
|
||||
|
||||
def setRunFrequency(self):
|
||||
self.view.spinBoxRunF.editingFinished.disconnect()
|
||||
try:
|
||||
self.det.runclk = self.view.spinBoxRunF.value()
|
||||
except Exception as e:
|
||||
QtWidgets.QMessageBox.warning(self.mainWindow, "Run Frequency Fail", str(e), QtWidgets.QMessageBox.Ok)
|
||||
# TODO: handling double event exceptions
|
||||
self.view.spinBoxRunF.editingFinished.connect(self.setRunFrequency)
|
||||
self.getRunFrequency()
|
||||
self._setFrequency('runclk', self.view.spinBoxRunF, self.view.comboBoxRunF, "Run Frequency Fail", self.getRunFrequency)
|
||||
|
||||
def getTransceiver(self):
|
||||
self.view.spinBoxTransceiver.editingFinished.disconnect()
|
||||
@@ -260,19 +280,10 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
self.getDigital()
|
||||
|
||||
def getADCFrequency(self):
|
||||
self.view.spinBoxADCF.editingFinished.disconnect()
|
||||
self.view.spinBoxADCF.setValue(self.det.adcclk)
|
||||
self.view.spinBoxADCF.editingFinished.connect(self.setADCFrequency)
|
||||
self._getFrequency('adcclk', self.view.spinBoxADCF, self.setADCFrequency, self.view.comboBoxADCF)
|
||||
|
||||
def setADCFrequency(self):
|
||||
self.view.spinBoxADCF.editingFinished.disconnect()
|
||||
try:
|
||||
self.det.adcclk = self.view.spinBoxADCF.value()
|
||||
except Exception as e:
|
||||
QtWidgets.QMessageBox.warning(self.mainWindow, "ADC Frequency Fail", str(e), QtWidgets.QMessageBox.Ok)
|
||||
# TODO: handling double event exceptions
|
||||
self.view.spinBoxADCF.editingFinished.connect(self.setADCFrequency)
|
||||
self.getADCFrequency()
|
||||
self._setFrequency('adcclk', self.view.spinBoxADCF, self.view.comboBoxADCF, "ADC Frequency Fail", self.getADCFrequency)
|
||||
|
||||
def getADCPhase(self):
|
||||
self.view.spinBoxADCPhase.editingFinished.disconnect()
|
||||
@@ -305,19 +316,10 @@ class AcquisitionTab(QtWidgets.QWidget):
|
||||
self.getADCPipeline()
|
||||
|
||||
def getDBITFrequency(self):
|
||||
self.view.spinBoxDBITF.editingFinished.disconnect()
|
||||
self.view.spinBoxDBITF.setValue(self.det.dbitclk)
|
||||
self.view.spinBoxDBITF.editingFinished.connect(self.setDBITFrequency)
|
||||
self._getFrequency('dbitclk', self.view.spinBoxDBITF, self.setDBITFrequency, self.view.comboBoxDBITF)
|
||||
|
||||
def setDBITFrequency(self):
|
||||
self.view.spinBoxDBITF.editingFinished.disconnect()
|
||||
try:
|
||||
self.det.dbitclk = self.view.spinBoxDBITF.value()
|
||||
except Exception as e:
|
||||
QtWidgets.QMessageBox.warning(self.mainWindow, "DBit Frequency Fail", str(e), QtWidgets.QMessageBox.Ok)
|
||||
# TODO: handling double event exceptions
|
||||
self.view.spinBoxDBITF.editingFinished.connect(self.setDBITFrequency)
|
||||
self.getDBITFrequency()
|
||||
self._setFrequency('dbitclk', self.view.spinBoxDBITF, self.view.comboBoxDBITF, "DBit Frequency Fail", self.getDBITFrequency)
|
||||
|
||||
def getDBITPhase(self):
|
||||
self.view.spinBoxDBITPhase.editingFinished.disconnect()
|
||||
|
||||
+377
-238
@@ -36,7 +36,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_19">
|
||||
<item row="1" column="5">
|
||||
<widget class="QSpinBox" name="spinBoxRunF">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxRunF">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -45,13 +45,13 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>120</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>120</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -61,18 +61,17 @@
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_398">
|
||||
<property name="text">
|
||||
<string>Read Out Mode: </string>
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -117,13 +116,67 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_398">
|
||||
<property name="text">
|
||||
<string>Read Out Mode: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="labelRunF">
|
||||
<property name="text">
|
||||
<string>Run Clock Frequency (MHz):</string>
|
||||
<string>Run Clock Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QComboBox" name="comboBoxRunF">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>MHz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>kHz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hz</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="frame_13">
|
||||
@@ -152,13 +205,13 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>185</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>185</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -210,6 +263,12 @@
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>190</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
@@ -217,16 +276,128 @@
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="2" column="3">
|
||||
<widget class="QLabel" name="labelDBITF">
|
||||
<property name="minimumSize">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelADCPipeline">
|
||||
<property name="text">
|
||||
<string>ADC Pipeline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<widget class="QLabel" name="labelDBITPhase">
|
||||
<property name="text">
|
||||
<string>DBIT Clock Frequency (MHz):</string>
|
||||
<string>DBIT Clock Phase (a.u.):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxADCF">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelADCPhase">
|
||||
<property name="text">
|
||||
<string>ADC Clock Phase (a.u.):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="5">
|
||||
<widget class="QLabel" name="labelDBITPipeline">
|
||||
<property name="text">
|
||||
<string>DBIT Pipeline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="labelDigital">
|
||||
<property name="text">
|
||||
<string>Digital Samples:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxDBITF">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -245,213 +416,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ADC Clock Frequency (MHz):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QSpinBox" name="spinBoxDBITPhase">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLabel" name="labelDBITPipeline">
|
||||
<property name="text">
|
||||
<string>DBIT Pipeline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxADCF">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxADCPipeline">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelADCPipeline">
|
||||
<property name="text">
|
||||
<string>ADC Pipeline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelADCPhase">
|
||||
<property name="text">
|
||||
<string>ADC Clock Phase (a.u.):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="labelDBITPhase">
|
||||
<property name="text">
|
||||
<string>DBIT Clock Phase (a.u.):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QSpinBox" name="spinBoxDBITF">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="QSpinBox" name="spinBoxDBITPipeline">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxADCPhase">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
<string>ADC Clock Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -462,7 +427,51 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="2" column="5">
|
||||
<widget class="QLabel" name="labelDBITF">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DBIT Clock Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="comboBoxADCF">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>MHz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>kHz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hz</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxAnalog">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@@ -472,13 +481,13 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>185</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>185</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -493,14 +502,60 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="labelDigital">
|
||||
<property name="text">
|
||||
<string>Digital Samples:</string>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxADCPhase">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxADCPipeline">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxDigital">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@@ -510,13 +565,13 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>185</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<width>185</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -534,6 +589,90 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="6" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxDBITPhase">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="6" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxDBITPipeline">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QComboBox" name="comboBoxDBITF">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>MHz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>kHz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hz</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="frame_11">
|
||||
|
||||
@@ -13,6 +13,7 @@ pybind11_add_module(_slsdet
|
||||
src/DurationWrapper.cpp
|
||||
src/pedestal.cpp
|
||||
src/bit.cpp
|
||||
src/frequency.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(_slsdet PUBLIC
|
||||
|
||||
@@ -34,6 +34,9 @@ scanParameters = _slsdet.scanParameters
|
||||
currentSrcParameters = _slsdet.currentSrcParameters
|
||||
DurationWrapper = _slsdet.DurationWrapper
|
||||
pedestalParameters = _slsdet.pedestalParameters
|
||||
Hz = _slsdet.Hz
|
||||
kHz = _slsdet.kHz
|
||||
MHz = _slsdet.MHz
|
||||
|
||||
import os
|
||||
def read_version():
|
||||
|
||||
+32
-13
@@ -14,11 +14,12 @@ powerIndex = slsDetectorDefs.powerIndex
|
||||
detectorType = slsDetectorDefs.detectorType
|
||||
streamingInterface = slsDetectorDefs.streamingInterface
|
||||
|
||||
|
||||
defs = slsDetectorDefs
|
||||
|
||||
from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask
|
||||
from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list
|
||||
from ._slsdet import xy, freeSharedMemory, getUserDetails
|
||||
from ._slsdet import xy, Hz, freeSharedMemory, getUserDetails
|
||||
from .gaincaps import Mythen3GainCapsWrapper
|
||||
from . import utils as ut
|
||||
from .proxy import JsonProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
|
||||
@@ -3441,15 +3442,21 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def runclk(self):
|
||||
"""
|
||||
[Ctb] Sets Run clock frequency in MHz. \n
|
||||
[Xilinx Ctb] Sets Run clock frequency in kHz.
|
||||
"""
|
||||
[Ctb][Xilinx Ctb] Sets Run clock frequency.
|
||||
|
||||
Example
|
||||
--------
|
||||
>>> d.runclk
|
||||
>>> 10MHz
|
||||
>>> d.runclk = MHz(5)
|
||||
>>> d.runclk = Hz(5 * 1000 * 1000)
|
||||
>>> d.runclk = kHz(2000)
|
||||
"""
|
||||
return self.getRUNClock()
|
||||
|
||||
@runclk.setter
|
||||
def runclk(self, freq):
|
||||
ut.set_using_dict(self.setRUNClock, freq)
|
||||
ut.set_using_dict(self.setRUNClock, freq)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -3526,10 +3533,16 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def dbitclk(self):
|
||||
"""
|
||||
[Ctb] Sets clock for latching the digital bits in MHz. \n
|
||||
[Xilinx Ctb] clock for latching the digital bits in kHz.
|
||||
"""
|
||||
[Ctb][Xilinx Ctb] Sets clock for latching the digital bits.
|
||||
|
||||
Example
|
||||
--------
|
||||
>>> d.dbitclk
|
||||
>>> 10MHz
|
||||
>>> d.dbitclk = MHz(5)
|
||||
>>> d.dbitclk = Hz(5 * 1000 * 1000)
|
||||
>>> d.dbitclk = kHz(2000)
|
||||
"""
|
||||
return self.getDBITClock()
|
||||
|
||||
@dbitclk.setter
|
||||
@@ -3657,10 +3670,16 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def adcclk(self):
|
||||
"""
|
||||
[Ctb] Sets ADC clock frequency in MHz. \n
|
||||
[Xilinx Ctb] Sets ADC clock frequency in kHz.
|
||||
"""
|
||||
[Ctb][Xilinx Ctb] Sets ADC clock frequency.
|
||||
|
||||
Example
|
||||
--------
|
||||
>>> d.adcclk
|
||||
>>> 10MHz
|
||||
>>> d.adcclk = MHz(5)
|
||||
>>> d.adcclk = Hz(5 * 1000 * 1000)
|
||||
>>> d.adcclk = kHz(2000)
|
||||
"""
|
||||
return self.getADCClock()
|
||||
|
||||
@adcclk.setter
|
||||
@@ -3671,7 +3690,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def syncclk(self):
|
||||
"""
|
||||
[Ctb] Sync clock in MHz.
|
||||
[Ctb] Sync clock.
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
@@ -3704,7 +3723,7 @@ class Detector(CppDetectorApi):
|
||||
[Ctb][Mythen3][Xilinx Ctb] Gets the pattern file name including path of the last pattern uploaded. Returns an empty if nothing was uploaded or via a server default
|
||||
file
|
||||
"""
|
||||
return self.getPatterFileName()
|
||||
return self.getPatternFileName()
|
||||
|
||||
def patternstart(self):
|
||||
"""[Ctb][Mythen3][Xilinx Ctb] Starts pattern. """
|
||||
|
||||
+15
-15
@@ -1529,23 +1529,31 @@ void init_det(py::module &m) {
|
||||
Detector::setNumberOfAnalogSamples,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getADCClock",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
(Result<defs::Hz>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getADCClock,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("setADCClock",
|
||||
(void (Detector::*)(int, sls::Positions)) &
|
||||
(void (Detector::*)(defs::Hz, sls::Positions)) &
|
||||
Detector::setADCClock,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getRUNClock",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
(Result<defs::Hz>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getRUNClock,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("setRUNClock",
|
||||
(void (Detector::*)(int, sls::Positions)) &
|
||||
(void (Detector::*)(defs::Hz, sls::Positions)) &
|
||||
Detector::setRUNClock,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getDBITClock",
|
||||
(Result<defs::Hz>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getDBITClock,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("setDBITClock",
|
||||
(void (Detector::*)(defs::Hz, sls::Positions)) &
|
||||
Detector::setDBITClock,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getSYNCClock",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
(Result<defs::Hz>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getSYNCClock,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("getPowerList",
|
||||
@@ -1646,14 +1654,6 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(defs::readoutMode, sls::Positions)) &
|
||||
Detector::setReadoutMode,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getDBITClock",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getDBITClock,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("setDBITClock",
|
||||
(void (Detector::*)(int, sls::Positions)) &
|
||||
Detector::setDBITClock,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getExternalSamplingSource",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getExternalSamplingSource,
|
||||
@@ -1891,9 +1891,9 @@ void init_det(py::module &m) {
|
||||
Detector::configureTransceiver,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getPatterFileName",
|
||||
"getPatternFileName",
|
||||
(Result<std::string>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getPatterFileName,
|
||||
Detector::getPatternFileName,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"setPattern",
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
/*
|
||||
This file contains Python bindings for the Hz and for conversion to other units from and to string.
|
||||
*/
|
||||
#include "py_headers.h"
|
||||
#include <cmath>
|
||||
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
constexpr double kHz = 1e3;
|
||||
constexpr double MHz = 1e6;
|
||||
|
||||
void init_freq(py::module &m) {
|
||||
|
||||
py::class_<slsDetectorDefs::Hz> Hz(m, "Hz");
|
||||
Hz.def(py::init<int>());
|
||||
Hz.def_readwrite("value", &slsDetectorDefs::Hz::value);
|
||||
Hz.def("__repr__", [](const slsDetectorDefs::Hz &f) {
|
||||
return sls::ToString(f);
|
||||
});
|
||||
Hz.def("__str__", [](const slsDetectorDefs::Hz &f) {
|
||||
return sls::ToString(f);
|
||||
});
|
||||
|
||||
Hz.def(py::self == py::self);
|
||||
Hz.def("__mul__", [](const slsDetectorDefs::Hz &h, int x) {
|
||||
return slsDetectorDefs::Hz(h.value * x);
|
||||
}, py::is_operator());
|
||||
Hz.def("__rmul__", [](const slsDetectorDefs::Hz &h, int x) {
|
||||
return slsDetectorDefs::Hz(h.value * x);
|
||||
}, py::is_operator());
|
||||
Hz.def("__truediv__", [](const slsDetectorDefs::Hz &h, int x) {
|
||||
return slsDetectorDefs::Hz(h.value / x);
|
||||
}, py::is_operator());
|
||||
Hz.def("__add__", [](const slsDetectorDefs::Hz &a,
|
||||
const slsDetectorDefs::Hz &b) {
|
||||
return slsDetectorDefs::Hz(a.value + b.value);
|
||||
}, py::is_operator());
|
||||
Hz.def("__sub__", [](const slsDetectorDefs::Hz &a,
|
||||
const slsDetectorDefs::Hz &b) {
|
||||
return slsDetectorDefs::Hz(a.value - b.value);
|
||||
}, py::is_operator());
|
||||
|
||||
m.def("kHz", [](double v) {
|
||||
return slsDetectorDefs::Hz(static_cast<int>(std::round(v * kHz)));
|
||||
});
|
||||
|
||||
m.def("MHz", [](double v) {
|
||||
return slsDetectorDefs::Hz(static_cast<int>(std::round(v * MHz)));
|
||||
});
|
||||
}
|
||||
@@ -21,6 +21,7 @@ void init_source(py::module &);
|
||||
void init_duration(py::module &);
|
||||
void init_pedestal(py::module &);
|
||||
void init_bit(py::module &);
|
||||
void init_freq(py::module &);
|
||||
|
||||
PYBIND11_MODULE(_slsdet, m) {
|
||||
m.doc() = R"pbdoc(
|
||||
@@ -42,6 +43,7 @@ PYBIND11_MODULE(_slsdet, m) {
|
||||
init_duration(m);
|
||||
init_pedestal(m);
|
||||
init_bit(m);
|
||||
init_freq(m);
|
||||
// init_experimental(m);
|
||||
|
||||
py::module io = m.def_submodule("io", "Submodule for io");
|
||||
|
||||
@@ -396,6 +396,193 @@ def test_patternstart(session_simulator, request):
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_runclk(session_simulator, request):
|
||||
""" Test using runclk for ctb and xilinx_ctb."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Hz, MHz, kHz
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
prev_runclk = d.getRUNClock()
|
||||
|
||||
d.runclk
|
||||
|
||||
# invalid value type
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.runclk = 5e6
|
||||
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.runclk = 5 * 1000 * 1000
|
||||
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.runclk = Hz(5e6)
|
||||
|
||||
d.runclk = MHz(15)
|
||||
assert d.runclk.value == 15_000_000
|
||||
|
||||
d.runclk = MHz(14.5)
|
||||
assert d.runclk.value == 14_500_000
|
||||
|
||||
d.runclk = kHz(15000.5)
|
||||
assert d.runclk.value == 15_000_500
|
||||
|
||||
# invalid values from server
|
||||
# max is 300MHz
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.runclk = MHz(301)
|
||||
|
||||
# min is 2MHz for ctb and 10MHz for xilinx_ctb
|
||||
if det_type == 'ctb':
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.runclk = MHz(1)
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.runclk = MHz(9)
|
||||
|
||||
c = MHz(2)
|
||||
for rc in [5, 10, 15, 20]:
|
||||
d.runclk = rc * c
|
||||
assert d.runclk.value == 40_000_000
|
||||
|
||||
for i in range(len(d)):
|
||||
d.setRUNClock(prev_runclk[i], [i])
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_adcclk(session_simulator, request):
|
||||
""" Test using adcclk for ctb and xilinx_ctb."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Hz, MHz, kHz
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
prev_adcclk = d.getADCClock()
|
||||
|
||||
d.adcclk
|
||||
|
||||
# invalid value type
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = 5e6
|
||||
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = 5 * 1000 * 1000
|
||||
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = Hz(5e6)
|
||||
|
||||
d.adcclk = MHz(15)
|
||||
assert d.adcclk.value == 15_000_000
|
||||
|
||||
d.adcclk = MHz(14.5)
|
||||
assert d.adcclk.value == 14_500_000
|
||||
|
||||
d.adcclk = kHz(15000.5)
|
||||
assert d.adcclk.value == 15_000_500
|
||||
|
||||
# invalid values from server
|
||||
# max is 300MHz for xilinx and 54 MHz for ctb
|
||||
if det_type == 'ctb':
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = MHz(66)
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = MHz(301)
|
||||
|
||||
# min is 2MHz for ctb and 10MHz for xilinx_ctb
|
||||
if det_type == 'ctb':
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = MHz(1)
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.adcclk = MHz(9)
|
||||
|
||||
c = MHz(2)
|
||||
for rc in [5, 10, 15, 20]:
|
||||
d.adcclk = rc * c
|
||||
assert d.adcclk.value == 40_000_000
|
||||
|
||||
for i in range(len(d)):
|
||||
d.setADCClock(prev_adcclk[i], [i])
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_dbitclk(session_simulator, request):
|
||||
""" Test using dbitclk for ctb and xilinx_ctb."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Hz, MHz, kHz
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
prev_dbitclk = d.getDBITClock()
|
||||
|
||||
d.dbitclk
|
||||
|
||||
# invalid value type
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.dbitclk = 5e6
|
||||
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.dbitclk = 5 * 1000 * 1000
|
||||
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.dbitclk = Hz(5e6)
|
||||
|
||||
d.dbitclk = MHz(15)
|
||||
assert d.dbitclk.value == 15_000_000
|
||||
|
||||
d.dbitclk = MHz(14.5)
|
||||
assert d.dbitclk.value == 14_500_000
|
||||
|
||||
d.dbitclk = kHz(15000.5)
|
||||
assert d.dbitclk.value == 15_000_500
|
||||
|
||||
# invalid values from server
|
||||
# max is 300MHz
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.dbitclk = MHz(301)
|
||||
|
||||
# min is 2MHz for ctb and 10MHz for xilinx_ctb
|
||||
if det_type == 'ctb':
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.dbitclk = MHz(1)
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.dbitclk = MHz(9)
|
||||
|
||||
c = MHz(2)
|
||||
for rc in [5, 10, 15, 20]:
|
||||
d.dbitclk = rc * c
|
||||
assert d.dbitclk.value == 40_000_000
|
||||
|
||||
for i in range(len(d)):
|
||||
d.setDBITClock(prev_dbitclk[i], [i])
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_syncclk(session_simulator, request):
|
||||
""" Test using syncclk for ctb."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
if det_type in ['ctb']:
|
||||
d.syncclk
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_v_limit(session_simulator, request):
|
||||
"""Test v_limit."""
|
||||
@@ -715,3 +902,4 @@ def test_dac(session_simulator, request):
|
||||
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
from slsdet import Hz, MHz, kHz
|
||||
|
||||
def test_Hz():
|
||||
f = Hz(1)
|
||||
assert f.value == 1
|
||||
f = Hz(1 * 1000)
|
||||
assert f.value == 1000
|
||||
f = MHz(5)
|
||||
assert f.value == 5_000_000
|
||||
f = MHz(0.5)
|
||||
assert f.value == 500_000
|
||||
f = kHz(2.5)
|
||||
assert f.value == 2500
|
||||
f = kHz(5000)
|
||||
assert f.value == 5_000_000
|
||||
|
||||
def test_rounding_exact():
|
||||
f = MHz(1.234)
|
||||
assert f.value == round(1_234_000)
|
||||
|
||||
|
||||
def test_mul():
|
||||
c = MHz(1)
|
||||
assert (c * 2).value == 2_000_000
|
||||
assert (c * 4).value == 4_000_000
|
||||
|
||||
|
||||
def test_rmul():
|
||||
c = MHz(1)
|
||||
assert (2 * c).value == 2_000_000
|
||||
assert (4 * c).value == 4_000_000
|
||||
|
||||
c = c * 2
|
||||
assert c.value == 2_000_000
|
||||
|
||||
for rc in [1, 2, 4, 8]:
|
||||
c = rc * c
|
||||
assert c.value == 128_000_000
|
||||
|
||||
|
||||
def test_div():
|
||||
c = MHz(1)
|
||||
assert (c / 2).value == 500_000
|
||||
|
||||
def test_eq():
|
||||
assert MHz(1) == MHz(1)
|
||||
assert MHz(1) != MHz(2)
|
||||
assert MHz(1) == kHz(1000)
|
||||
@@ -628,11 +628,14 @@
|
||||
#define ADC_SLOW_CTRL_DONE_OFST (1)
|
||||
#define ADC_SLOW_CTRL_DONE_MSK (0x00000001 << ADC_SLOW_CTRL_DONE_OFST)
|
||||
|
||||
/* 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_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)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -13,6 +13,7 @@
|
||||
#include "communication_funcs_UDP.h"
|
||||
#include "loadPattern.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -65,7 +66,7 @@ uint8_t adcEnableMask_10g = 0xFF;
|
||||
uint32_t transceiverMask = DEFAULT_TRANSCEIVER_MASK;
|
||||
|
||||
int32_t clkPhase[NUM_CLOCKS] = {};
|
||||
uint32_t clkFrequency[NUM_CLOCKS] = {40, 20, 20, 200};
|
||||
uint32_t clkFrequency[NUM_CLOCKS] = {};
|
||||
int dacValues[NDAC_ONLY] = {};
|
||||
int powerValues[NPWR] = {}; // powerIndex (A->IO, Chip)
|
||||
|
||||
@@ -557,7 +558,7 @@ void setupDetector() {
|
||||
ALTERA_PLL_SetDefines(PLL_CNTRL_REG, PLL_PARAM_REG,
|
||||
PLL_CNTRL_RCNFG_PRMTR_RST_MSK, PLL_CNTRL_WR_PRMTR_MSK,
|
||||
PLL_CNTRL_PLL_RST_MSK, PLL_CNTRL_ADDR_MSK,
|
||||
PLL_CNTRL_ADDR_OFST);
|
||||
PLL_CNTRL_ADDR_OFST, PLL_FREQ_MEASURE_REG);
|
||||
ALTERA_PLL_ResetPLLAndReconfiguration();
|
||||
|
||||
resetCore();
|
||||
@@ -632,10 +633,16 @@ void setupDetector() {
|
||||
DEFAULT_NUM_SAMPLES); // update databytes and allocate ram
|
||||
setNumTransceiverSamples(DEFAULT_NUM_SAMPLES);
|
||||
setNumFrames(DEFAULT_NUM_FRAMES);
|
||||
setExpTime(DEFAULT_EXPTIME);
|
||||
initError = setExpTime(DEFAULT_EXPTIME, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
setNumTriggers(DEFAULT_NUM_CYCLES);
|
||||
setPeriod(DEFAULT_PERIOD);
|
||||
setDelayAfterTrigger(DEFAULT_DELAY);
|
||||
initError = setPeriod(DEFAULT_PERIOD, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
initError = setDelayAfterTrigger(DEFAULT_DELAY, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
setTiming(DEFAULT_TIMING_MODE);
|
||||
setADCEnableMask(BIT32_MSK);
|
||||
setADCEnableMask_10G(BIT32_MSK);
|
||||
@@ -1134,64 +1141,132 @@ int setNumTransceiverSamples(int val) {
|
||||
|
||||
int getNumTransceiverSamples() { return ntSamples; }
|
||||
|
||||
int setExpTime(int64_t val) {
|
||||
int setExpTime(int64_t val, char *mess) {
|
||||
setPatternWaitInterval(0, val);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getExpTime();
|
||||
// validate
|
||||
uint64_t arg_clocks = ns_to_clocks(val, clkFrequency[RUN_CLK]);
|
||||
uint64_t retval_clocks = getPatternWaitClocks(0);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(mess,
|
||||
"Failed to set exposure time. Could not set number of clocks "
|
||||
"to %lld, read %lld\n",
|
||||
(long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
int64_t retval = getPatternWaitInterval(0);
|
||||
if (val != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getExpTime(int64_t *retval, char *mess) {
|
||||
*retval = getPatternWaitInterval(0);
|
||||
if (*retval == -1) {
|
||||
sprintf(mess, "Failed to get exposure time.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getExpTime() { return getPatternWaitInterval(0); }
|
||||
|
||||
int setPeriod(int64_t val) {
|
||||
int setPeriod(int64_t val, char *mess) {
|
||||
if (val < 0) {
|
||||
LOG(logERROR, ("Invalid period: %lld ns\n", (long long int)val));
|
||||
sprintf(mess, "Invalid period: %lld ns\n", (long long int)val);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting period %lld ns\n", (long long int)val));
|
||||
val *= (1E-3 * clkFrequency[SYNC_CLK]);
|
||||
set64BitReg(val, PERIOD_LSB_REG, PERIOD_MSB_REG);
|
||||
uint64_t arg_clocks = ns_to_clocks(val, clkFrequency[SYNC_CLK]);
|
||||
set64BitReg(arg_clocks, PERIOD_LSB_REG, PERIOD_MSB_REG);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getPeriod();
|
||||
val /= (1E-3 * clkFrequency[SYNC_CLK]);
|
||||
if (val != retval) {
|
||||
// validate
|
||||
uint64_t retval_clocks = get64BitReg(PERIOD_LSB_REG, PERIOD_MSB_REG);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(mess,
|
||||
"Failed to set period. Could not set number of clocks "
|
||||
"to %lld, red %lld\n",
|
||||
(long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
int64_t retval = 0;
|
||||
if (getPeriod(&retval, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
if (val != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getPeriod() {
|
||||
return get64BitReg(PERIOD_LSB_REG, PERIOD_MSB_REG) /
|
||||
(1E-3 * clkFrequency[SYNC_CLK]);
|
||||
int getPeriod(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[SYNC_CLK] == 0) {
|
||||
sprintf(mess, "Cannot get period. Sync clock frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = get64BitReg(PERIOD_LSB_REG, PERIOD_MSB_REG);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[SYNC_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setDelayAfterTrigger(int64_t val) {
|
||||
int setDelayAfterTrigger(int64_t val, char *mess) {
|
||||
if (val < 0) {
|
||||
LOG(logERROR,
|
||||
("Invalid delay after trigger: %lld ns\n", (long long int)val));
|
||||
sprintf(mess, "Invalid delay after trigger: %lld ns\n",
|
||||
(long long int)val);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting delay after trigger %lld ns\n", (long long int)val));
|
||||
val *= (1E-3 * clkFrequency[SYNC_CLK]);
|
||||
set64BitReg(val, DELAY_LSB_REG, DELAY_MSB_REG);
|
||||
uint64_t arg_clocks = ns_to_clocks(val, clkFrequency[SYNC_CLK]);
|
||||
set64BitReg(arg_clocks, DELAY_LSB_REG, DELAY_MSB_REG);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getDelayAfterTrigger();
|
||||
val /= (1E-3 * clkFrequency[SYNC_CLK]);
|
||||
if (val != retval) {
|
||||
// validate
|
||||
uint64_t retval_clocks = get64BitReg(DELAY_LSB_REG, DELAY_MSB_REG);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(
|
||||
mess,
|
||||
"Failed to set delay after trigger. Could not set number of clocks "
|
||||
"to %lld, read %lld\n",
|
||||
(long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
int64_t retval = 0;
|
||||
if (getDelayAfterTrigger(&retval, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
if (val != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getDelayAfterTrigger() {
|
||||
return get64BitReg(DELAY_LSB_REG, DELAY_MSB_REG) /
|
||||
(1E-3 * clkFrequency[SYNC_CLK]);
|
||||
int getDelayAfterTrigger(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[SYNC_CLK] == 0) {
|
||||
sprintf(mess,
|
||||
"Cannot get delay after trigger. Sync clock frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = get64BitReg(DELAY_LSB_REG, DELAY_MSB_REG);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[SYNC_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getNumFramesLeft() {
|
||||
@@ -1202,14 +1277,27 @@ int64_t getNumTriggersLeft() {
|
||||
return get64BitReg(CYCLES_LEFT_LSB_REG, CYCLES_LEFT_MSB_REG);
|
||||
}
|
||||
|
||||
int64_t getDelayAfterTriggerLeft() {
|
||||
return get64BitReg(DELAY_LEFT_LSB_REG, DELAY_LEFT_MSB_REG) /
|
||||
(1E-3 * clkFrequency[SYNC_CLK]);
|
||||
int getDelayAfterTriggerLeft(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[SYNC_CLK] == 0) {
|
||||
sprintf(mess, "Cannot get delay after trigger left. Sync clock "
|
||||
"frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = get64BitReg(DELAY_LEFT_LSB_REG, DELAY_LEFT_MSB_REG);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[SYNC_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getPeriodLeft() {
|
||||
return get64BitReg(PERIOD_LEFT_LSB_REG, PERIOD_LEFT_MSB_REG) /
|
||||
(1E-3 * clkFrequency[SYNC_CLK]);
|
||||
int getPeriodLeft(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[SYNC_CLK] == 0) {
|
||||
sprintf(mess, "Cannot get period left. Sync clock frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = get64BitReg(PERIOD_LEFT_LSB_REG, PERIOD_LEFT_MSB_REG);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[SYNC_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getFramesFromStart() {
|
||||
@@ -1218,13 +1306,14 @@ int64_t getFramesFromStart() {
|
||||
}
|
||||
|
||||
int64_t getActualTime() {
|
||||
return get64BitReg(TIME_FROM_START_LSB_REG, TIME_FROM_START_MSB_REG) /
|
||||
(1E-3 * CLK_FREQ);
|
||||
// reg in unit of 100ns
|
||||
return get64BitReg(TIME_FROM_START_LSB_REG, TIME_FROM_START_MSB_REG) * 100;
|
||||
}
|
||||
|
||||
int64_t getMeasurementTime() {
|
||||
return get64BitReg(START_FRAME_TIME_LSB_REG, START_FRAME_TIME_MSB_REG) /
|
||||
(1E-3 * CLK_FREQ);
|
||||
// reg in unit of 100ns
|
||||
return get64BitReg(START_FRAME_TIME_LSB_REG, START_FRAME_TIME_MSB_REG) *
|
||||
100;
|
||||
}
|
||||
|
||||
/* parameters - settings */
|
||||
@@ -2206,13 +2295,12 @@ int getMaxPhase(enum CLKINDEX ind) {
|
||||
LOG(logERROR, ("Unknown clock index %d to get max phase\n", ind));
|
||||
return -1;
|
||||
}
|
||||
int ret = ((double)PLL_VCO_FREQ_MHZ / (double)clkFrequency[ind]) *
|
||||
int ret = ((double)PLL_VCO_FREQ_HZ / (double)clkFrequency[ind]) *
|
||||
MAX_PHASE_SHIFTS_STEPS;
|
||||
|
||||
char *clock_names[] = {CLK_NAMES};
|
||||
LOG(logDEBUG1,
|
||||
("Max Phase Shift (%s): %d (Clock: %d MHz, VCO:%d MHz)\n",
|
||||
clock_names[ind], ret, clkFrequency[ind], PLL_VCO_FREQ_MHZ));
|
||||
LOG(logDEBUG1, ("Max Phase Shift (%s): %d (Clock: %d Hz, VCO:%d Hz)\n",
|
||||
clock_names[ind], ret, clkFrequency[ind], PLL_VCO_FREQ_HZ));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2248,12 +2336,12 @@ int setFrequency(enum CLKINDEX ind, int val) {
|
||||
return FAIL;
|
||||
}
|
||||
char *clock_names[] = {CLK_NAMES};
|
||||
LOG(logINFO, ("\tSetting %s clock (%d) frequency to %d MHz\n",
|
||||
LOG(logINFO, ("\tSetting %s clock (%d) frequency to %d Hz\n",
|
||||
clock_names[ind], ind, val));
|
||||
|
||||
// check adc clk too high
|
||||
if (ind == ADC_CLK && val > MAXIMUM_ADC_CLK) {
|
||||
LOG(logERROR, ("Frequency %d MHz too high for ADC\n", val));
|
||||
LOG(logERROR, ("Frequency %d Hz too high for ADC\n", val));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -2265,8 +2353,8 @@ int setFrequency(enum CLKINDEX ind, int val) {
|
||||
|
||||
// Calculate and set output frequency
|
||||
clkFrequency[ind] =
|
||||
ALTERA_PLL_SetOuputFrequency(ind, PLL_VCO_FREQ_MHZ, val);
|
||||
LOG(logINFO, ("\t%s clock (%d) frequency set to %d MHz\n", clock_names[ind],
|
||||
ALTERA_PLL_SetOutputFrequency(ind, PLL_VCO_FREQ_HZ, val);
|
||||
LOG(logINFO, ("\t%s clock (%d) frequency set to %d Hz\n", clock_names[ind],
|
||||
ind, clkFrequency[ind]));
|
||||
|
||||
// phase reset by pll (when setting output frequency)
|
||||
@@ -2294,6 +2382,17 @@ int getFrequency(enum CLKINDEX ind) {
|
||||
LOG(logERROR, ("Unknown clock index %d to get frequency\n", ind));
|
||||
return -1;
|
||||
}
|
||||
#ifndef VIRTUAL
|
||||
// get the measured frequency from the firmware
|
||||
int measuredFreqHz = ALTERA_PLL_getFrequency(ind);
|
||||
|
||||
// checking against 0 here ensures compatibility with old firmware, TODO:
|
||||
// remove this check at some point
|
||||
if (measuredFreqHz != 0) {
|
||||
// Round to nearest Hz. (should we round at all ?)
|
||||
clkFrequency[ind] = measuredFreqHz;
|
||||
}
|
||||
#endif
|
||||
return clkFrequency[ind];
|
||||
}
|
||||
|
||||
@@ -2507,10 +2606,21 @@ void *start_timer(void *arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int64_t periodNs = getPeriod();
|
||||
int64_t periodNs = 0;
|
||||
int64_t expUs = 0;
|
||||
{
|
||||
char mess[MAX_STR_LENGTH] = {0};
|
||||
if (getPeriod(&periodNs, mess) == FAIL) {
|
||||
LOG(logERROR, ("Failed to get period.\n"));
|
||||
return NULL;
|
||||
}
|
||||
if (getExpTime(&expUs, mess) == FAIL) {
|
||||
LOG(logERROR, ("Failed to get exposure time.\n"));
|
||||
return NULL;
|
||||
}
|
||||
expUs /= 1000;
|
||||
}
|
||||
int numFrames = (getNumFrames() * getNumTriggers());
|
||||
int64_t expUs = getExpTime() / 1000;
|
||||
|
||||
int imageSize = dataBytes;
|
||||
int dataSize = UDP_PACKET_DATA_BYTES;
|
||||
int packetSize = sizeof(sls_detector_header) + dataSize;
|
||||
|
||||
@@ -98,10 +98,10 @@ void setNumFrames(int64_t val);
|
||||
int64_t getNumFrames();
|
||||
void setNumTriggers(int64_t val);
|
||||
int64_t getNumTriggers();
|
||||
int setExpTime(int64_t val);
|
||||
int64_t getExpTime();
|
||||
int setPeriod(int64_t val);
|
||||
int64_t getPeriod();
|
||||
int setExpTime(int64_t val, char *mess);
|
||||
int getExpTime(int64_t *retval, char *mess);
|
||||
int setPeriod(int64_t val, char *mess);
|
||||
int getPeriod(int64_t *retval, char *mess);
|
||||
int setNumAnalogSamples(int val);
|
||||
int getNumAnalogSamples();
|
||||
int setNumDigitalSamples(int val);
|
||||
@@ -111,10 +111,10 @@ int getNumTransceiverSamples();
|
||||
|
||||
int64_t getNumFramesLeft();
|
||||
int64_t getNumTriggersLeft();
|
||||
int setDelayAfterTrigger(int64_t val);
|
||||
int64_t getDelayAfterTrigger();
|
||||
int64_t getDelayAfterTriggerLeft();
|
||||
int64_t getPeriodLeft();
|
||||
int setDelayAfterTrigger(int64_t val, char *mess);
|
||||
int getDelayAfterTrigger(int64_t *retval, char *mess);
|
||||
int getDelayAfterTriggerLeft(int64_t *retval, char *mess);
|
||||
int getPeriodLeft(int64_t *retval, char *mess);
|
||||
int64_t getFramesFromStart();
|
||||
int64_t getActualTime();
|
||||
int64_t getMeasurementTime();
|
||||
|
||||
@@ -44,13 +44,16 @@
|
||||
#define DEFAULT_VLIMIT (0)
|
||||
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
|
||||
#define DEFAULT_TX_UDP_PORT (0x7e9a)
|
||||
#define DEFAULT_RUN_CLK (200) // 40
|
||||
#define DEFAULT_ADC_CLK (40) // 20
|
||||
#define DEFAULT_SYNC_CLK (40) // 20
|
||||
#define DEFAULT_DBIT_CLK (200)
|
||||
#define NS_TO_CLK_CYCLE (1E-3) // ns to MHz
|
||||
#define DEFAULT_RUN_CLK (80000000) // 80 MHz
|
||||
#define DEFAULT_ADC_CLK (40000000) // 40 MHz
|
||||
#define DEFAULT_SYNC_CLK (40000000) // 40 MHz
|
||||
#define DEFAULT_DBIT_CLK (200000000) // 200 MHz
|
||||
#define NS_TO_CLK_CYCLE (1E-9) // ns to MHz
|
||||
#define DEFAULT_TRANSCEIVER_MASK (0x3)
|
||||
|
||||
#define MIN_CLK_FREQ (2000000) // 2 MHz
|
||||
#define MAX_CLK_FREQ (300000000) // 300 MHz
|
||||
|
||||
#define MAX_TRANSCEIVER_MASK (0xF)
|
||||
#define MAX_TRANSCEIVER_SAMPLES (0xFFFF)
|
||||
|
||||
@@ -89,8 +92,8 @@
|
||||
#define BIT32_MSK (0xFFFFFFFF)
|
||||
#define BIT16_MASK (0xFFFF)
|
||||
|
||||
#define MAXIMUM_ADC_CLK (65)
|
||||
#define PLL_VCO_FREQ_MHZ (800)
|
||||
#define MAXIMUM_ADC_CLK (65000000) // 65 MHz
|
||||
#define PLL_VCO_FREQ_HZ (800000000) // 800MHz
|
||||
|
||||
/* Struct Definitions */
|
||||
typedef struct udp_header_struct {
|
||||
|
||||
@@ -163,7 +163,6 @@ int setPhase(enum CLKINDEX ind, int val, int degrees);
|
||||
int getPhase(enum CLKINDEX ind, int degrees);
|
||||
int getMaxPhase(enum CLKINDEX ind);
|
||||
int validatePhaseinDegrees(enum CLKINDEX ind, int val, int retval);
|
||||
// void setFrequency(enum CLKINDEX ind, int val);
|
||||
int getFrequency(enum CLKINDEX ind);
|
||||
int getVCOFrequency(enum CLKINDEX ind);
|
||||
int setReadoutSpeed(int val);
|
||||
|
||||
Binary file not shown.
@@ -195,7 +195,6 @@ int setPhase(enum CLKINDEX ind, int val, int degrees);
|
||||
int getPhase(enum CLKINDEX ind, int degrees);
|
||||
int getMaxPhase(enum CLKINDEX ind);
|
||||
int validatePhaseinDegrees(enum CLKINDEX ind, int val, int retval);
|
||||
// void setFrequency(enum CLKINDEX ind, int val);
|
||||
int getFrequency(enum CLKINDEX ind);
|
||||
int getVCOFrequency(enum CLKINDEX ind);
|
||||
int getMaxClockDivider();
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
void ALTERA_PLL_SetDefines(uint32_t creg, uint32_t preg, uint32_t rprmsk,
|
||||
uint32_t wpmsk, uint32_t prmsk, uint32_t amsk,
|
||||
int aofst, uint32_t wd2msk, int clk2Index);
|
||||
#elif defined(CHIPTESTBOARDD)
|
||||
void ALTERA_PLL_SetDefines(uint32_t creg, uint32_t preg, uint32_t rprmsk,
|
||||
uint32_t wpmsk, uint32_t prmsk, uint32_t amsk,
|
||||
int aofst, uint32_t freqreg);
|
||||
#else
|
||||
/**
|
||||
* Set Defines
|
||||
@@ -71,8 +75,15 @@ void ALTERA_PLL_SetModePolling();
|
||||
/**
|
||||
* Calculate and write output frequency
|
||||
* @param clkIndex clock index
|
||||
* @param pllVCOFreqMhz PLL VCO Frequency in Mhz
|
||||
* @param pllVCOFreqHz PLL VCO Frequency in Hz
|
||||
* @param value frequency to set to
|
||||
* @param frequency set
|
||||
*/
|
||||
int ALTERA_PLL_SetOuputFrequency(int clkIndex, int pllVCOFreqMhz, int value);
|
||||
int ALTERA_PLL_SetOutputFrequency(int clkIndex, int pllVCOFreqHz, int value);
|
||||
|
||||
/**
|
||||
* get measured clock frequency
|
||||
*/
|
||||
#if defined(CHIPTESTBOARDD)
|
||||
uint32_t ALTERA_PLL_getFrequency(uint32_t clkIDX);
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include "clogger.h"
|
||||
#include "sls/md5.h"
|
||||
#include <stdint.h> // int64_t
|
||||
#include <stdio.h>
|
||||
@@ -21,6 +22,19 @@
|
||||
enum numberMode { DEC, HEX };
|
||||
enum PROGRAM_INDEX { PROGRAM_FPGA, PROGRAM_KERNEL, PROGRAM_SERVER };
|
||||
|
||||
#define NS_PER_SEC 1000000000ULL
|
||||
#define HALF_NS_PER_SEC (NS_PER_SEC / 2)
|
||||
static inline uint64_t ns_to_clocks(uint64_t t, uint32_t freq_hz) {
|
||||
return (t * (uint64_t)freq_hz + HALF_NS_PER_SEC) / NS_PER_SEC;
|
||||
}
|
||||
static inline uint64_t clocks_to_ns(uint64_t clocks, uint32_t freq_hz) {
|
||||
if (freq_hz == 0) {
|
||||
LOG(logERROR, ("Frequency is 0, cannot convert clocks to ns\n"));
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
return (clocks * (uint64_t)NS_PER_SEC + freq_hz / 2) / freq_hz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a value from a range to a different range (eg voltage to dac or vice
|
||||
* versa)
|
||||
|
||||
@@ -130,7 +130,8 @@ uint32_t ALTERA_PLL_Cntrl_WrPrmtrMask = 0x0;
|
||||
#if defined(JUNGFRAUD)
|
||||
uint32_t ALTERA_PLL_Cntrl_DBIT_PLL_WrPrmtrMask = 0x0;
|
||||
int ALTERA_PLL_Cntrl_DBIT_ClkIndex = 0;
|
||||
|
||||
#elif defined(CHIPTESTBOARDD)
|
||||
uint32_t ALTERA_PLL_FREQ_MEASURE_BASE = 0x0;
|
||||
#endif
|
||||
uint32_t ALTERA_PLL_Cntrl_PLLRstMask = 0x0;
|
||||
uint32_t ALTERA_PLL_Cntrl_AddrMask = 0x0;
|
||||
@@ -150,6 +151,19 @@ void ALTERA_PLL_SetDefines(uint32_t creg, uint32_t preg, uint32_t rprmsk,
|
||||
ALTERA_PLL_Cntrl_DBIT_PLL_WrPrmtrMask = wd2msk;
|
||||
ALTERA_PLL_Cntrl_DBIT_ClkIndex = clk2Index;
|
||||
}
|
||||
#elif defined(CHIPTESTBOARDD)
|
||||
void ALTERA_PLL_SetDefines(uint32_t creg, uint32_t preg, uint32_t rprmsk,
|
||||
uint32_t wpmsk, uint32_t prmsk, uint32_t amsk,
|
||||
int aofst, uint32_t freqreg) {
|
||||
ALTERA_PLL_Cntrl_Reg = creg;
|
||||
ALTERA_PLL_Param_Reg = preg;
|
||||
ALTERA_PLL_Cntrl_RcnfgPrmtrRstMask = rprmsk;
|
||||
ALTERA_PLL_Cntrl_WrPrmtrMask = wpmsk;
|
||||
ALTERA_PLL_Cntrl_PLLRstMask = prmsk;
|
||||
ALTERA_PLL_Cntrl_AddrMask = amsk;
|
||||
ALTERA_PLL_Cntrl_AddrOfst = aofst;
|
||||
ALTERA_PLL_FREQ_MEASURE_BASE = freqreg;
|
||||
}
|
||||
#else
|
||||
void ALTERA_PLL_SetDefines(uint32_t creg, uint32_t preg, uint32_t rprmsk,
|
||||
uint32_t wpmsk, uint32_t prmsk, uint32_t amsk,
|
||||
@@ -269,12 +283,12 @@ void ALTERA_PLL_SetModePolling() {
|
||||
ALTERA_PLL_MODE_PLLNG_MD_VAL, 0);
|
||||
}
|
||||
|
||||
int ALTERA_PLL_SetOuputFrequency(int clkIndex, int pllVCOFreqMhz, int value) {
|
||||
LOG(logDEBUG1, ("C%d: Setting output frequency to %d (pllvcofreq: %dMhz)\n",
|
||||
clkIndex, value, pllVCOFreqMhz));
|
||||
int ALTERA_PLL_SetOutputFrequency(int clkIndex, int pllVCOFreqHz, int value) {
|
||||
LOG(logDEBUG1, ("C%d: Setting output frequency to %d (pllvcofreq: %dHz)\n",
|
||||
clkIndex, value, pllVCOFreqHz));
|
||||
|
||||
// calculate output frequency
|
||||
uint32_t total_div = (float)pllVCOFreqMhz / (float)value;
|
||||
// calculate output frequency, round to next closest integer division
|
||||
uint32_t total_div = (pllVCOFreqHz + value / 2) / value;
|
||||
|
||||
// assume 50% duty cycle
|
||||
uint32_t low_count = total_div / 2;
|
||||
@@ -307,11 +321,24 @@ int ALTERA_PLL_SetOuputFrequency(int clkIndex, int pllVCOFreqMhz, int value) {
|
||||
// as adc clock is stopped temporarily when resetting pll)
|
||||
ALTERA_PLL_ResetPLL();
|
||||
|
||||
/*double temp = ((double)pllVCOFreqMhz / (double)(low_count + high_count));
|
||||
/*double temp = ((double)pllVCOFreqHz / (double)(low_count + high_count));
|
||||
if ((temp - (int)temp) > 0.0001) {
|
||||
temp += 0.5;
|
||||
}
|
||||
return (int)temp;
|
||||
*/
|
||||
|
||||
#if defined(CHIPTESTBOARDD) && !defined(VIRTUAL)
|
||||
// wait for firmware to measure the actual frequency
|
||||
usleep(2 * 1000 * 1000);
|
||||
value = ALTERA_PLL_getFrequency(clkIndex);
|
||||
LOG(logDEBUG1, ("Frequency is %d\n", value));
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(CHIPTESTBOARDD)
|
||||
uint32_t ALTERA_PLL_getFrequency(uint32_t clk_index) {
|
||||
return bus_r(ALTERA_PLL_FREQ_MEASURE_BASE + clk_index * 2);
|
||||
}
|
||||
#endif
|
||||
@@ -11,9 +11,9 @@
|
||||
// leave some things away)
|
||||
|
||||
// clang-format off
|
||||
#define XILINX_PLL_INPUT_FREQ (100000) // 100 MHz
|
||||
#define XILINX_PLL_MIN_FREQ (10000)
|
||||
#define XILINX_PLL_MAX_FREQ (250000)
|
||||
#define XILINX_PLL_INPUT_FREQ (100000000) // 100 MHz
|
||||
#define XILINX_PLL_MIN_FREQ (10000000)
|
||||
#define XILINX_PLL_MAX_FREQ (250000000)
|
||||
#define XILINX_PLL_MAX_CLK_DIV (256)
|
||||
#define XILINX_PLL_NUM_CLKS (7)
|
||||
#define XILINX_PLL_MAX_NUM_CLKS_FOR_GET (3)
|
||||
@@ -71,14 +71,14 @@
|
||||
|
||||
// clang-format on
|
||||
|
||||
// freq in kHz !!
|
||||
// freq in Hz !!
|
||||
int XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq) {
|
||||
if (clk_index >= XILINX_PLL_NUM_CLKS) {
|
||||
LOG(logERROR, ("XILINX_PLL: Invalid clock index %d\n", clk_index));
|
||||
return 1;
|
||||
}
|
||||
if (freq < XILINX_PLL_MIN_FREQ || freq > XILINX_PLL_MAX_FREQ) {
|
||||
LOG(logERROR, ("XILINX_PLL: Frequency %d kHz is out of range\n", freq));
|
||||
LOG(logERROR, ("XILINX_PLL: Frequency %d Hz is out of range\n", freq));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -160,11 +160,7 @@ uint32_t XILINX_PLL_getFrequency(uint32_t clk_index) {
|
||||
clk_index -= XILINX_PLL_MEASURE_BASE_ADDR0_MAX_CLKS;
|
||||
base_addr = XILINX_PLL_MEASURE_BASE_ADDR1;
|
||||
}
|
||||
uint32_t addr = base_addr + clk_index * XILINX_PLL_MEASURE_WIDTH;
|
||||
uint32_t counter_val = bus_r_csp2(addr);
|
||||
// Hz => round to nearest kHz
|
||||
uint32_t freq_kHz = (counter_val + 500) / 1000; // round to nearest kHz
|
||||
return freq_kHz;
|
||||
return bus_r_csp2(base_addr + clk_index * XILINX_PLL_MEASURE_WIDTH);
|
||||
}
|
||||
|
||||
bool XILINX_PLL_isLocked() {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#ifdef MYTHEN3D
|
||||
extern enum TLogLevel trimmingPrint;
|
||||
extern uint32_t clkDivider[];
|
||||
extern int getFrequency(enum CLKINDEX ind);
|
||||
#endif
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
extern uint32_t clkFrequency[];
|
||||
@@ -277,6 +277,14 @@ int validate_getPatternWaitClocksAndInterval(char *message, int level,
|
||||
*waittime = getPatternWaitClocks(level);
|
||||
} else {
|
||||
*waittime = getPatternWaitInterval(level);
|
||||
if (*waittime == (uint64_t)-1) {
|
||||
sprintf(
|
||||
message,
|
||||
"Cannot get pattern wait interval for level %d. runclk is 0.\n",
|
||||
level);
|
||||
LOG(logERROR, (message));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -297,17 +305,17 @@ uint64_t getPatternWaitClocks(int level) {
|
||||
|
||||
uint64_t getPatternWaitInterval(int level) {
|
||||
uint64_t numClocks = getPatternWaitClocks(level);
|
||||
int runclk = 0;
|
||||
uint32_t runclk = 0;
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
runclk = clkFrequency[RUN_CLK];
|
||||
#elif MYTHEN3D
|
||||
runclk = clkDivider[SYSTEM_C0];
|
||||
runclk = getFrequency(SYSTEM_C0);
|
||||
#endif
|
||||
if (runclk == 0) {
|
||||
LOG(logERROR, ("runclk is 0. Cannot divide by 0. Returning -1.\n"));
|
||||
return -1;
|
||||
}
|
||||
return numClocks / (NS_TO_CLK_CYCLE * runclk);
|
||||
return clocks_to_ns(numClocks, runclk);
|
||||
}
|
||||
|
||||
int validate_setPatternWaitClocksAndInterval(char *message, int level,
|
||||
@@ -321,27 +329,50 @@ int validate_setPatternWaitClocksAndInterval(char *message, int level,
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
uint64_t retval = 0;
|
||||
if (clocks) {
|
||||
setPatternWaitClocks(level, waittime);
|
||||
// validate result
|
||||
retval = getPatternWaitClocks(level);
|
||||
uint64_t retval = getPatternWaitClocks(level);
|
||||
LOG(logDEBUG1, ("Pattern wait time in clocks (level:%d) retval: %d\n",
|
||||
level, (long long int)retval));
|
||||
} else {
|
||||
setPatternWaitInterval(level, waittime);
|
||||
// validate result
|
||||
retval = getPatternWaitInterval(level);
|
||||
LOG(logDEBUG1, ("Pattern wait time (level:%d) retval: %d\n", level,
|
||||
(long long int)retval));
|
||||
|
||||
int ret = OK;
|
||||
char mode[128];
|
||||
memset(mode, 0, sizeof(mode));
|
||||
sprintf(mode, "set pattern Loop %d wait time (clocks)", level);
|
||||
validate64(&ret, message, waittime, retval, mode, DEC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ret = OK;
|
||||
char mode[128];
|
||||
memset(mode, 0, sizeof(mode));
|
||||
sprintf(mode, "set pattern Loop %d wait time", level);
|
||||
validate64(&ret, message, waittime, retval, mode, DEC);
|
||||
return ret;
|
||||
// interval
|
||||
setPatternWaitInterval(level, waittime);
|
||||
|
||||
// validate
|
||||
uint32_t runclk = 0;
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
runclk = clkFrequency[RUN_CLK];
|
||||
#elif MYTHEN3D
|
||||
runclk = getFrequency(SYSTEM_C0);
|
||||
#endif
|
||||
uint64_t arg_clocks = ns_to_clocks(waittime, runclk);
|
||||
uint64_t retval_clocks = getPatternWaitClocks(level);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(message,
|
||||
"Failed to set pattern loop %d wait interval. Could not set "
|
||||
"number of clocks to %lld, read %lld\n",
|
||||
level, (long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (message));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
uint64_t retval = getPatternWaitInterval(level);
|
||||
if (waittime != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setPatternWaitClocks(int level, uint64_t t) {
|
||||
@@ -375,13 +406,13 @@ void setPatternWaitInterval(int level, uint64_t t) {
|
||||
#endif
|
||||
("Setting Pattern Wait Time (level:%d) :%lld ns\n", level,
|
||||
(long long int)t));
|
||||
int runclk = 0;
|
||||
uint32_t runclk = 0;
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
runclk = clkFrequency[RUN_CLK];
|
||||
#elif MYTHEN3D
|
||||
runclk = clkDivider[SYSTEM_C0];
|
||||
runclk = getFrequency(SYSTEM_C0);
|
||||
#endif
|
||||
uint64_t numClocks = t * (NS_TO_CLK_CYCLE * runclk);
|
||||
uint64_t numClocks = ns_to_clocks(t, runclk);
|
||||
setPatternWaitClocks(level, numClocks);
|
||||
}
|
||||
|
||||
|
||||
@@ -2402,7 +2402,11 @@ int get_exptime(int file_des) {
|
||||
"for this detector\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = getExpTime(&retval, mess);
|
||||
#else
|
||||
retval = getExpTime();
|
||||
#endif
|
||||
LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval));
|
||||
}
|
||||
#endif
|
||||
@@ -2472,6 +2476,9 @@ int set_exptime(int file_des) {
|
||||
"for this detector\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = setExpTime(val, mess);
|
||||
#else
|
||||
ret = setExpTime(val);
|
||||
int64_t retval = getExpTime();
|
||||
LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval));
|
||||
@@ -2482,6 +2489,7 @@ int set_exptime(int file_des) {
|
||||
(long long int)val, (long long int)retval);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2494,7 +2502,11 @@ int get_period(int file_des) {
|
||||
int64_t retval = -1;
|
||||
|
||||
// get only
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = getPeriod(&retval, mess);
|
||||
#else
|
||||
retval = getPeriod();
|
||||
#endif
|
||||
LOG(logDEBUG1, ("retval period %lld ns\n", (long long int)retval));
|
||||
return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
|
||||
}
|
||||
@@ -2510,6 +2522,9 @@ int set_period(int file_des) {
|
||||
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = setPeriod(arg, mess);
|
||||
#else
|
||||
ret = setPeriod(arg);
|
||||
int64_t retval = getPeriod();
|
||||
LOG(logDEBUG1, ("retval period %lld ns\n", (long long int)retval));
|
||||
@@ -2518,6 +2533,7 @@ int set_period(int file_des) {
|
||||
(long long int)arg, (long long int)retval);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return Server_SendResult(file_des, INT64, NULL, 0);
|
||||
}
|
||||
@@ -2533,7 +2549,11 @@ int get_delay_after_trigger(int file_des) {
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = getDelayAfterTrigger(&retval, mess);
|
||||
#else
|
||||
retval = getDelayAfterTrigger();
|
||||
#endif
|
||||
LOG(logDEBUG1,
|
||||
("retval delay after trigger %lld ns\n", (long long int)retval));
|
||||
#endif
|
||||
@@ -2557,6 +2577,9 @@ int set_delay_after_trigger(int file_des) {
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = setDelayAfterTrigger(arg, mess);
|
||||
#else
|
||||
ret = setDelayAfterTrigger(arg);
|
||||
int64_t retval = getDelayAfterTrigger();
|
||||
LOG(logDEBUG1,
|
||||
@@ -2568,6 +2591,7 @@ int set_delay_after_trigger(int file_des) {
|
||||
(long long int)arg, (long long int)retval);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT64, NULL, 0);
|
||||
@@ -2802,7 +2826,11 @@ int get_period_left(int file_des) {
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = getPeriodLeft(&retval, mess);
|
||||
#else
|
||||
retval = getPeriodLeft();
|
||||
#endif
|
||||
LOG(logDEBUG1, ("retval period left %lld ns\n", (long long int)retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
|
||||
@@ -2819,7 +2847,11 @@ int get_delay_after_trigger_left(int file_des) {
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
ret = getDelayAfterTriggerLeft(&retval, mess);
|
||||
#else
|
||||
retval = getDelayAfterTriggerLeft();
|
||||
#endif
|
||||
LOG(logDEBUG1,
|
||||
("retval delay after trigger left %lld ns\n", (long long int)retval));
|
||||
#endif
|
||||
@@ -3306,10 +3338,6 @@ int set_pattern_wait_clocks(int file_des) {
|
||||
if (ret == OK) {
|
||||
ret = validate_getPatternWaitClocksAndInterval(mess, loopLevel,
|
||||
&retval, 1);
|
||||
if ((int64_t)timeval != GET_FLAG) {
|
||||
validate64(&ret, mess, (int64_t)timeval, retval,
|
||||
"set pattern wait clocks", DEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -5693,11 +5721,9 @@ int set_clock_frequency(int file_des) {
|
||||
case ADC_CLOCK:
|
||||
c = ADC_CLK;
|
||||
break;
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
case DBIT_CLOCK:
|
||||
c = DBIT_CLK;
|
||||
break;
|
||||
#endif
|
||||
case RUN_CLOCK:
|
||||
c = RUN_CLK;
|
||||
break;
|
||||
@@ -5718,26 +5744,38 @@ int set_clock_frequency(int file_des) {
|
||||
(int)c);
|
||||
|
||||
if (getFrequency(c) == val) {
|
||||
LOG(logINFO, ("Same %s: %d %s\n", modeName, val,
|
||||
myDetectorType == GOTTHARD2 ? "Hz" : "MHz"));
|
||||
} else {
|
||||
LOG(logINFO, ("Same %s: %d %s\n", modeName, val, "Hz"));
|
||||
} else if (val < MIN_CLK_FREQ || val > MAX_CLK_FREQ) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Cannot set frequency to %f MHz. Frequency outside "
|
||||
"limits (%f - %f MHz)\n",
|
||||
val / 1e6, MIN_CLK_FREQ / 1e6, MAX_CLK_FREQ / 1e6);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#ifdef CHIPTESTBOARDD
|
||||
else if (ind == ADC_CLOCK && (val > MAXIMUM_ADC_CLK)) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Cannot set ADC clock frequency to %f MHz. Frequency "
|
||||
"outside limits (<= %f MHz)\n",
|
||||
val / 1e6, MAXIMUM_ADC_CLK / 1e6);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
int ret = setFrequency(c, val);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set %s to %d %s\n", modeName, val,
|
||||
myDetectorType == XILINX_CHIPTESTBOARD ? "kHz"
|
||||
: "MHz");
|
||||
sprintf(mess, "Could not set %s to %f MHz\n", modeName,
|
||||
val / 1e6);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getFrequency(c);
|
||||
LOG(logDEBUG1,
|
||||
("retval %s: %d %s\n", modeName, retval,
|
||||
myDetectorType == XILINX_CHIPTESTBOARD ? "kHz"
|
||||
: "MHz"));
|
||||
#if !defined(XILINX_CHIPTESTBOARDD)
|
||||
// XCTB will give the actual frequency, which is not
|
||||
("retval %s: %f MHz\n", modeName, retval / 1e6));
|
||||
// both CTB's will give the actual frequency, which is not
|
||||
// 100% identical to the set frequency
|
||||
validate(&ret, mess, val, retval, modeName, DEC);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5790,14 +5828,8 @@ int get_clock_frequency(int file_des) {
|
||||
if (ret == OK) {
|
||||
retval = getFrequency(c);
|
||||
char *clock_names[] = {CLK_NAMES};
|
||||
LOG(logDEBUG1,
|
||||
("retval %s clock (%d) frequency: %d %s\n", clock_names[c], (int)c,
|
||||
retval,
|
||||
myDetectorType == XILINX_CHIPTESTBOARD
|
||||
? "kHz"
|
||||
: (myDetectorType == GOTTHARD2 || myDetectorType == MYTHEN3
|
||||
? "Hz"
|
||||
: "MHz")));
|
||||
LOG(logDEBUG1, ("retval %s clock (%d) frequency: %d %s\n",
|
||||
clock_names[c], (int)c, retval, "Hz"));
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
@@ -7029,6 +7061,11 @@ int get_receiver_parameters(int file_des) {
|
||||
// exptime
|
||||
#ifdef MYTHEN3D
|
||||
i64 = 0;
|
||||
#elif defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
if (getExpTime(&i64, mess) == FAIL) {
|
||||
sprintf(mess, "Could not get exposure time.\n");
|
||||
return sendError(file_des);
|
||||
}
|
||||
#else
|
||||
i64 = getExpTime();
|
||||
#endif
|
||||
@@ -7037,7 +7074,15 @@ int get_receiver_parameters(int file_des) {
|
||||
return printSocketReadError();
|
||||
|
||||
// period
|
||||
i64 = 0;
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
if (getPeriod(&i64, mess) == FAIL) {
|
||||
sprintf(mess, "Could not get period.\n");
|
||||
return sendError(file_des);
|
||||
}
|
||||
#else
|
||||
i64 = getPeriod();
|
||||
#endif
|
||||
n += sendData(file_des, &i64, sizeof(i64), INT64);
|
||||
if (n < 0)
|
||||
return printSocketReadError();
|
||||
@@ -10894,13 +10939,6 @@ int set_pattern_wait_interval(int file_des) {
|
||||
if (Server_VerifyLock() == OK) {
|
||||
ret = validate_setPatternWaitClocksAndInterval(mess, loopLevel, timeval,
|
||||
0);
|
||||
if (ret == OK) {
|
||||
uint64_t retval = 0;
|
||||
ret = validate_getPatternWaitClocksAndInterval(mess, loopLevel,
|
||||
&retval, 0);
|
||||
validate64(&ret, mess, (int64_t)timeval, retval,
|
||||
"set pattern wait interval", DEC);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
@@ -363,7 +363,7 @@ void initStopServer() {
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
setupDetector();
|
||||
#endif
|
||||
}
|
||||
initCheckDone = 1;
|
||||
@@ -389,9 +389,13 @@ void setupDetector() {
|
||||
vLimit = DEFAULT_VLIMIT;
|
||||
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStatus(IDLE);
|
||||
setupUDPCommParameters();
|
||||
initializePatternWord();
|
||||
if (isControlServer) {
|
||||
sharedMemory_setStatus(IDLE);
|
||||
setupUDPCommParameters();
|
||||
initializePatternWord();
|
||||
} else {
|
||||
sharedMemory_setStop(0);
|
||||
}
|
||||
#endif
|
||||
// initialization only at start up (restart fpga)
|
||||
initError = waitTransceiverReset(initErrorMessage);
|
||||
@@ -444,9 +448,15 @@ void setupDetector() {
|
||||
setNumFrames(DEFAULT_NUM_FRAMES);
|
||||
setNumTriggers(DEFAULT_NUM_CYCLES);
|
||||
setTiming(DEFAULT_TIMING_MODE);
|
||||
setExpTime(DEFAULT_EXPTIME);
|
||||
setPeriod(DEFAULT_PERIOD);
|
||||
setDelayAfterTrigger(DEFAULT_DELAY);
|
||||
initError = setExpTime(DEFAULT_EXPTIME, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
initError = setPeriod(DEFAULT_PERIOD, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
initError = setDelayAfterTrigger(DEFAULT_DELAY, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
|
||||
setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER);
|
||||
}
|
||||
@@ -766,63 +776,132 @@ int getNumTransceiverSamples() {
|
||||
return ((bus_r(NO_SAMPLES_X_REG) & NO_SAMPLES_X_MSK) >> NO_SAMPLES_X_OFST);
|
||||
}
|
||||
|
||||
int setExpTime(int64_t val) {
|
||||
int setExpTime(int64_t val, char *mess) {
|
||||
setPatternWaitInterval(0, val);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getExpTime();
|
||||
// validate
|
||||
uint64_t arg_clocks = ns_to_clocks(val, clkFrequency[RUN_CLK]);
|
||||
uint64_t retval_clocks = getPatternWaitClocks(0);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(mess,
|
||||
"Failed to set exposure time. Could not set number of clocks "
|
||||
"to %lld, read %lld\n",
|
||||
(long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
int64_t retval = getPatternWaitInterval(0);
|
||||
if (val != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getExpTime(int64_t *retval, char *mess) {
|
||||
*retval = getPatternWaitInterval(0);
|
||||
if (*retval == -1) {
|
||||
sprintf(mess, "Failed to get exposure time.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getExpTime() { return getPatternWaitInterval(0); }
|
||||
|
||||
int setPeriod(int64_t val) {
|
||||
int setPeriod(int64_t val, char *mess) {
|
||||
if (val < 0) {
|
||||
LOG(logERROR, ("Invalid period: %lld ns\n", (long long int)val));
|
||||
sprintf(mess, "Invalid period: %lld ns\n", (long long int)val);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting period %lld ns\n", (long long int)val));
|
||||
val *= (NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
setU64BitReg(val, PERIOD_IN_REG_1, PERIOD_IN_REG_2);
|
||||
uint64_t arg_clocks = ns_to_clocks(val, clkFrequency[RUN_CLK]);
|
||||
setU64BitReg(arg_clocks, PERIOD_IN_REG_1, PERIOD_IN_REG_2);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getPeriod();
|
||||
val /= (NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
if (val != retval) {
|
||||
// validate
|
||||
uint64_t retval_clocks = getU64BitReg(PERIOD_IN_REG_1, PERIOD_IN_REG_2);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(mess,
|
||||
"Failed to set period. Could not set number of clocks "
|
||||
"to %lld, red %lld\n",
|
||||
(long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
int64_t retval = 0;
|
||||
if (getPeriod(&retval, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
if (val != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getPeriod() {
|
||||
return getU64BitReg(PERIOD_IN_REG_1, PERIOD_IN_REG_2) /
|
||||
(NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
int getPeriod(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[RUN_CLK] == 0) {
|
||||
sprintf(mess, "Cannot get period. Run clock frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = getU64BitReg(PERIOD_IN_REG_1, PERIOD_IN_REG_2);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[RUN_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setDelayAfterTrigger(int64_t val) {
|
||||
int setDelayAfterTrigger(int64_t val, char *mess) {
|
||||
if (val < 0) {
|
||||
LOG(logERROR, ("Invalid delay after trigger: %ld ns\n", val));
|
||||
sprintf(mess, "Invalid delay after trigger: %lld ns\n",
|
||||
(long long int)val);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting delay after trigger %ld ns\n", val));
|
||||
val *= (NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
setU64BitReg(val, DELAY_IN_REG_1, DELAY_IN_REG_2);
|
||||
LOG(logINFO, ("Setting delay after trigger %lld ns\n", (long long int)val));
|
||||
uint64_t arg_clocks = ns_to_clocks(val, clkFrequency[RUN_CLK]);
|
||||
setU64BitReg(arg_clocks, DELAY_IN_REG_1, DELAY_IN_REG_2);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getDelayAfterTrigger();
|
||||
val /= (NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
if (val != retval) {
|
||||
// validate
|
||||
uint64_t retval_clocks = getU64BitReg(DELAY_IN_REG_1, DELAY_IN_REG_2);
|
||||
if (arg_clocks != retval_clocks) {
|
||||
sprintf(
|
||||
mess,
|
||||
"Failed to set delay after trigger. Could not set number of clocks "
|
||||
"to %lld, read %lld\n",
|
||||
(long long int)arg_clocks, (long long int)retval_clocks);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// log rounding if any
|
||||
int64_t retval = 0;
|
||||
if (getDelayAfterTrigger(&retval, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
if (val != retval) {
|
||||
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
|
||||
(long long int)retval));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getDelayAfterTrigger() {
|
||||
return getU64BitReg(DELAY_IN_REG_1, DELAY_IN_REG_2) /
|
||||
(NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
int getDelayAfterTrigger(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[RUN_CLK] == 0) {
|
||||
sprintf(mess,
|
||||
"Cannot get delay after trigger. Run clock frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = getU64BitReg(DELAY_IN_REG_1, DELAY_IN_REG_2);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[RUN_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getNumFramesLeft() {
|
||||
@@ -833,14 +912,27 @@ int64_t getNumTriggersLeft() {
|
||||
return getU64BitReg(CYCLES_OUT_REG_1, CYCLES_OUT_REG_2);
|
||||
}
|
||||
|
||||
int64_t getDelayAfterTriggerLeft() {
|
||||
return getU64BitReg(DELAY_OUT_REG_1, DELAY_OUT_REG_2) /
|
||||
(NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
int getDelayAfterTriggerLeft(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[RUN_CLK] == 0) {
|
||||
sprintf(mess, "Cannot get delay after trigger left. Run clock "
|
||||
"frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = getU64BitReg(DELAY_OUT_REG_1, DELAY_OUT_REG_2);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[RUN_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getPeriodLeft() {
|
||||
return getU64BitReg(PERIOD_OUT_REG_1, PERIOD_OUT_REG_2) /
|
||||
(NS_TO_CLK_CYCLE * clkFrequency[RUN_CLK]);
|
||||
int getPeriodLeft(int64_t *retval, char *mess) {
|
||||
if (clkFrequency[RUN_CLK] == 0) {
|
||||
sprintf(mess, "Cannot get period left. Run clock frequency is 0.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
uint64_t numClocks = getU64BitReg(PERIOD_OUT_REG_1, PERIOD_OUT_REG_2);
|
||||
*retval = clocks_to_ns(numClocks, clkFrequency[RUN_CLK]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int64_t getFramesFromStart() {
|
||||
@@ -849,13 +941,14 @@ int64_t getFramesFromStart() {
|
||||
}
|
||||
|
||||
int64_t getActualTime() {
|
||||
return getU64BitReg(TIME_FROM_START_OUT_REG_1, TIME_FROM_START_OUT_REG_2) /
|
||||
(NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]);
|
||||
// in unit of 100ns
|
||||
return getU64BitReg(TIME_FROM_START_OUT_REG_1, TIME_FROM_START_OUT_REG_2) *
|
||||
100;
|
||||
}
|
||||
|
||||
int64_t getMeasurementTime() {
|
||||
return getU64BitReg(FRAME_TIME_OUT_REG_1, FRAME_TIME_OUT_REG_2) /
|
||||
(NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]);
|
||||
// in unit of 100ns
|
||||
return getU64BitReg(FRAME_TIME_OUT_REG_1, FRAME_TIME_OUT_REG_2) * 100;
|
||||
}
|
||||
|
||||
/* parameters - dac, adc, hv */
|
||||
@@ -1447,11 +1540,22 @@ void *start_timer(void *arg) {
|
||||
if (!isControlServer) {
|
||||
return NULL;
|
||||
}
|
||||
int64_t periodNs = 0;
|
||||
int64_t expUs = 0;
|
||||
{
|
||||
char mess[MAX_STR_LENGTH] = {0};
|
||||
if (getPeriod(&periodNs, mess) == FAIL) {
|
||||
LOG(logERROR, ("Failed to get period.\n"));
|
||||
return NULL;
|
||||
}
|
||||
if (getExpTime(&expUs, mess) == FAIL) {
|
||||
LOG(logERROR, ("Failed to get exposure time.\n"));
|
||||
return NULL;
|
||||
}
|
||||
expUs /= 1000;
|
||||
}
|
||||
|
||||
int64_t periodNs = getPeriod();
|
||||
int numFrames = (getNumFrames() * getNumTriggers());
|
||||
int64_t expUs = getExpTime() / 1000;
|
||||
|
||||
int imageSize = calculateDataBytes();
|
||||
int maxDataSize = MAX_DATA_SIZE_IN_PACKET;
|
||||
int packetSize = sizeof(sls_detector_header) + maxDataSize;
|
||||
@@ -1716,11 +1820,11 @@ int setFrequency(enum CLKINDEX ind, int val) {
|
||||
}
|
||||
|
||||
char *clock_names[] = {CLK_NAMES};
|
||||
LOG(logINFO, ("\tSetting %s clock (%d) frequency to %d kHz\n",
|
||||
LOG(logINFO, ("\tSetting %s clock (%d) frequency to %d Hz\n",
|
||||
clock_names[ind], ind, val));
|
||||
|
||||
if (XILINX_PLL_setFrequency(ind, val) == FAIL) {
|
||||
LOG(logERROR, ("\tCould not set %s clock (%d) frequency to %d kHz\n",
|
||||
LOG(logERROR, ("\tCould not set %s clock (%d) frequency to %d Hz\n",
|
||||
clock_names[ind], ind, val));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -84,10 +84,10 @@ void setNumFrames(int64_t val);
|
||||
int64_t getNumFrames();
|
||||
void setNumTriggers(int64_t val);
|
||||
int64_t getNumTriggers();
|
||||
int setExpTime(int64_t val);
|
||||
int64_t getExpTime();
|
||||
int setPeriod(int64_t val);
|
||||
int64_t getPeriod();
|
||||
int setExpTime(int64_t val, char *mess);
|
||||
int getExpTime(int64_t *retval, char *mess);
|
||||
int setPeriod(int64_t val, char *mess);
|
||||
int getPeriod(int64_t *retval, char *mess);
|
||||
int setNumAnalogSamples(int val);
|
||||
int getNumAnalogSamples();
|
||||
int setNumDigitalSamples(int val);
|
||||
@@ -97,10 +97,10 @@ int getNumTransceiverSamples();
|
||||
|
||||
int64_t getNumFramesLeft();
|
||||
int64_t getNumTriggersLeft();
|
||||
int setDelayAfterTrigger(int64_t val);
|
||||
int64_t getDelayAfterTrigger();
|
||||
int64_t getDelayAfterTriggerLeft();
|
||||
int64_t getPeriodLeft();
|
||||
int setDelayAfterTrigger(int64_t val, char *mess);
|
||||
int getDelayAfterTrigger(int64_t *retval, char *mess);
|
||||
int getDelayAfterTriggerLeft(int64_t *retval, char *mess);
|
||||
int getPeriodLeft(int64_t *retval, char *mess);
|
||||
int64_t getFramesFromStart();
|
||||
int64_t getActualTime();
|
||||
int64_t getMeasurementTime();
|
||||
|
||||
@@ -158,8 +158,11 @@ typedef struct udp_header_struct {
|
||||
enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS };
|
||||
#define CLK_NAMES "run", "adc", "sync", "dbit"
|
||||
|
||||
#define DEFAULT_RUN_CLK (20000) // 20 MHz
|
||||
#define DEFAULT_ADC_CLK (100000) // 100 MHz
|
||||
#define DEFAULT_SYNC_CLK (20000) // 20 MHz
|
||||
#define DEFAULT_DBIT_CLK (100000) // 100 MHz
|
||||
#define NS_TO_CLK_CYCLE (1E-6) // ns to kHz
|
||||
#define DEFAULT_RUN_CLK (20000000) // 20 MHz
|
||||
#define DEFAULT_ADC_CLK (100000000) // 100 MHz
|
||||
#define DEFAULT_SYNC_CLK (20000000) // 20 MHz
|
||||
#define DEFAULT_DBIT_CLK (100000000) // 100 MHz
|
||||
#define NS_TO_CLK_CYCLE (1E-9) // ns to Hz
|
||||
|
||||
#define MIN_CLK_FREQ (10000000) // 10 MHz
|
||||
#define MAX_CLK_FREQ (300000000) // 300 MHz
|
||||
|
||||
@@ -54,6 +54,9 @@ class Caller {
|
||||
return ToString(value, unit);
|
||||
}
|
||||
|
||||
std::string OutString(const Result<defs::Hz> &value,
|
||||
const std::string &unit);
|
||||
|
||||
std::vector<std::string> getAllCommands();
|
||||
std::map<std::string, std::string> GetDeprecatedCommands();
|
||||
std::string list(int action);
|
||||
@@ -96,6 +99,7 @@ class Caller {
|
||||
defs::dacIndex parseDacIndex(int argIndex, bool isCtb);
|
||||
bool parseMV(int argIndex);
|
||||
defs::powerIndex parsePowerIndex(int argIndex);
|
||||
defs::FrequencyUnit parseFrequencyUnit(const std::string &s);
|
||||
|
||||
FunctionMap functions{
|
||||
{"list", &Caller::list},
|
||||
|
||||
@@ -16,6 +16,7 @@ type_values = {
|
||||
'special::mv': ["mv", "mV"],
|
||||
"special::deg": ["deg"],
|
||||
"special::time_unit": ["s", "ms", "us", "ns"],
|
||||
"special::freq_unit": ["Hz", "kHz", "MHz"],
|
||||
"special::hard": ["hard"],
|
||||
"special::force-delete-normal-file": ["--force-delete-normal-file"],
|
||||
"special::currentSourceFix": ["fix", "nofix"],
|
||||
@@ -40,11 +41,11 @@ def get_types(arg_types):
|
||||
#list of options with a command line call that fetches them
|
||||
#TODO! Rename sls_detector_get
|
||||
if "defs::dacIndex" in arg_types:
|
||||
return "`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
return r"`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
elif "defs::detectorSettings" in arg_types:
|
||||
return "`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
return r"`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
elif "defs::timingMode" in arg_types:
|
||||
return "`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
return r"`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
|
||||
|
||||
return ret
|
||||
|
||||
@@ -96,10 +96,18 @@ return 0
|
||||
}
|
||||
__adcclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -565,12 +573,12 @@ __dacname() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
@@ -611,10 +619,18 @@ return 0
|
||||
}
|
||||
__dbitclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -648,21 +664,21 @@ __defaultdac() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -671,13 +687,13 @@ __defaultpattern() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2120,10 +2136,18 @@ return 0
|
||||
}
|
||||
__runclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -2408,7 +2432,7 @@ __scan() {
|
||||
FCN_RETURN=""
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
@@ -2461,7 +2485,7 @@ __settings() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2571,12 +2595,12 @@ __slowadcname() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
@@ -2680,6 +2704,16 @@ return 0
|
||||
}
|
||||
__syncclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__temp_10ge() {
|
||||
@@ -2773,13 +2807,13 @@ if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "5" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2791,13 +2825,13 @@ if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "5" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2806,7 +2840,7 @@ __timing() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
|
||||
@@ -20,10 +20,18 @@ return 0
|
||||
}
|
||||
__adcclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -489,12 +497,12 @@ __dacname() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
@@ -535,10 +543,18 @@ return 0
|
||||
}
|
||||
__dbitclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -572,21 +588,21 @@ __defaultdac() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -595,13 +611,13 @@ __defaultpattern() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2044,10 +2060,18 @@ return 0
|
||||
}
|
||||
__runclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -2332,7 +2356,7 @@ __scan() {
|
||||
FCN_RETURN=""
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
@@ -2385,7 +2409,7 @@ __settings() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2495,12 +2519,12 @@ __slowadcname() {
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
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="`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
@@ -2604,6 +2628,16 @@ return 0
|
||||
}
|
||||
__syncclk() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="Hz MHz kHz"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__temp_10ge() {
|
||||
@@ -2697,13 +2731,13 @@ if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "5" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2715,13 +2749,13 @@ if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "5" ]]; then
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
@@ -2730,7 +2764,7 @@ __timing() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN="`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\1/' | sed 's/,//g'`"
|
||||
FCN_RETURN="`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
|
||||
@@ -2,6 +2,56 @@
|
||||
# detectors: MYTHEN3
|
||||
|
||||
################# TEMPLATES #################
|
||||
FREQ_COMMAND:
|
||||
infer_action: true
|
||||
help: ""
|
||||
template: true
|
||||
actions:
|
||||
GET:
|
||||
require_det_id: true
|
||||
function: ''
|
||||
args:
|
||||
- argc: 0
|
||||
output: [ OutString(t) ]
|
||||
- argc: 1
|
||||
arg_types: [ special::freq_unit ]
|
||||
output: [ "OutString(t , args[0])" ]
|
||||
PUT:
|
||||
function: ''
|
||||
require_det_id: true
|
||||
input: [ converted_freq ]
|
||||
input_types: [ defs::Hz ]
|
||||
args:
|
||||
- argc: 1
|
||||
arg_types: [ std::string ]
|
||||
|
||||
separate_freq_units:
|
||||
input: 'args[0]'
|
||||
output: [ converted_freq, unit ]
|
||||
output: [ 'args[0]' ]
|
||||
- argc: 2
|
||||
arg_types: [ int, special::freq_unit ]
|
||||
|
||||
convert_to_freq:
|
||||
input: [ 'args[0]', 'args[1]' ]
|
||||
output: converted_freq
|
||||
output: [ 'args[0]', 'args[1]' ]
|
||||
|
||||
FREQ_GET_COMMAND:
|
||||
infer_action: true
|
||||
help: ""
|
||||
template: true
|
||||
actions:
|
||||
GET:
|
||||
require_det_id: true
|
||||
function: ''
|
||||
args:
|
||||
- argc: 0
|
||||
output: [ OutString(t) ]
|
||||
- argc: 1
|
||||
arg_types: [ special::freq_unit ]
|
||||
output: [ "OutString(t , args[0])" ]
|
||||
|
||||
TIME_COMMAND:
|
||||
infer_action: true
|
||||
help: ""
|
||||
@@ -401,6 +451,44 @@ CTB_GET_INDEX:
|
||||
|
||||
|
||||
################# COMMANDS ##################################
|
||||
################# FREQ_COMMAND #############
|
||||
adcclk:
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb][Xilinx Ctb] ADC clock frequency."
|
||||
inherit_actions: FREQ_COMMAND
|
||||
actions:
|
||||
GET:
|
||||
function: getADCClock
|
||||
PUT:
|
||||
function: setADCClock
|
||||
|
||||
runclk:
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb][Xilinx Ctb] Run clock frequency."
|
||||
inherit_actions: FREQ_COMMAND
|
||||
actions:
|
||||
GET:
|
||||
function: getRUNClock
|
||||
PUT:
|
||||
function: setRUNClock
|
||||
|
||||
|
||||
dbitclk:
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb][Xilinx Ctb] Clock for latching the digital bits."
|
||||
inherit_actions: FREQ_COMMAND
|
||||
actions:
|
||||
GET:
|
||||
function: getDBITClock
|
||||
PUT:
|
||||
function: setDBITClock
|
||||
|
||||
################# FREQ_GET_COMMAND #############
|
||||
|
||||
syncclk:
|
||||
inherit_actions: FREQ_GET_COMMAND
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb] Sync clock."
|
||||
actions:
|
||||
GET:
|
||||
function: getSYNCClock
|
||||
|
||||
################# TIME_COMMAND #############
|
||||
|
||||
period:
|
||||
@@ -1243,23 +1331,6 @@ asamples:
|
||||
PUT:
|
||||
function: setNumberOfAnalogSamples
|
||||
|
||||
adcclk:
|
||||
help: "[n_clk in MHz]\n\t[Ctb] ADC clock frequency in MHz.\n\t[xilinx Ctb] ADC clock frequency in kHz."
|
||||
inherit_actions: INTEGER_COMMAND_VEC_ID
|
||||
actions:
|
||||
GET:
|
||||
function: getADCClock
|
||||
PUT:
|
||||
function: setADCClock
|
||||
|
||||
runclk:
|
||||
help: "[n_clk in MHz]\n\t[Ctb] Run clock in MHz.\n\t[xilinx Ctb] Run clock in kHz."
|
||||
inherit_actions: INTEGER_COMMAND_VEC_ID
|
||||
actions:
|
||||
GET:
|
||||
function: getRUNClock
|
||||
PUT:
|
||||
function: setRUNClock
|
||||
|
||||
dsamples:
|
||||
help: "[n_value]\n\t[Ctb] Number of digital samples expected."
|
||||
@@ -1289,15 +1360,6 @@ romode:
|
||||
function: setReadoutMode
|
||||
input_types: [ defs::readoutMode ]
|
||||
|
||||
dbitclk:
|
||||
help: "[n_clk in MHz]\n\t[Ctb] Clock for latching the digital bits in MHz.\n\t[xilinx Ctb] Clock for latching the digital bits in kHz."
|
||||
inherit_actions: INTEGER_COMMAND_VEC_ID
|
||||
actions:
|
||||
GET:
|
||||
function: getDBITClock
|
||||
PUT:
|
||||
function: setDBITClock
|
||||
|
||||
extsampling:
|
||||
help: "[0, 1]\n\t[Ctb] Enable for external sampling signal for digital data to signal by extsampling src command. For advanced users only."
|
||||
inherit_actions: INTEGER_COMMAND_VEC_ID
|
||||
@@ -1912,19 +1974,12 @@ burstsl:
|
||||
GET:
|
||||
function: getNumberOfBurstsLeft
|
||||
|
||||
syncclk:
|
||||
inherit_actions: GET_COMMAND
|
||||
help: "[n_clk in MHz]\n\t[Ctb] Sync clock in MHz."
|
||||
actions:
|
||||
GET:
|
||||
function: getSYNCClock
|
||||
|
||||
patfname:
|
||||
inherit_actions: GET_COMMAND
|
||||
help: "\n\t[Ctb][Mythen3][Xilinx Ctb] Gets the pattern file name including path of the last pattern uploaded. Returns an empty if nothing was uploaded or via a server default file"
|
||||
actions:
|
||||
GET:
|
||||
function: getPatterFileName
|
||||
function: getPatternFileName
|
||||
|
||||
lastclient:
|
||||
inherit_actions: GET_COMMAND
|
||||
|
||||
@@ -50,7 +50,6 @@ class CommandParser:
|
||||
if len(arg['input_types']) != len(arg['input']):
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of inputs')
|
||||
if 'separate_time_units' in arg:
|
||||
|
||||
if arg['separate_time_units']['input'] == "":
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of inputs for separate_time_units')
|
||||
if len(arg['separate_time_units']['output']) != 2:
|
||||
@@ -60,6 +59,16 @@ class CommandParser:
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of inputs for convert_to_time')
|
||||
if len(arg['convert_to_time']['output']) == "":
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of outputs for convert_to_time')
|
||||
if 'separate_freq_units' in arg:
|
||||
if arg['separate_freq_units']['input'] == "":
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of inputs for separate_freq_units')
|
||||
if len(arg['separate_freq_units']['output']) != 2:
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of outputs for separate_freq_units')
|
||||
if 'convert_to_freq' in arg:
|
||||
if len(arg['convert_to_freq']['input']) != 2:
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of inputs for convert_to_freq')
|
||||
if len(arg['convert_to_freq']['output']) == "":
|
||||
raise ValueError(f'Argument {arg} does not have the correct number of outputs for convert_to_freq')
|
||||
# if infer_action:
|
||||
# if arg['argc'] in self.argc_set:
|
||||
# raise ValueError(f'Argument {arg} has a duplicate argc')
|
||||
|
||||
@@ -142,6 +142,16 @@ class CodeGenerator:
|
||||
if 'convert_to_time' in arg and arg['convert_to_time']:
|
||||
self.write_line(f'auto {arg["convert_to_time"]["output"]} = '
|
||||
f'StringTo < time::ns > ({", ".join(arg["convert_to_time"]["input"])});')
|
||||
if 'separate_freq_units' in arg and arg['separate_freq_units']:
|
||||
self.write_line(f'std::string tmp_freq({arg["separate_freq_units"]["input"]});')
|
||||
self.write_line(f'std::string {arg["separate_freq_units"]["output"][1]}'
|
||||
f' = RemoveUnit(tmp_freq);')
|
||||
self.write_line(f'auto {arg["separate_freq_units"]["output"][0]} = '
|
||||
f'StringTo < defs::Hz > (tmp_freq,'
|
||||
f' {arg["separate_freq_units"]["output"][1]});')
|
||||
if 'convert_to_freq' in arg and arg['convert_to_freq']:
|
||||
self.write_line(f'auto {arg["convert_to_freq"]["output"]} = '
|
||||
f'StringTo < defs::Hz > ({", ".join(arg["convert_to_freq"]["input"])});')
|
||||
input_arguments = []
|
||||
if 'exceptions' in arg:
|
||||
for exception in arg['exceptions']:
|
||||
|
||||
@@ -86,28 +86,69 @@ adcclk:
|
||||
- OutString(t)
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
- arg_types:
|
||||
- special::freq_unit
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: getADCClock
|
||||
input: []
|
||||
input_types: []
|
||||
output:
|
||||
- OutString(t , args[0])
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- int
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input:
|
||||
- true
|
||||
- false
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: setADCClock
|
||||
input:
|
||||
- args[0]
|
||||
- converted_freq
|
||||
input_types:
|
||||
- int
|
||||
- defs::Hz
|
||||
output:
|
||||
- args.front()
|
||||
- args[0]
|
||||
require_det_id: true
|
||||
separate_freq_units:
|
||||
input: args[0]
|
||||
output:
|
||||
- converted_freq
|
||||
- unit
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- int
|
||||
- special::freq_unit
|
||||
argc: 2
|
||||
cast_input:
|
||||
- false
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
convert_to_freq:
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
output: converted_freq
|
||||
function: setADCClock
|
||||
input:
|
||||
- converted_freq
|
||||
input_types:
|
||||
- defs::Hz
|
||||
output:
|
||||
- args[0]
|
||||
- args[1]
|
||||
require_det_id: true
|
||||
store_result_in_t: false
|
||||
command_name: adcclk
|
||||
function_alias: adcclk
|
||||
help: "[n_clk in MHz]\n\t[Ctb] ADC clock frequency in MHz.\n\t[xilinx Ctb] ADC clock\
|
||||
\ frequency in kHz."
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb][Xilinx Ctb] ADC clock\
|
||||
\ frequency."
|
||||
infer_action: true
|
||||
template: true
|
||||
adcenable:
|
||||
@@ -2060,28 +2101,69 @@ dbitclk:
|
||||
- OutString(t)
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
- arg_types:
|
||||
- special::freq_unit
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: getDBITClock
|
||||
input: []
|
||||
input_types: []
|
||||
output:
|
||||
- OutString(t , args[0])
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- int
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input:
|
||||
- true
|
||||
- false
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: setDBITClock
|
||||
input:
|
||||
- args[0]
|
||||
- converted_freq
|
||||
input_types:
|
||||
- int
|
||||
- defs::Hz
|
||||
output:
|
||||
- args.front()
|
||||
- args[0]
|
||||
require_det_id: true
|
||||
separate_freq_units:
|
||||
input: args[0]
|
||||
output:
|
||||
- converted_freq
|
||||
- unit
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- int
|
||||
- special::freq_unit
|
||||
argc: 2
|
||||
cast_input:
|
||||
- false
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
convert_to_freq:
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
output: converted_freq
|
||||
function: setDBITClock
|
||||
input:
|
||||
- converted_freq
|
||||
input_types:
|
||||
- defs::Hz
|
||||
output:
|
||||
- args[0]
|
||||
- args[1]
|
||||
require_det_id: true
|
||||
store_result_in_t: false
|
||||
command_name: dbitclk
|
||||
function_alias: dbitclk
|
||||
help: "[n_clk in MHz]\n\t[Ctb] Clock for latching the digital bits in MHz.\n\t[xilinx\
|
||||
\ Ctb] Clock for latching the digital bits in kHz."
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb][Xilinx Ctb] Clock\
|
||||
\ for latching the digital bits."
|
||||
infer_action: true
|
||||
template: true
|
||||
dbitphase:
|
||||
@@ -5788,7 +5870,7 @@ patfname:
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: getPatterFileName
|
||||
function: getPatternFileName
|
||||
input: []
|
||||
input_types: []
|
||||
output:
|
||||
@@ -8140,27 +8222,69 @@ runclk:
|
||||
- OutString(t)
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
- arg_types:
|
||||
- special::freq_unit
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: getRUNClock
|
||||
input: []
|
||||
input_types: []
|
||||
output:
|
||||
- OutString(t , args[0])
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- int
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input:
|
||||
- true
|
||||
- false
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: setRUNClock
|
||||
input:
|
||||
- args[0]
|
||||
- converted_freq
|
||||
input_types:
|
||||
- int
|
||||
- defs::Hz
|
||||
output:
|
||||
- args.front()
|
||||
- args[0]
|
||||
require_det_id: true
|
||||
separate_freq_units:
|
||||
input: args[0]
|
||||
output:
|
||||
- converted_freq
|
||||
- unit
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- int
|
||||
- special::freq_unit
|
||||
argc: 2
|
||||
cast_input:
|
||||
- false
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
convert_to_freq:
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
output: converted_freq
|
||||
function: setRUNClock
|
||||
input:
|
||||
- converted_freq
|
||||
input_types:
|
||||
- defs::Hz
|
||||
output:
|
||||
- args[0]
|
||||
- args[1]
|
||||
require_det_id: true
|
||||
store_result_in_t: false
|
||||
command_name: runclk
|
||||
function_alias: runclk
|
||||
help: "[n_clk in MHz]\n\t[Ctb] Run clock in MHz.\n\t[xilinx Ctb] Run clock in kHz."
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb][Xilinx Ctb] Run clock\
|
||||
\ frequency."
|
||||
infer_action: true
|
||||
template: true
|
||||
runtime:
|
||||
@@ -10575,9 +10699,22 @@ syncclk:
|
||||
- OutString(t)
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
- arg_types:
|
||||
- special::freq_unit
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: getSYNCClock
|
||||
input: []
|
||||
input_types: []
|
||||
output:
|
||||
- OutString(t , args[0])
|
||||
require_det_id: true
|
||||
store_result_in_t: true
|
||||
command_name: syncclk
|
||||
function_alias: syncclk
|
||||
help: "[n_clk in MHz]\n\t[Ctb] Sync clock in MHz."
|
||||
help: "[n_clk] [(optional unit) Hz(default)|kHz|MHz]\n\t[Ctb] Sync clock."
|
||||
infer_action: true
|
||||
template: true
|
||||
temp_10ge:
|
||||
|
||||
@@ -122,7 +122,25 @@ def generate(
|
||||
f'StringTo < time::ns > ({", ".join(arg["convert_to_time"]["input"])});')
|
||||
codegen.write_line(
|
||||
f'}} catch (...) {{ throw RuntimeError("Could not convert arguments to time::ns");}}')
|
||||
elif 'separate_freq_units' in arg and arg['separate_freq_units']:
|
||||
codegen.write_line(f'try {{')
|
||||
# TODO: refactor this repeating code
|
||||
codegen.write_line(f'std::string tmp_freq({arg["separate_freq_units"]["input"]});')
|
||||
codegen.write_line(f'std::string {arg["separate_freq_units"]["output"][1]}'
|
||||
f' = RemoveUnit(tmp_freq);')
|
||||
codegen.write_line(f'auto {arg["separate_freq_units"]["output"][0]} = '
|
||||
f'StringTo < defs::Hz > (tmp_freq,'
|
||||
f' {arg["separate_freq_units"]["output"][1]});')
|
||||
codegen.write_line(
|
||||
f'}} catch (...) {{ throw RuntimeError("Could not convert argument to defs::Hz");}}')
|
||||
|
||||
elif 'convert_to_freq' in arg and arg['convert_to_freq']:
|
||||
codegen.write_line(f'try {{')
|
||||
|
||||
codegen.write_line(
|
||||
f'StringTo < defs::Hz > ({", ".join(arg["convert_to_freq"]["input"])});')
|
||||
codegen.write_line(
|
||||
f'}} catch (...) {{ throw RuntimeError("Could not convert arguments to defs::Hz");}}')
|
||||
for i in range(len(arg['input'])):
|
||||
if not arg['cast_input'][i]:
|
||||
continue
|
||||
|
||||
@@ -302,7 +302,13 @@ write_arg in codegen reads the argument fields and generate c++ code accordingly
|
||||
std::string $output[1]$ = RemoveUnit(tmp_time);
|
||||
auto $output[0]$ = StringTo<time::ns>(tmp_time, $output[1]$);
|
||||
```
|
||||
- convert_to_time: takes three parameters: input[0], input[1], output
|
||||
- separate_freq_units: takes three parameters: input, output[0], output[1] each one is a variable name
|
||||
```cpp
|
||||
std::string tmp_freq($input$);
|
||||
std::string $output[1]$ = RemoveUnit(tmp_freq);
|
||||
auto $output[0]$ = StringTo<defs::Hz>(tmp_freq, $output[1]$);
|
||||
```
|
||||
- convert_to_time and convert_to_freq: takes three parameters: input[0], input[1], output
|
||||
```cpp
|
||||
auto output = StringTo<time::ns>(input[0], input[1]);
|
||||
```
|
||||
|
||||
@@ -1613,20 +1613,26 @@ class Detector {
|
||||
/** [CTB] */
|
||||
void setNumberOfAnalogSamples(int value, Positions pos = {});
|
||||
|
||||
/** [CTB] in MHz, [XCTB] in kHz */
|
||||
Result<int> getADCClock(Positions pos = {}) const;
|
||||
/** [CTB][XCTB] */
|
||||
Result<defs::Hz> getADCClock(Positions pos = {}) const;
|
||||
|
||||
/** [CTB] in MHz, [XCTB] in kHz */
|
||||
void setADCClock(int value_in_MHz, Positions pos = {});
|
||||
/** [CTB][XCTB] */
|
||||
void setADCClock(defs::Hz val, Positions pos = {});
|
||||
|
||||
/** [CTB] in MHz, [XCTB] in kHz */
|
||||
Result<int> getRUNClock(Positions pos = {}) const;
|
||||
/** [CTB][XCTB] */
|
||||
Result<defs::Hz> getRUNClock(Positions pos = {}) const;
|
||||
|
||||
/** [CTB] in MHz, [XCTB] in kHz */
|
||||
void setRUNClock(int value_in_MHz, Positions pos = {});
|
||||
/** [CTB][XCTB] */
|
||||
void setRUNClock(defs::Hz val, Positions pos = {});
|
||||
|
||||
/** [CTB] in MHZ */
|
||||
Result<int> getSYNCClock(Positions pos = {}) const;
|
||||
/** [CTB][XCTB] */
|
||||
Result<defs::Hz> getDBITClock(Positions pos = {}) const;
|
||||
|
||||
/** [CTB][XCTB] */
|
||||
void setDBITClock(defs::Hz val, Positions pos = {});
|
||||
|
||||
/** [CTB][XCTB] */
|
||||
Result<defs::Hz> getSYNCClock(Positions pos = {}) const;
|
||||
|
||||
/** gets list of power enums */
|
||||
std::vector<defs::powerIndex> getPowerList() const;
|
||||
@@ -1721,12 +1727,6 @@ class Detector {
|
||||
*/
|
||||
void setReadoutMode(defs::readoutMode value, Positions pos = {});
|
||||
|
||||
/** [CTB] in MHz, [XCTB] in kHz */
|
||||
Result<int> getDBITClock(Positions pos = {}) const;
|
||||
|
||||
/** [CTB] in MHz, [XCTB] in kHz */
|
||||
void setDBITClock(int value_in_MHz, Positions pos = {});
|
||||
|
||||
/** [CTB] */
|
||||
Result<int> getExternalSamplingSource(Positions pos = {}) const;
|
||||
|
||||
@@ -1934,7 +1934,7 @@ class Detector {
|
||||
/** [CTB][Mythen3][Xilinx CTB] Gets the pattern file name including path of
|
||||
* the last pattern uploaded. \n Returns an empty if nothing was uploaded or
|
||||
* via a server default file*/
|
||||
Result<std::string> getPatterFileName(Positions pos = {}) const;
|
||||
Result<std::string> getPatternFileName(Positions pos = {}) const;
|
||||
|
||||
/** [CTB][Mythen3][Xilinx CTB] Loads ASCII pattern file directly to server
|
||||
* (instead of executing line by line)*/
|
||||
|
||||
@@ -38,6 +38,7 @@ template <class T, class Allocator = std::allocator<T>> class Result {
|
||||
template <typename V, typename = typename std::enable_if<
|
||||
std::is_integral<V>::value &&
|
||||
(std::is_same<T, time::ns>::value ||
|
||||
std::is_same<T, defs::Hz>::value ||
|
||||
std::is_same<T, bool>::value)>::type>
|
||||
Result(const Result<V> &from) {
|
||||
vec.reserve(from.size());
|
||||
@@ -49,6 +50,7 @@ template <class T, class Allocator = std::allocator<T>> class Result {
|
||||
template <typename V, typename = typename std::enable_if<
|
||||
std::is_integral<V>::value &&
|
||||
(std::is_same<T, time::ns>::value ||
|
||||
std::is_same<T, defs::Hz>::value ||
|
||||
std::is_same<T, bool>::value)>::type>
|
||||
Result(Result<V> &from) {
|
||||
vec.reserve(from.size());
|
||||
@@ -60,6 +62,7 @@ template <class T, class Allocator = std::allocator<T>> class Result {
|
||||
template <typename V, typename = typename std::enable_if<
|
||||
std::is_integral<V>::value &&
|
||||
(std::is_same<T, time::ns>::value ||
|
||||
std::is_same<T, defs::Hz>::value ||
|
||||
std::is_same<T, bool>::value)>::type>
|
||||
Result(Result<V> &&from) {
|
||||
vec.reserve(from.size());
|
||||
|
||||
@@ -72,34 +72,46 @@ std::string Caller::adcclk(int action) {
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([n_clk in MHz]
|
||||
[Ctb] ADC clock frequency in MHz.
|
||||
[xilinx Ctb] ADC clock frequency in kHz. )V0G0N"
|
||||
os << R"V0G0N([n_clk] [(optional unit) Hz(default)|kHz|MHz]
|
||||
[Ctb][Xilinx Ctb] ADC clock frequency. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (1 && args.size() != 0) {
|
||||
if (1 && args.size() != 0 && args.size() != 1) {
|
||||
throw RuntimeError("Wrong number of arguments for action GET");
|
||||
}
|
||||
|
||||
if (args.size() == 0) {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (1 && args.size() != 1) {
|
||||
if (1 && args.size() != 1 && args.size() != 2) {
|
||||
throw RuntimeError("Wrong number of arguments for action PUT");
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
try {
|
||||
StringTo<int>(args[0]);
|
||||
std::string tmp_freq(args[0]);
|
||||
std::string unit = RemoveUnit(tmp_freq);
|
||||
auto converted_freq = StringTo<defs::Hz>(tmp_freq, unit);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to int");
|
||||
throw RuntimeError("Could not convert argument to defs::Hz");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<defs::Hz>(args[0], args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert arguments to defs::Hz");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,13 +129,26 @@ std::string Caller::adcclk(int action) {
|
||||
auto t = det->getADCClock(std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
auto t = det->getADCClock(std::vector<int>{det_id});
|
||||
os << OutString(t, args[0]) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (args.size() == 1) {
|
||||
auto arg0 = StringTo<int>(args[0]);
|
||||
det->setADCClock(arg0, std::vector<int>{det_id});
|
||||
os << args.front() << '\n';
|
||||
std::string tmp_freq(args[0]);
|
||||
std::string unit = RemoveUnit(tmp_freq);
|
||||
auto converted_freq = StringTo<defs::Hz>(tmp_freq, unit);
|
||||
det->setADCClock(converted_freq, std::vector<int>{det_id});
|
||||
os << args[0] << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
auto converted_freq = StringTo<defs::Hz>(args[0], args[1]);
|
||||
det->setADCClock(converted_freq, std::vector<int>{det_id});
|
||||
os << args[0] << args[1] << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2482,34 +2507,46 @@ std::string Caller::dbitclk(int action) {
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([n_clk in MHz]
|
||||
[Ctb] Clock for latching the digital bits in MHz.
|
||||
[xilinx Ctb] Clock for latching the digital bits in kHz. )V0G0N"
|
||||
os << R"V0G0N([n_clk] [(optional unit) Hz(default)|kHz|MHz]
|
||||
[Ctb][Xilinx Ctb] Clock for latching the digital bits. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (1 && args.size() != 0) {
|
||||
if (1 && args.size() != 0 && args.size() != 1) {
|
||||
throw RuntimeError("Wrong number of arguments for action GET");
|
||||
}
|
||||
|
||||
if (args.size() == 0) {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (1 && args.size() != 1) {
|
||||
if (1 && args.size() != 1 && args.size() != 2) {
|
||||
throw RuntimeError("Wrong number of arguments for action PUT");
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
try {
|
||||
StringTo<int>(args[0]);
|
||||
std::string tmp_freq(args[0]);
|
||||
std::string unit = RemoveUnit(tmp_freq);
|
||||
auto converted_freq = StringTo<defs::Hz>(tmp_freq, unit);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to int");
|
||||
throw RuntimeError("Could not convert argument to defs::Hz");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<defs::Hz>(args[0], args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert arguments to defs::Hz");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2527,13 +2564,26 @@ std::string Caller::dbitclk(int action) {
|
||||
auto t = det->getDBITClock(std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
auto t = det->getDBITClock(std::vector<int>{det_id});
|
||||
os << OutString(t, args[0]) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (args.size() == 1) {
|
||||
auto arg0 = StringTo<int>(args[0]);
|
||||
det->setDBITClock(arg0, std::vector<int>{det_id});
|
||||
os << args.front() << '\n';
|
||||
std::string tmp_freq(args[0]);
|
||||
std::string unit = RemoveUnit(tmp_freq);
|
||||
auto converted_freq = StringTo<defs::Hz>(tmp_freq, unit);
|
||||
det->setDBITClock(converted_freq, std::vector<int>{det_id});
|
||||
os << args[0] << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
auto converted_freq = StringTo<defs::Hz>(args[0], args[1]);
|
||||
det->setDBITClock(converted_freq, std::vector<int>{det_id});
|
||||
os << args[0] << args[1] << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7312,7 +7362,7 @@ std::string Caller::patfname(int action) {
|
||||
// generate code for each action
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (args.size() == 0) {
|
||||
auto t = det->getPatterFileName(std::vector<int>{det_id});
|
||||
auto t = det->getPatternFileName(std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
}
|
||||
}
|
||||
@@ -9909,34 +9959,46 @@ std::string Caller::runclk(int action) {
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([n_clk in MHz]
|
||||
[Ctb] Run clock in MHz.
|
||||
[xilinx Ctb] Run clock in kHz. )V0G0N"
|
||||
os << R"V0G0N([n_clk] [(optional unit) Hz(default)|kHz|MHz]
|
||||
[Ctb][Xilinx Ctb] Run clock frequency. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (1 && args.size() != 0) {
|
||||
if (1 && args.size() != 0 && args.size() != 1) {
|
||||
throw RuntimeError("Wrong number of arguments for action GET");
|
||||
}
|
||||
|
||||
if (args.size() == 0) {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (1 && args.size() != 1) {
|
||||
if (1 && args.size() != 1 && args.size() != 2) {
|
||||
throw RuntimeError("Wrong number of arguments for action PUT");
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
try {
|
||||
StringTo<int>(args[0]);
|
||||
std::string tmp_freq(args[0]);
|
||||
std::string unit = RemoveUnit(tmp_freq);
|
||||
auto converted_freq = StringTo<defs::Hz>(tmp_freq, unit);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to int");
|
||||
throw RuntimeError("Could not convert argument to defs::Hz");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<defs::Hz>(args[0], args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert arguments to defs::Hz");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9954,13 +10016,26 @@ std::string Caller::runclk(int action) {
|
||||
auto t = det->getRUNClock(std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
auto t = det->getRUNClock(std::vector<int>{det_id});
|
||||
os << OutString(t, args[0]) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (args.size() == 1) {
|
||||
auto arg0 = StringTo<int>(args[0]);
|
||||
det->setRUNClock(arg0, std::vector<int>{det_id});
|
||||
os << args.front() << '\n';
|
||||
std::string tmp_freq(args[0]);
|
||||
std::string unit = RemoveUnit(tmp_freq);
|
||||
auto converted_freq = StringTo<defs::Hz>(tmp_freq, unit);
|
||||
det->setRUNClock(converted_freq, std::vector<int>{det_id});
|
||||
os << args[0] << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
auto converted_freq = StringTo<defs::Hz>(args[0], args[1]);
|
||||
det->setRUNClock(converted_freq, std::vector<int>{det_id});
|
||||
os << args[0] << args[1] << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13062,21 +13137,24 @@ std::string Caller::syncclk(int action) {
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([n_clk in MHz]
|
||||
[Ctb] Sync clock in MHz. )V0G0N"
|
||||
os << R"V0G0N([n_clk] [(optional unit) Hz(default)|kHz|MHz]
|
||||
[Ctb] Sync clock. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (1 && args.size() != 0) {
|
||||
if (1 && args.size() != 0 && args.size() != 1) {
|
||||
throw RuntimeError("Wrong number of arguments for action GET");
|
||||
}
|
||||
|
||||
if (args.size() == 0) {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
@@ -13091,6 +13169,11 @@ std::string Caller::syncclk(int action) {
|
||||
auto t = det->getSYNCClock(std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
auto t = det->getSYNCClock(std::vector<int>{det_id});
|
||||
os << OutString(t, args[0]) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return os.str();
|
||||
|
||||
@@ -54,6 +54,9 @@ class Caller {
|
||||
return ToString(value, unit);
|
||||
}
|
||||
|
||||
std::string OutString(const Result<defs::Hz> &value,
|
||||
const std::string &unit);
|
||||
|
||||
std::vector<std::string> getAllCommands();
|
||||
std::map<std::string, std::string> GetDeprecatedCommands();
|
||||
std::string list(int action);
|
||||
@@ -421,6 +424,7 @@ class Caller {
|
||||
defs::dacIndex parseDacIndex(int argIndex, bool isCtb);
|
||||
bool parseMV(int argIndex);
|
||||
defs::powerIndex parsePowerIndex(int argIndex);
|
||||
defs::FrequencyUnit parseFrequencyUnit(const std::string &s);
|
||||
|
||||
FunctionMap functions{
|
||||
{"list", &Caller::list},
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
namespace sls {
|
||||
// some helper functions to print
|
||||
|
||||
std::string Caller::OutString(const Result<defs::Hz> &value,
|
||||
const std::string &unit) {
|
||||
auto u = parseFrequencyUnit(unit);
|
||||
if (value.equal())
|
||||
return ToString(value.front(), u);
|
||||
return ToString(value, u);
|
||||
}
|
||||
|
||||
std::vector<std::string> Caller::getAllCommands() {
|
||||
std::vector<std::string> ret;
|
||||
for (auto it : functions)
|
||||
@@ -2105,4 +2113,21 @@ std::string Caller::powervalues(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
defs::FrequencyUnit Caller::parseFrequencyUnit(const std::string &unit) {
|
||||
auto unitLower = [&] {
|
||||
std::string result = unit;
|
||||
std::transform(result.begin(), result.end(), result.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
return result;
|
||||
}();
|
||||
if (unitLower == "hz")
|
||||
return defs::FrequencyUnit::Hz;
|
||||
if (unitLower == "khz")
|
||||
return defs::FrequencyUnit::kHz;
|
||||
if (unitLower == "mhz")
|
||||
return defs::FrequencyUnit::MHz;
|
||||
|
||||
throw std::runtime_error("Unknown frequency unit: " + unit);
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -2144,25 +2144,34 @@ void Detector::setNumberOfAnalogSamples(int value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setNumberOfAnalogSamples, pos, value);
|
||||
}
|
||||
|
||||
Result<int> Detector::getADCClock(Positions pos) const {
|
||||
Result<defs::Hz> Detector::getADCClock(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getClockFrequency, pos, defs::ADC_CLOCK);
|
||||
}
|
||||
|
||||
void Detector::setADCClock(int value_in_MHz, Positions pos) {
|
||||
void Detector::setADCClock(defs::Hz val, Positions pos) {
|
||||
pimpl->Parallel(&Module::setClockFrequency, pos, defs::ADC_CLOCK,
|
||||
value_in_MHz);
|
||||
val.value);
|
||||
}
|
||||
|
||||
Result<int> Detector::getRUNClock(Positions pos) const {
|
||||
Result<defs::Hz> Detector::getRUNClock(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getClockFrequency, pos, defs::RUN_CLOCK);
|
||||
}
|
||||
|
||||
void Detector::setRUNClock(int value_in_MHz, Positions pos) {
|
||||
void Detector::setRUNClock(defs::Hz val, Positions pos) {
|
||||
pimpl->Parallel(&Module::setClockFrequency, pos, defs::RUN_CLOCK,
|
||||
value_in_MHz);
|
||||
val.value);
|
||||
}
|
||||
|
||||
Result<int> Detector::getSYNCClock(Positions pos) const {
|
||||
Result<defs::Hz> Detector::getDBITClock(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getClockFrequency, pos, defs::DBIT_CLOCK);
|
||||
}
|
||||
|
||||
void Detector::setDBITClock(defs::Hz val, Positions pos) {
|
||||
pimpl->Parallel(&Module::setClockFrequency, pos, defs::DBIT_CLOCK,
|
||||
val.value);
|
||||
}
|
||||
|
||||
Result<defs::Hz> Detector::getSYNCClock(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getClockFrequency, pos, defs::SYNC_CLOCK);
|
||||
}
|
||||
|
||||
@@ -2310,15 +2319,6 @@ void Detector::setReadoutMode(defs::readoutMode value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setReadoutMode, pos, value);
|
||||
}
|
||||
|
||||
Result<int> Detector::getDBITClock(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getClockFrequency, pos, defs::DBIT_CLOCK);
|
||||
}
|
||||
|
||||
void Detector::setDBITClock(int value_in_MHz, Positions pos) {
|
||||
pimpl->Parallel(&Module::setClockFrequency, pos, defs::DBIT_CLOCK,
|
||||
value_in_MHz);
|
||||
}
|
||||
|
||||
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");
|
||||
@@ -2609,8 +2609,8 @@ void Detector::configureTransceiver(Positions pos) {
|
||||
|
||||
// Pattern
|
||||
|
||||
Result<std::string> Detector::getPatterFileName(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getPatterFileName, pos);
|
||||
Result<std::string> Detector::getPatternFileName(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getPatternFileName, pos);
|
||||
}
|
||||
|
||||
void Detector::setPattern(const std::string &fname, Positions pos) {
|
||||
|
||||
@@ -2668,7 +2668,7 @@ void Module::configureTransceiver() {
|
||||
}
|
||||
|
||||
// Pattern
|
||||
std::string Module::getPatterFileName() const {
|
||||
std::string Module::getPatternFileName() const {
|
||||
char retval[MAX_STR_LENGTH]{};
|
||||
sendToDetector(F_GET_PATTERN_FILE_NAME, nullptr, retval);
|
||||
return retval;
|
||||
|
||||
@@ -536,7 +536,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
* Pattern *
|
||||
* *
|
||||
* ************************************************/
|
||||
std::string getPatterFileName() const;
|
||||
std::string getPatternFileName() const;
|
||||
void setPattern(const Pattern &pat, const std::string &fname);
|
||||
Pattern getPattern();
|
||||
void loadDefaultPattern();
|
||||
|
||||
@@ -63,6 +63,12 @@ int InferAction::adcclk() {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
throw RuntimeError(
|
||||
"sls_detector is disabled for command: adcclk with number of "
|
||||
"arguments 1. Use sls_detector_get or sls_detector_put");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
@@ -711,6 +717,12 @@ int InferAction::dbitclk() {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
throw RuntimeError(
|
||||
"sls_detector is disabled for command: dbitclk with number of "
|
||||
"arguments 1. Use sls_detector_get or sls_detector_put");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
@@ -2595,6 +2607,12 @@ int InferAction::runclk() {
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
throw RuntimeError(
|
||||
"sls_detector is disabled for command: runclk with number of "
|
||||
"arguments 1. Use sls_detector_get or sls_detector_put");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
@@ -3477,6 +3495,10 @@ int InferAction::syncclk() {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError("Could not infer action: Wrong number of arguments");
|
||||
|
||||
@@ -921,23 +921,65 @@ TEST_CASE("adcclk", "[.detectorintegration]") {
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD) {
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
auto prev_val = det.getADCClock();
|
||||
|
||||
REQUIRE_NOTHROW(caller.call("adcclk", {"MHZ"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("adcclk", {"mhz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("adcclk", {"MHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("adcclk", {"kHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("adcclk", {"Hz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("adcclk", {}, -1, GET));
|
||||
// min
|
||||
if (det_type == defs::CHIPTESTBOARD)
|
||||
REQUIRE_THROWS(caller.call("adcclk", {"1", "MHz"}, -1, PUT));
|
||||
else
|
||||
REQUIRE_THROWS(caller.call("adcclk", {"9", "MHz"}, -1, PUT));
|
||||
// max
|
||||
if (det_type == defs::CHIPTESTBOARD)
|
||||
REQUIRE_THROWS(caller.call("adcclk", {"66", "MHz"}, -1, PUT));
|
||||
else
|
||||
REQUIRE_THROWS(caller.call("adcclk", {"301", "MHz"}, -1, PUT));
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {"20"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "adcclk 20\n");
|
||||
caller.call("adcclk", {"20MHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "adcclk 20MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {"10"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "adcclk 10\n");
|
||||
caller.call("adcclk", {"10000000"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "adcclk 10000000\n");
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "adcclk 10MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {"15000", "kHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "adcclk 15000kHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "adcclk 10\n");
|
||||
REQUIRE(oss.str() == "adcclk 15MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {"15.75", "MHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "adcclk 15.75MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("adcclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "adcclk 15.75MHz\n");
|
||||
}
|
||||
std::cout << "Resetting adc clock to :" << ToString(prev_val)
|
||||
<< std::endl;
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setADCClock(prev_val[i], {i});
|
||||
}
|
||||
@@ -952,25 +994,119 @@ TEST_CASE("runclk", "[.detectorintegration]") {
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD) {
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
auto prev_val = det.getRUNClock();
|
||||
|
||||
REQUIRE_NOTHROW(caller.call("runclk", {"MHZ"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("runclk", {"mhz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("runclk", {"MHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("runclk", {"kHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("runclk", {"Hz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("runclk", {}, -1, GET));
|
||||
// min
|
||||
if (det_type == defs::CHIPTESTBOARD)
|
||||
REQUIRE_THROWS(caller.call("runclk", {"1", "MHz"}, -1, PUT));
|
||||
else
|
||||
REQUIRE_THROWS(caller.call("runclk", {"9", "MHz"}, -1, PUT));
|
||||
// max
|
||||
REQUIRE_THROWS(caller.call("runclk", {"301", "MHz"}, -1, PUT));
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {"20"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "runclk 20\n");
|
||||
caller.call("runclk", {"20MHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "runclk 20MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {"10"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "runclk 10\n");
|
||||
caller.call("runclk", {"10000000"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "runclk 10000000\n");
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "runclk 10MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {"15000", "kHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "runclk 15000kHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "runclk 10\n");
|
||||
REQUIRE(oss.str() == "runclk 15MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {"15.75", "MHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "runclk 15.75MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("runclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "runclk 15.75MHz\n");
|
||||
}
|
||||
// tolerance
|
||||
auto prev_exptime = det.getExptime();
|
||||
auto prev_period = det.getPeriod();
|
||||
auto prev_delay = det.getDelayAfterTrigger();
|
||||
{
|
||||
caller.call("runclk", {"80", "MHz"}, -1, PUT);
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("exptime", {"10012", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("exptime", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "exptime 10013ns\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("exptime", {"10013", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("exptime", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "exptime 10013ns\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("exptime", {"10019", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("exptime", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "exptime 10025ns\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("period", {"10125", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("period", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "period 10125ns\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("period", {"10124", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("period", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "period 10125ns\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(caller.call("delay", {"10125", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("delay", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "delay 10125ns\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(caller.call("delay", {"10124", "ns"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("delay", {"ns"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "delay 10125ns\n");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRUNClock(prev_val[i], {i});
|
||||
det.setExptime(prev_exptime[i], {i});
|
||||
det.setPeriod(prev_period[i], {i});
|
||||
det.setDelayAfterTrigger(prev_delay[i], {i});
|
||||
}
|
||||
} else {
|
||||
// clock index might work
|
||||
@@ -983,6 +1119,11 @@ TEST_CASE("syncclk", "[.detectorintegration]") {
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::CHIPTESTBOARD) {
|
||||
REQUIRE_NOTHROW(caller.call("syncclk", {"MHZ"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("syncclk", {"mhz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("syncclk", {"MHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("syncclk", {"kHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("syncclk", {"Hz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("syncclk", {}, -1, GET));
|
||||
} else {
|
||||
// clock index might work
|
||||
@@ -1249,22 +1390,59 @@ TEST_CASE("dbitclk", "[.detectorintegration]") {
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD) {
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
auto prev_val = det.getDBITClock();
|
||||
|
||||
REQUIRE_NOTHROW(caller.call("dbitclk", {"MHZ"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("dbitclk", {"mhz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("dbitclk", {"MHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("dbitclk", {"kHz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("dbitclk", {"Hz"}, -1, GET));
|
||||
REQUIRE_NOTHROW(caller.call("dbitclk", {}, -1, GET));
|
||||
// min
|
||||
if (det_type == defs::CHIPTESTBOARD)
|
||||
REQUIRE_THROWS(caller.call("dbitclk", {"1", "MHz"}, -1, PUT));
|
||||
else
|
||||
REQUIRE_THROWS(caller.call("dbitclk", {"9", "MHz"}, -1, PUT));
|
||||
// max
|
||||
REQUIRE_THROWS(caller.call("dbitclk", {"301", "MHz"}, -1, PUT));
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {"20"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 20\n");
|
||||
caller.call("dbitclk", {"20MHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 20MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {"10"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 10\n");
|
||||
caller.call("dbitclk", {"10000000"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 10000000\n");
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 10MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {"15000", "kHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 15000kHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 10\n");
|
||||
REQUIRE(oss.str() == "dbitclk 15MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {"15.75", "MHz"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 15.75MHz\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("dbitclk", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "dbitclk 15.75MHz\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setDBITClock(prev_val[i], {i});
|
||||
|
||||
@@ -108,6 +108,12 @@ ToString(From t) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert frequency with specified output unit */
|
||||
std::string ToString(defs::Hz f, defs::FrequencyUnit unit);
|
||||
|
||||
/** Convert frequency automatically selecting the unit */
|
||||
std::string ToString(defs::Hz f);
|
||||
|
||||
/** Conversion of floating point values, removes trailing zeros*/
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_floating_point<T>::value, std::string>::type
|
||||
@@ -279,7 +285,23 @@ ToString(const T &container, const std::string &unit) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
/** Container and specified unit, call ToString(value, FrequencyUnit) */
|
||||
template <typename T>
|
||||
typename std::enable_if<is_container<T>::value, std::string>::type
|
||||
ToString(const T &container, defs::FrequencyUnit unit) {
|
||||
std::ostringstream os;
|
||||
os << '[';
|
||||
if (!container.empty()) {
|
||||
auto it = container.cbegin();
|
||||
os << ToString(*it++, unit);
|
||||
while (it != container.cend())
|
||||
os << ", " << ToString(*it++, unit);
|
||||
}
|
||||
os << ']';
|
||||
return os.str();
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<sls::is_duration<T>::value, int> = 0>
|
||||
T StringTo(const std::string &t, const std::string &unit) {
|
||||
double tval{0};
|
||||
try {
|
||||
@@ -304,6 +326,33 @@ T StringTo(const std::string &t, const std::string &unit) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<sls::is_frequency<T>::value, int> = 0>
|
||||
T StringTo(const std::string &f, const std::string &unit) {
|
||||
double fval{0};
|
||||
try {
|
||||
fval = std::stod(f);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
throw RuntimeError("Could not convert string to frequency");
|
||||
}
|
||||
auto unitLower = [&] {
|
||||
std::string result = unit;
|
||||
std::transform(result.begin(), result.end(), result.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
return result;
|
||||
}();
|
||||
|
||||
if (unitLower == "mhz") {
|
||||
return T(static_cast<int>(fval * 1e6));
|
||||
} else if (unitLower == "khz") {
|
||||
return T(static_cast<int>(fval * 1e3));
|
||||
} else if (unitLower.empty() || unitLower == "hz") {
|
||||
return T(static_cast<int>(fval));
|
||||
} else {
|
||||
throw RuntimeError(
|
||||
"Invalid unit in conversion from string to frequency");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> T StringTo(const std::string &t) {
|
||||
std::string tmp{t};
|
||||
auto unit = RemoveUnit(tmp);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -120,4 +122,9 @@ struct has_bool_isValid : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_bool_isValid<T, std::void_t<decltype(std::declval<T>().isValid)>>
|
||||
: std::is_same<decltype(std::declval<T>().isValid), bool> {};
|
||||
|
||||
template <typename T> struct is_frequency : std::false_type {};
|
||||
|
||||
template <> struct is_frequency<defs::Hz> : std::true_type {};
|
||||
|
||||
} // namespace sls
|
||||
@@ -221,6 +221,16 @@ class slsDetectorDefs {
|
||||
std::map<std::string, std::string> addJsonHeader;
|
||||
};
|
||||
|
||||
struct Hz {
|
||||
int value{0};
|
||||
explicit Hz(int v) : value(v){};
|
||||
constexpr bool operator==(const Hz &other) const {
|
||||
return (value == other.value);
|
||||
}
|
||||
};
|
||||
|
||||
enum class FrequencyUnit { Hz, kHz, MHz };
|
||||
|
||||
#endif
|
||||
enum frameDiscardPolicy {
|
||||
NO_DISCARD,
|
||||
@@ -854,7 +864,6 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// TODO! discuss this
|
||||
#include <vector> //hmm... but currently no way around
|
||||
namespace sls {
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
/** API versions */
|
||||
#define APILIB "0.0.0 0x250909"
|
||||
#define APIRECEIVER "0.0.0 0x250822"
|
||||
#define APICTB "0.0.0 0x260427"
|
||||
#define APICTB "0.0.0 0x260506"
|
||||
#define APIGOTTHARD2 "0.0.0 0x260427"
|
||||
#define APIMOENCH "0.0.0 0x260424"
|
||||
#define APIEIGER "0.0.0 0x260424"
|
||||
#define APIXILINXCTB "0.0.0 0x260427"
|
||||
#define APIXILINXCTB "0.0.0 0x260506"
|
||||
#define APIJUNGFRAU "0.0.0 0x260424"
|
||||
#define APIMYTHEN3 "0.0.0 0x260427"
|
||||
#define APIMATTERHORN "0.0.0 0x260212"
|
||||
#define APIMYTHEN3 "0.0.0 0x260506"
|
||||
#define APIMATTERHORN "0.0.0 0x260212"
|
||||
|
||||
@@ -741,6 +741,36 @@ std::string ToString(const defs::collectionMode s) {
|
||||
|
||||
const std::string &ToString(const std::string &s) { return s; }
|
||||
|
||||
std::string ToString(defs::Hz f, defs::FrequencyUnit unit) {
|
||||
double val = static_cast<double>(f.value);
|
||||
std::ostringstream os;
|
||||
switch (unit) {
|
||||
case defs::FrequencyUnit::Hz:
|
||||
os << val << "Hz";
|
||||
break;
|
||||
case defs::FrequencyUnit::kHz:
|
||||
os << val / (static_cast<double>(1e3)) << "kHz";
|
||||
break;
|
||||
case defs::FrequencyUnit::MHz:
|
||||
os << val / (static_cast<double>(1e6)) << "MHz";
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown frequency unit");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string ToString(defs::Hz f) {
|
||||
int val = f.value;
|
||||
if (val < 1e3) {
|
||||
return ToString(f, defs::FrequencyUnit::Hz);
|
||||
} else if (val < 1e6) {
|
||||
return ToString(f, defs::FrequencyUnit::kHz);
|
||||
} else {
|
||||
return ToString(f, defs::FrequencyUnit::MHz);
|
||||
}
|
||||
}
|
||||
|
||||
template <> defs::detectorType StringTo(const std::string &s) {
|
||||
if (s == "Eiger")
|
||||
return defs::EIGER;
|
||||
|
||||
@@ -76,6 +76,15 @@ TEST_CASE("conversion from duration to string", "[support]") {
|
||||
REQUIRE(ToString(us(-100)) == "-100us");
|
||||
}
|
||||
|
||||
TEST_CASE("conversion from frequency to string", "[support]") {
|
||||
REQUIRE(ToString(defs::Hz(150)) == "150Hz");
|
||||
REQUIRE(ToString(defs::Hz(1500)) == "1.5kHz");
|
||||
REQUIRE(ToString(defs::Hz(1500000)) == "1.5MHz");
|
||||
REQUIRE(ToString(defs::Hz(150), defs::FrequencyUnit::Hz) == "150Hz");
|
||||
REQUIRE(ToString(defs::Hz(150), defs::FrequencyUnit::kHz) == "0.15kHz");
|
||||
REQUIRE(ToString(defs::Hz(150), defs::FrequencyUnit::MHz) == "0.00015MHz");
|
||||
}
|
||||
|
||||
TEST_CASE("Convert vector of time", "[support]") {
|
||||
std::vector<ns> vec{ns(150), us(10), ns(600)};
|
||||
REQUIRE(ToString(vec) == "[150ns, 10us, 600ns]");
|
||||
@@ -155,6 +164,15 @@ TEST_CASE("string to std::chrono::duration", "[support]") {
|
||||
REQUIRE_THROWS(StringTo<ns>("asvn"));
|
||||
}
|
||||
|
||||
TEST_CASE("string to frequency", "[support]") {
|
||||
REQUIRE(StringTo<defs::Hz>("150") == defs::Hz(150));
|
||||
REQUIRE(StringTo<defs::Hz>("150Hz") == defs::Hz(150));
|
||||
REQUIRE(StringTo<defs::Hz>("1.5kHz") == defs::Hz(1500));
|
||||
REQUIRE(StringTo<defs::Hz>("1.5MHz") == defs::Hz(1500000));
|
||||
REQUIRE_THROWS(StringTo<defs::Hz>("5xs"));
|
||||
REQUIRE_THROWS(StringTo<defs::Hz>("asvn"));
|
||||
}
|
||||
|
||||
TEST_CASE("string to detectorType") {
|
||||
using dt = slsDetectorDefs::detectorType;
|
||||
REQUIRE(StringTo<dt>("Eiger") == dt::EIGER);
|
||||
|
||||
Reference in New Issue
Block a user