mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-12-16 01:21:20 +01:00
Compare commits
84 Commits
rosenblatt
...
dev/define
| Author | SHA1 | Date | |
|---|---|---|---|
| 41a73e0c73 | |||
| caa3b3087c | |||
| ea9508da9f | |||
| ea561e2422 | |||
| 5f287ea092 | |||
| 199f5f113f | |||
| 224f202e05 | |||
| ad642c07a4 | |||
| 5ae1021de9 | |||
| e3c1191088 | |||
| 497c890b28 | |||
|
|
c34eec033a | ||
|
|
5295e148da | ||
|
|
f150eed74b | ||
| 654c16b52b | |||
| ee3222e56b | |||
| a503881353 | |||
| 497b3ed00e | |||
| 300a296c20 | |||
| ecf1ec553d | |||
| 0ca667bd52 | |||
| 01e392b112 | |||
| 5409cec73e | |||
|
|
1c31a85a43 | ||
| 134137ead0 | |||
| 6d3922f487 | |||
| f14cfb0b31 | |||
| cf4e6b65c1 | |||
| 0da80cd898 | |||
| 8e7921ae45 | |||
| b90851a855 | |||
| 683accd914 | |||
| 30e82e4740 | |||
| 08486b9812 | |||
| a5c661ce22 | |||
| 50448cefb4 | |||
| c1e5cfa101 | |||
| ae8c9175bf | |||
| e7f5a2aa11 | |||
| cad44943c3 | |||
| d4f8049623 | |||
| 925cd55b1c | |||
| ec11ba5a54 | |||
| eea4dca449 | |||
| 3285221e8a | |||
|
|
56de3c17ea | ||
|
|
f32fcf1e88 | ||
| 3ff199822d | |||
| 0ba9a269a1 | |||
| afc51c9771 | |||
| 1ad2628311 | |||
| 1cf9dc21ab | |||
| f4c1395319 | |||
| 3b92ffb902 | |||
|
|
0490c0ef23 | ||
| f0bd9dd0b3 | |||
| 161cd5508d | |||
| af2c6eca0c | |||
|
|
d3dc92b18b | ||
|
|
e243af045d | ||
| b4a0c69897 | |||
| c80dc9bdf3 | |||
| 98c72efd31 | |||
| a4d5e38130 | |||
| 6551d22c7e | |||
| 049aeaf52a | |||
| 55aa5db630 | |||
| d6f8ff09d0 | |||
| 98ecbe954d | |||
| 4fb66865fd | |||
| 137365642d | |||
| 5d4a0055e1 | |||
| 3fdef9dac6 | |||
| a382705e50 | |||
| c43a3207e8 | |||
| d32c034fcf | |||
| b55bc8d89e | |||
| c2141cf60f | |||
| 7e13ccf632 | |||
| 2c2d046ce0 | |||
| 08b282a330 | |||
| 8178a5c16e | |||
| 89be26dfe0 | |||
| 96804ab7cd |
33
.gitea/workflows/rh8-local.yml
Normal file
33
.gitea/workflows/rh8-local.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Build on local RHEL8
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- developer
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "detectors-software-RH8"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build library
|
||||
run: |
|
||||
source /home/gitea_runner/.bashrc
|
||||
conda activate det
|
||||
mkdir build && cd build
|
||||
conda activate det
|
||||
cmake .. -DSLS_USE_PYTHON=ON
|
||||
make -j 2
|
||||
cd ../pyctbgui
|
||||
make
|
||||
|
||||
- name: Deploy to NFS update server
|
||||
if: gitea.ref == 'refs/heads/developer'
|
||||
run: |
|
||||
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH8 <<< $'put build/bin'
|
||||
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH8 <<< $'put pyctbgui'
|
||||
@@ -21,9 +21,9 @@ jobs:
|
||||
- name: Build library
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON
|
||||
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON -DSLS_USE_SIMULATOR=ON
|
||||
make -j 2
|
||||
|
||||
- name: C++ unit tests
|
||||
working-directory: ${{gitea.workspace}}/build
|
||||
run: ctest
|
||||
run: ctest -j1 --rerun-failed --output-on-failure
|
||||
30
.gitea/workflows/rh9-local.yml
Normal file
30
.gitea/workflows/rh9-local.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Build on local RHEL9
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- developer
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "detectors-software-RH9"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build library
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DSLS_USE_PYTHON=ON -DPython_EXECUTABLE=/usr/bin/python3.13 -DPython_INCLUDE_DIR=/usr/include/python3.13 -DPython_LIBRARY=/usr/lib64/libpython3.13.so ..
|
||||
make -j 2
|
||||
cd ../pyctbgui
|
||||
make
|
||||
|
||||
- name: Deploy to NFS update server
|
||||
if: gitea.ref == 'refs/heads/developer'
|
||||
run: |
|
||||
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH9 <<< $'put build/bin'
|
||||
sftp -r gitea_runner@mpc2935:/slsDetectorSoftware/RH9 <<< $'put pyctbgui'
|
||||
@@ -19,9 +19,9 @@ jobs:
|
||||
- name: Build library
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON
|
||||
cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON -DSLS_USE_SIMULATOR=ON
|
||||
make -j 2
|
||||
|
||||
- name: C++ unit tests
|
||||
working-directory: ${{gitea.workspace}}/build
|
||||
run: ctest
|
||||
run: ctest -j1 --rerun-failed --output-on-failure
|
||||
2
.github/workflows/build_wheel.yml
vendored
2
.github/workflows/build_wheel.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
run: pipx run cibuildwheel==2.23.0
|
||||
run: pipx run cibuildwheel==3.2.1
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
4
.github/workflows/cmake.yaml
vendored
4
.github/workflows/cmake.yaml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: 'pip'
|
||||
- run: pip install pytest numpy
|
||||
- run: pip install pytest numpy colorama
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
|
||||
- name: C++ unit tests
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: ctest -C ${{env.BUILD_TYPE}} -j1
|
||||
run: ctest -C ${{env.BUILD_TYPE}} -j1 --rerun-failed --output-on-failure
|
||||
|
||||
- name: Python unit tests
|
||||
working-directory: ${{github.workspace}}/build/bin
|
||||
|
||||
@@ -24,6 +24,15 @@ include(cmake/SlsAddFlag.cmake)
|
||||
include(cmake/helpers.cmake)
|
||||
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# POSIX threads are required for the moment but we use CMake to find them
|
||||
# Once migrated to std::thread this can be removed
|
||||
if(NOT CMAKE_USE_PTHREADS_INIT)
|
||||
message(FATAL_ERROR "A POSIX threads (pthread) implementation is required, but was not found.")
|
||||
endif()
|
||||
|
||||
|
||||
option(SLS_USE_SYSTEM_ZMQ "Use system installed libzmq" OFF)
|
||||
|
||||
# Using FetchContent to get libzmq
|
||||
@@ -332,6 +341,9 @@ if (NOT TARGET slsProjectCSettings)
|
||||
-Wno-format-truncation
|
||||
)
|
||||
sls_disable_c_warning("-Wstringop-truncation")
|
||||
target_link_libraries(slsProjectCSettings INTERFACE
|
||||
Threads::Threads
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SLS Detector Package Major Release x.x.x released on xx.xx.202x
|
||||
===============================================================
|
||||
|
||||
This document describes the differences between vx.x.x and vx.0.2
|
||||
This document describes the differences between vx.x.x and v10.0.0
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ instead of the one included in our repo.
|
||||
|
||||
Experimental support for building the detector client (including python bindings) on macOS
|
||||
|
||||
``rx_dbitlist`` keeps the order of the passed bit list
|
||||
|
||||
2 On-board Detector Server Compatibility
|
||||
==========================================
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ cmake .. -G Ninja \
|
||||
-DSLS_USE_PYTHON=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DSLS_USE_HDF5=OFF \
|
||||
-DSLS_USE_SYSTEM_ZMQ=ON \
|
||||
|
||||
NCORES=$(getconf _NPROCESSORS_ONLN)
|
||||
echo "Building using: ${NCORES} cores"
|
||||
|
||||
@@ -29,6 +29,7 @@ requirements:
|
||||
- libtiff
|
||||
- zlib
|
||||
- expat
|
||||
- zeromq
|
||||
|
||||
run:
|
||||
- libstdcxx-ng
|
||||
|
||||
@@ -2,6 +2,8 @@ python:
|
||||
- 3.11
|
||||
- 3.12
|
||||
- 3.13
|
||||
- 3.14
|
||||
|
||||
|
||||
c_compiler:
|
||||
- gcc # [linux]
|
||||
@@ -13,4 +15,4 @@ cxx_compiler:
|
||||
- gxx # [linux]
|
||||
|
||||
c_stdlib_version: # [linux]
|
||||
- 2.17 # [linux]
|
||||
- 2.17 # [linux]
|
||||
|
||||
@@ -9,11 +9,11 @@ package:
|
||||
build:
|
||||
number: 0
|
||||
script:
|
||||
- unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win]
|
||||
- unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv --config-settings=cmake.define.SLS_USE_SYSTEM_ZMQ=ON # [not win]
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python {{python}}
|
||||
- python
|
||||
- {{ compiler('c') }}
|
||||
- {{ stdlib("c") }}
|
||||
- {{ compiler('cxx') }}
|
||||
@@ -21,7 +21,7 @@ requirements:
|
||||
host:
|
||||
- cmake
|
||||
- ninja
|
||||
- python {{python}}
|
||||
- python
|
||||
- pip
|
||||
- scikit-build-core
|
||||
- pybind11 >=2.13.0
|
||||
@@ -31,7 +31,7 @@ requirements:
|
||||
- catch2
|
||||
|
||||
run:
|
||||
- python {{python}}
|
||||
- python
|
||||
- numpy
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ add_executable(gendoc src/gendoc.cpp)
|
||||
# This is a bit hacky, but better than exposing stuff?
|
||||
target_include_directories(gendoc PRIVATE ${PROJECT_SOURCE_DIR}/slsDetectorSoftware/src)
|
||||
target_link_libraries(gendoc PRIVATE
|
||||
slsDetectorShared
|
||||
slsDetectorStatic
|
||||
|
||||
)
|
||||
set_target_properties(gendoc PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
|
||||
@@ -50,6 +50,12 @@ datetime.timedelta, DurationWrapper or by setting the time in seconds.
|
||||
>>> d.getExptime()
|
||||
[sls::DurationWrapper(total_seconds: 181.23 count: 181230000000)]
|
||||
|
||||
# In C++ it is possible to use chrono literals to set time more easily
|
||||
# d.setExptime(7ms). However, this is not possible due to pythons syntax.
|
||||
# instead we can create a unit that we use for conversion.
|
||||
>>> ms = dt.timedelta(milliseconds = 1)
|
||||
>>> d.exptime = 7.5*ms
|
||||
|
||||
|
||||
|
||||
------------------------------------
|
||||
|
||||
@@ -17,7 +17,7 @@ dependencies = [
|
||||
|
||||
[tool.cibuildwheel]
|
||||
before-all = "uname -a"
|
||||
build = "cp{311,312,313}-manylinux_x86_64"
|
||||
build = "cp{311,312,313,314}-manylinux_x86_64"
|
||||
|
||||
[tool.scikit-build.build]
|
||||
verbose = true
|
||||
|
||||
@@ -12,6 +12,7 @@ pybind11_add_module(_slsdet
|
||||
src/duration.cpp
|
||||
src/DurationWrapper.cpp
|
||||
src/pedestal.cpp
|
||||
src/bit.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(_slsdet PUBLIC
|
||||
|
||||
@@ -27,6 +27,9 @@ from .defines import *
|
||||
|
||||
IpAddr = _slsdet.IpAddr
|
||||
MacAddr = _slsdet.MacAddr
|
||||
RegisterAddress = _slsdet.RegisterAddress
|
||||
BitAddress = _slsdet.BitAddress
|
||||
RegisterValue = _slsdet.RegisterValue
|
||||
scanParameters = _slsdet.scanParameters
|
||||
currentSrcParameters = _slsdet.currentSrcParameters
|
||||
DurationWrapper = _slsdet.DurationWrapper
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from ._slsdet import CppDetectorApi
|
||||
from ._slsdet import slsDetectorDefs
|
||||
from ._slsdet import IpAddr, MacAddr
|
||||
from ._slsdet import RegisterAddress, RegisterValue, BitAddress
|
||||
|
||||
runStatus = slsDetectorDefs.runStatus
|
||||
timingMode = slsDetectorDefs.timingMode
|
||||
@@ -24,6 +25,7 @@ import datetime as dt
|
||||
|
||||
from functools import wraps
|
||||
from collections import namedtuple
|
||||
from collections.abc import Sequence
|
||||
import socket
|
||||
import numpy as np
|
||||
|
||||
@@ -301,6 +303,46 @@ class Detector(CppDetectorApi):
|
||||
def rx_arping(self, value):
|
||||
ut.set_using_dict(self.setRxArping, value)
|
||||
|
||||
@property
|
||||
def rx_roi(self):
|
||||
"""Gets the list of ROIs configured in the receiver.
|
||||
|
||||
Note
|
||||
-----
|
||||
Each ROI is represented as a tuple of (x_start, y_start, x_end, y_end). \n
|
||||
If no ROIs are configured, returns [[-1,-1,-1,-1]].
|
||||
"""
|
||||
return self.getRxROI() #vector of Roi structs how represented?
|
||||
|
||||
@rx_roi.setter
|
||||
def rx_roi(self, rois):
|
||||
"""
|
||||
Sets the list of ROIs in the receiver.
|
||||
Can only set multiple ROIs at multi module level without gap pixels. If more than 1 ROI per
|
||||
UDP port, it will throw. Setting number of udp interfaces will clear the
|
||||
roi. Cannot be set for CTB or Xilinx CTB.
|
||||
|
||||
Note
|
||||
-----
|
||||
Each ROI should be represented as a sequence of 4 ints (x_start, y_start, x_end, y_end). \n
|
||||
For mythen3 or gotthard2 pass a sequence of 2 ints (x_start, x_end) \n
|
||||
For multiple ROI's pass a sequence of sequence \n
|
||||
Example: [[0, 100, 50, 100], [260, 270, 50,100]] \n
|
||||
"""
|
||||
# TODO: maybe better to accept py::object in setRxROI and handle there?
|
||||
if not isinstance(rois, Sequence):
|
||||
raise TypeError(
|
||||
"setRxROI failed: expected a tuple/list of ints x_min, x_max, y_min, y_max "
|
||||
"or a sequence of such."
|
||||
)
|
||||
if(not isinstance(rois[0], Sequence)):
|
||||
self.setRxROI([rois])
|
||||
else:
|
||||
self.setRxROI(rois)
|
||||
|
||||
def rx_clearroi(self):
|
||||
"""Clears all the ROIs configured in the receiver."""
|
||||
self.clearRxROI()
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -1772,6 +1814,109 @@ class Detector(CppDetectorApi):
|
||||
[Eiger] Address is +0x100 for only left, +0x200 for only right.
|
||||
"""
|
||||
return self._register
|
||||
|
||||
def define_reg(self, name, addr):
|
||||
"""
|
||||
[Ctb] Define a name for a register to be used later with reg.
|
||||
|
||||
Example
|
||||
--------
|
||||
|
||||
d.define_reg('myreg',addr=0x6)
|
||||
"""
|
||||
addr = RegisterAddress(addr)
|
||||
self.setRegisterDefinition(name, addr)
|
||||
|
||||
|
||||
def define_bit(self, name, addr, bit):
|
||||
"""
|
||||
[Ctb] Define a name for a bit in a register to be used later with setBit/clearBit/getBit
|
||||
|
||||
Example
|
||||
--------
|
||||
|
||||
d.define_bit('mybit',addr=0x6, bit=7)
|
||||
"""
|
||||
addr = RegisterAddress(addr)
|
||||
bit = BitAddress(addr, bit)
|
||||
self.setBitDefinition(name, bit)
|
||||
|
||||
def setBit(self, bit_or_addr, number=None):
|
||||
"""
|
||||
Set a bit in a register
|
||||
[Ctb] Can use a named bit address
|
||||
|
||||
Example
|
||||
--------
|
||||
d.setBit(0x5, 3)
|
||||
|
||||
#Ctb
|
||||
d.setBit('mybit')
|
||||
|
||||
myreg = RegisterAddress(0x5)
|
||||
mybit = BitAddress(myreg, 5)
|
||||
d.setBit(mybit)
|
||||
"""
|
||||
#Old usage passing two ints
|
||||
if isinstance(bit_or_addr, int):
|
||||
return super().setBit(bit_or_addr, number)
|
||||
|
||||
#New usage with str or BitAddress
|
||||
if isinstance(bit_or_addr, str):
|
||||
bit_or_addr = self.getBitDefinition(bit_or_addr)
|
||||
return super().setBit(bit_or_addr)
|
||||
|
||||
def clearBit(self, bit_or_addr, number=None):
|
||||
"""
|
||||
Clear a bit in a register
|
||||
[Ctb] Can use a named bit address
|
||||
|
||||
Example
|
||||
--------
|
||||
d.clearBit(0x5, 3)
|
||||
|
||||
#Ctb
|
||||
d.clearBit('mybit')
|
||||
|
||||
myreg = RegisterAddress(0x5)
|
||||
mybit = BitAddress(myreg, 5)
|
||||
d.clearBit(mybit)
|
||||
"""
|
||||
#Old usage passing two ints
|
||||
if isinstance(bit_or_addr, int):
|
||||
return super().clearBit(bit_or_addr, number)
|
||||
|
||||
#New usage with str or BitAddress
|
||||
if isinstance(bit_or_addr, str):
|
||||
bit_or_addr = self.getBitDefinition(bit_or_addr)
|
||||
return super().clearBit(bit_or_addr)
|
||||
|
||||
@element
|
||||
def getBit(self, bit_or_addr, number=None):
|
||||
"""
|
||||
Get a bit from a register
|
||||
[Ctb] Can use a named bit address
|
||||
|
||||
Example
|
||||
--------
|
||||
d.getBit(0x5, 3)
|
||||
|
||||
#Ctb
|
||||
d.getBit('mybit')
|
||||
|
||||
myreg = RegisterAddress(0x5)
|
||||
mybit = BitAddress(myreg, 5)
|
||||
d.getBit(mybit)
|
||||
"""
|
||||
#Old usage passing two ints
|
||||
if isinstance(bit_or_addr, int):
|
||||
return super().getBit(bit_or_addr, number)
|
||||
|
||||
#New usage with str or BitAddress
|
||||
if isinstance(bit_or_addr, str):
|
||||
bit_or_addr = self.getBitDefinition(bit_or_addr)
|
||||
return super().getBit(bit_or_addr)
|
||||
|
||||
|
||||
@property
|
||||
def slowadc(self):
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
from ._slsdet import RegisterValue, RegisterAddress
|
||||
from .utils import element
|
||||
|
||||
class Register:
|
||||
def __init__(self, detector):
|
||||
self._detector = detector
|
||||
|
||||
@element
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, str):
|
||||
key = self._detector.getRegisterDefinition(key)
|
||||
return self._detector.readRegister(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if isinstance(key, str):
|
||||
key = self._detector.getRegisterDefinition(key)
|
||||
elif isinstance(key, int):
|
||||
key = RegisterAddress(key)
|
||||
|
||||
if isinstance(value, int):
|
||||
value = RegisterValue(value)
|
||||
|
||||
self._detector.writeRegister(key, value, False)
|
||||
|
||||
class Adc_register:
|
||||
|
||||
@@ -141,21 +141,38 @@ def make_ip(arg):
|
||||
def make_mac(arg):
|
||||
return _make(arg, _slsdet.MacAddr)
|
||||
|
||||
def make_register_address(arg):
|
||||
return _make(arg, _slsdet.RegisterAddress)
|
||||
|
||||
def make_bit_address(arg):
|
||||
return _make(arg, _slsdet.BitAddress)
|
||||
|
||||
def make_register_value(arg):
|
||||
return _make(arg, _slsdet.RegisterValue)
|
||||
|
||||
def make_path(arg):
|
||||
return _make(arg, Path)
|
||||
|
||||
|
||||
def _make(arg, transform):
|
||||
"""Helper function for make_mac and make_ip special cases for
|
||||
"""Helper function for make_mac, make_ip and other special cases for
|
||||
dict, list and tuple. Otherwise just calls transform"""
|
||||
if isinstance(arg, dict):
|
||||
return {key: transform(value) for key, value in arg.items()}
|
||||
return {key: _make(value, transform) for key, value in arg.items()}
|
||||
elif isinstance(arg, list):
|
||||
return [transform(a) for a in arg]
|
||||
return [_make(a, transform) for a in arg]
|
||||
elif isinstance(arg, tuple):
|
||||
return tuple(transform(a) for a in arg)
|
||||
# special case for BitAddress
|
||||
if transform is _slsdet.BitAddress:
|
||||
addr, bit = arg
|
||||
if isinstance(addr, int):
|
||||
addr = _slsdet.RegisterAddress(addr)
|
||||
return transform(addr, bit)
|
||||
else:
|
||||
# general case: recursively transform each element
|
||||
return tuple(_make(a, transform) for a in arg)
|
||||
else:
|
||||
# single element
|
||||
return transform(arg)
|
||||
|
||||
|
||||
|
||||
60
python/src/bit.cpp
Normal file
60
python/src/bit.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
/*
|
||||
This file contains Python bindings for the RegisterAddr, BitAddress and
|
||||
RegisterValue classes.
|
||||
*/
|
||||
#include "py_headers.h"
|
||||
#include "sls/bit_utils.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
using sls::BitAddress;
|
||||
using sls::RegisterAddress;
|
||||
using sls::RegisterValue;
|
||||
|
||||
void init_bit(py::module &m) {
|
||||
|
||||
py::class_<RegisterAddress>(m, "RegisterAddress")
|
||||
.def(py::init())
|
||||
.def(py::init<const std::string &>())
|
||||
.def(py::init<uint32_t>())
|
||||
.def(py::init<const RegisterAddress &>())
|
||||
.def("__repr__", &RegisterAddress::str)
|
||||
.def("str", &RegisterAddress::str)
|
||||
.def("value", &RegisterAddress::value)
|
||||
.def(py::self == py::self)
|
||||
.def(py::self != py::self);
|
||||
|
||||
py::class_<BitAddress>(m, "BitAddress")
|
||||
.def(py::init())
|
||||
.def(py::init<RegisterAddress, uint32_t>())
|
||||
.def(py::init<std::string, std::string>())
|
||||
.def("__repr__", &BitAddress::str)
|
||||
.def("str", &BitAddress::str)
|
||||
.def("address", &BitAddress::address)
|
||||
.def("bitPosition", &BitAddress::bitPosition)
|
||||
.def(py::self == py::self)
|
||||
.def(py::self != py::self);
|
||||
|
||||
py::class_<RegisterValue>(m, "RegisterValue")
|
||||
.def(py::init<>())
|
||||
.def(py::init<const std::string &>())
|
||||
.def(py::init<uint32_t>())
|
||||
.def(py::init<const RegisterValue &>())
|
||||
.def("__repr__", &RegisterValue::str)
|
||||
.def("str", &RegisterValue::str)
|
||||
.def("value", &RegisterValue::value)
|
||||
.def(py::self == py::self)
|
||||
.def(py::self != py::self)
|
||||
.def("__or__", [](const RegisterValue &lhs, const RegisterValue &rhs) {
|
||||
return lhs | rhs;
|
||||
})
|
||||
.def("__or__", [](const RegisterValue& lhs, uint32_t rhs) {
|
||||
return lhs | rhs;
|
||||
})
|
||||
.def("__ior__", [](RegisterValue &lhs, uint32_t rhs) -> RegisterValue& {
|
||||
lhs |= rhs;
|
||||
return lhs;
|
||||
}, py::return_value_policy::reference_internal);
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "sls/Detector.h"
|
||||
#include "sls/TimeHelper.h"
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
@@ -15,10 +16,13 @@
|
||||
#include <chrono>
|
||||
namespace py = pybind11;
|
||||
void init_det(py::module &m) {
|
||||
using sls::BitAddress;
|
||||
using sls::defs;
|
||||
using sls::Detector;
|
||||
using sls::ns;
|
||||
using sls::Positions;
|
||||
using sls::RegisterAddress;
|
||||
using sls::RegisterValue;
|
||||
using sls::Result;
|
||||
|
||||
m.def("freeSharedMemory",
|
||||
@@ -1795,6 +1799,78 @@ void init_det(py::module &m) {
|
||||
(std::string(Detector::*)(const defs::dacIndex) const) &
|
||||
Detector::getSlowADCName,
|
||||
py::arg());
|
||||
CppDetectorApi.def("getRegisterDefinitionsCount",
|
||||
(int (Detector::*)() const) &
|
||||
Detector::getRegisterDefinitionsCount);
|
||||
CppDetectorApi.def(
|
||||
"setRegisterDefinition",
|
||||
(void (Detector::*)(const std::string &, sls::RegisterAddress)) &
|
||||
Detector::setRegisterDefinition,
|
||||
py::arg(), py::arg());
|
||||
CppDetectorApi.def("hasRegisterDefinition",
|
||||
(bool (Detector::*)(const std::string &) const) &
|
||||
Detector::hasRegisterDefinition,
|
||||
py::arg());
|
||||
CppDetectorApi.def("hasRegisterDefinition",
|
||||
(bool (Detector::*)(sls::RegisterAddress) const) &
|
||||
Detector::hasRegisterDefinition,
|
||||
py::arg());
|
||||
CppDetectorApi.def(
|
||||
"getRegisterDefinitionAddress",
|
||||
(sls::RegisterAddress(Detector::*)(const std::string &) const) &
|
||||
Detector::getRegisterDefinitionAddress,
|
||||
py::arg());
|
||||
CppDetectorApi.def("getRegisterDefinitionName",
|
||||
(std::string(Detector::*)(sls::RegisterAddress) const) &
|
||||
Detector::getRegisterDefinitionName,
|
||||
py::arg());
|
||||
CppDetectorApi.def("clearRegisterDefinitions",
|
||||
(void (Detector::*)()) &
|
||||
Detector::clearRegisterDefinitions);
|
||||
CppDetectorApi.def(
|
||||
"setRegisterDefinitions",
|
||||
(void (Detector::*)(const std::map<std::string, RegisterAddress> &)) &
|
||||
Detector::setRegisterDefinitions,
|
||||
py::arg());
|
||||
CppDetectorApi.def(
|
||||
"getRegisterDefinitions",
|
||||
(std::map<std::string, RegisterAddress>(Detector::*)() const) &
|
||||
Detector::getRegisterDefinitions);
|
||||
CppDetectorApi.def("getBitDefinitionsCount",
|
||||
(int (Detector::*)() const) &
|
||||
Detector::getBitDefinitionsCount);
|
||||
CppDetectorApi.def(
|
||||
"setBitDefinition",
|
||||
(void (Detector::*)(const std::string &, sls::BitAddress)) &
|
||||
Detector::setBitDefinition,
|
||||
py::arg(), py::arg());
|
||||
CppDetectorApi.def("hasBitDefinition",
|
||||
(bool (Detector::*)(const std::string &) const) &
|
||||
Detector::hasBitDefinition,
|
||||
py::arg());
|
||||
CppDetectorApi.def("hasBitDefinition",
|
||||
(bool (Detector::*)(sls::BitAddress) const) &
|
||||
Detector::hasBitDefinition,
|
||||
py::arg());
|
||||
CppDetectorApi.def(
|
||||
"getBitDefinitionAddress",
|
||||
(sls::BitAddress(Detector::*)(const std::string &) const) &
|
||||
Detector::getBitDefinitionAddress,
|
||||
py::arg());
|
||||
CppDetectorApi.def("getBitDefinitionName",
|
||||
(std::string(Detector::*)(sls::BitAddress) const) &
|
||||
Detector::getBitDefinitionName,
|
||||
py::arg());
|
||||
CppDetectorApi.def("clearBitDefinitions",
|
||||
(void (Detector::*)()) & Detector::clearBitDefinitions);
|
||||
CppDetectorApi.def(
|
||||
"setBitDefinitions",
|
||||
(void (Detector::*)(const std::map<std::string, BitAddress> &)) &
|
||||
Detector::setBitDefinitions,
|
||||
py::arg());
|
||||
CppDetectorApi.def("getBitDefinitions", (std::map<std::string, BitAddress>(
|
||||
Detector::*)() const) &
|
||||
Detector::getBitDefinitions);
|
||||
CppDetectorApi.def("configureTransceiver",
|
||||
(void (Detector::*)(sls::Positions)) &
|
||||
Detector::configureTransceiver,
|
||||
@@ -1968,6 +2044,58 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(const bool, sls::Positions)) &
|
||||
Detector::setUpdateMode,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("readRegister",
|
||||
(Result<sls::RegisterValue>(Detector::*)(
|
||||
sls::RegisterAddress, sls::Positions) const) &
|
||||
Detector::readRegister,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"writeRegister",
|
||||
(void (Detector::*)(sls::RegisterAddress, sls::RegisterValue, bool,
|
||||
sls::Positions)) &
|
||||
Detector::writeRegister,
|
||||
py::arg(), py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"setBit",
|
||||
(void (Detector::*)(sls::BitAddress, bool, sls::Positions)) &
|
||||
Detector::setBit,
|
||||
py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"clearBit",
|
||||
(void (Detector::*)(sls::BitAddress, bool, sls::Positions)) &
|
||||
Detector::clearBit,
|
||||
py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getBit",
|
||||
(Result<int>(Detector::*)(sls::BitAddress, sls::Positions) const) &
|
||||
Detector::getBit,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("readRegister",
|
||||
(Result<sls::RegisterValue>(Detector::*)(
|
||||
const std::string &, sls::Positions) const) &
|
||||
Detector::readRegister,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"writeRegister",
|
||||
(void (Detector::*)(const std::string &, sls::RegisterValue, bool,
|
||||
sls::Positions)) &
|
||||
Detector::writeRegister,
|
||||
py::arg(), py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"setBit",
|
||||
(void (Detector::*)(const std::string &, bool, sls::Positions)) &
|
||||
Detector::setBit,
|
||||
py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"clearBit",
|
||||
(void (Detector::*)(const std::string &, bool, sls::Positions)) &
|
||||
Detector::clearBit,
|
||||
py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getBit",
|
||||
(Result<int>(Detector::*)(const std::string &, sls::Positions) const) &
|
||||
Detector::getBit,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"readRegister",
|
||||
(Result<uint32_t>(Detector::*)(uint32_t, sls::Positions) const) &
|
||||
@@ -1990,7 +2118,7 @@ void init_det(py::module &m) {
|
||||
py::arg(), py::arg(), py::arg() = false, py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getBit",
|
||||
(Result<int>(Detector::*)(uint32_t, int, sls::Positions)) &
|
||||
(Result<int>(Detector::*)(uint32_t, int, sls::Positions) const) &
|
||||
Detector::getBit,
|
||||
py::arg(), py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("executeFirmwareTest",
|
||||
|
||||
@@ -7,15 +7,19 @@
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/TimeHelper.h"
|
||||
#include "sls/bit_utils.h"
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
namespace py = pybind11;
|
||||
void init_det(py::module &m) {
|
||||
using sls::BitAddress;
|
||||
using sls::defs;
|
||||
using sls::Detector;
|
||||
using sls::ns;
|
||||
using sls::Positions;
|
||||
using sls::RegisterAddress;
|
||||
using sls::RegisterValue;
|
||||
using sls::Result;
|
||||
|
||||
m.def("freeSharedMemory", (void (*)(const int, const int)) &sls::freeSharedMemory, py::arg() = 0, py::arg() = -1);
|
||||
|
||||
@@ -20,6 +20,7 @@ void init_scan(py::module &);
|
||||
void init_source(py::module &);
|
||||
void init_duration(py::module &);
|
||||
void init_pedestal(py::module &);
|
||||
void init_bit(py::module &);
|
||||
|
||||
PYBIND11_MODULE(_slsdet, m) {
|
||||
m.doc() = R"pbdoc(
|
||||
@@ -40,6 +41,7 @@ PYBIND11_MODULE(_slsdet, m) {
|
||||
init_source(m);
|
||||
init_duration(m);
|
||||
init_pedestal(m);
|
||||
init_bit(m);
|
||||
// init_experimental(m);
|
||||
|
||||
py::module io = m.def_submodule("io", "Submodule for io");
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <datetime.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
#include "sls/Result.h"
|
||||
#include "DurationWrapper.h"
|
||||
#include "sls/Result.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
namespace pybind11 {
|
||||
@@ -14,84 +15,130 @@ template <typename Type, typename Alloc>
|
||||
struct type_caster<sls::Result<Type, Alloc>>
|
||||
: list_caster<sls::Result<Type, Alloc>, Type> {};
|
||||
|
||||
|
||||
// Based on the typecaster in pybind11/chrono.h
|
||||
template <> struct type_caster<std::chrono::nanoseconds> {
|
||||
public:
|
||||
PYBIND11_TYPE_CASTER(std::chrono::nanoseconds, const_name("DurationWrapper"));
|
||||
public:
|
||||
PYBIND11_TYPE_CASTER(std::chrono::nanoseconds,
|
||||
const_name("DurationWrapper"));
|
||||
|
||||
// signed 25 bits required by the standard.
|
||||
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
|
||||
// signed 25 bits required by the standard.
|
||||
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
|
||||
|
||||
/**
|
||||
* Conversion part 1 (Python->C++): convert a PyObject into std::chrono::nanoseconds
|
||||
* try datetime.timedelta, floats and our DurationWrapper wrapper
|
||||
*/
|
||||
/**
|
||||
* Conversion part 1 (Python->C++): convert a PyObject into
|
||||
* std::chrono::nanoseconds try datetime.timedelta, floats and our
|
||||
* DurationWrapper wrapper
|
||||
*/
|
||||
|
||||
bool load(handle src, bool) {
|
||||
using namespace std::chrono;
|
||||
bool load(handle src, bool) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
// If invoked with datetime.delta object, same as in chrono.h
|
||||
if (PyDelta_Check(src.ptr())) {
|
||||
value = duration_cast<nanoseconds>(
|
||||
days(PyDateTime_DELTA_GET_DAYS(src.ptr())) +
|
||||
seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) +
|
||||
microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))
|
||||
|
||||
);
|
||||
return true;
|
||||
}
|
||||
// If invoked with a float we assume it is seconds and convert, same as
|
||||
// in chrono.h
|
||||
if (PyFloat_Check(src.ptr())) {
|
||||
value = duration_cast<nanoseconds>(
|
||||
duration<double>(PyFloat_AsDouble(src.ptr())));
|
||||
return true;
|
||||
}
|
||||
// If invoked with an int we assume it is nanoseconds and convert, same
|
||||
// as in chrono.h
|
||||
if (PyLong_Check(src.ptr())) {
|
||||
value = duration_cast<nanoseconds>(
|
||||
duration<int64_t>(PyLong_AsLongLong(src.ptr())));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Lastly if we were actually called with a DurationWrapper object we
|
||||
// get the number of nanoseconds and create a std::chrono::nanoseconds
|
||||
// from it
|
||||
py::object py_cls =
|
||||
py::module::import("slsdet._slsdet").attr("DurationWrapper");
|
||||
if (py::isinstance(src, py_cls)) {
|
||||
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
|
||||
value = nanoseconds(cls->count());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion part 2 (C++ -> Python)
|
||||
* import the module to get a handle to the wrapped class
|
||||
* Default construct an object of (wrapped) DurationWrapper
|
||||
* set the count from chrono::nanoseconds and return
|
||||
*/
|
||||
static handle cast(std::chrono::nanoseconds src,
|
||||
return_value_policy /* policy */, handle /* parent */) {
|
||||
py::object py_cls =
|
||||
py::module::import("slsdet._slsdet").attr("DurationWrapper");
|
||||
py::object *obj = new py::object;
|
||||
*obj = py_cls();
|
||||
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
|
||||
dur->set_count(src.count());
|
||||
return *obj;
|
||||
}
|
||||
};
|
||||
|
||||
// Type caster for sls::defs::ROI from tuple
|
||||
template <> struct type_caster<sls::defs::ROI> {
|
||||
PYBIND11_TYPE_CASTER(sls::defs::ROI, _("Sequence[int, int, int, int] or "
|
||||
"Sequence[int, int]"));
|
||||
|
||||
// convert c++ ROI to python tuple
|
||||
static handle cast(const sls::defs::ROI &roi, return_value_policy, handle) {
|
||||
return py::make_tuple(roi.xmin, roi.xmax, roi.ymin, roi.ymax).release();
|
||||
}
|
||||
|
||||
// convert from python to c++ ROI
|
||||
bool load(handle roi, bool /*allow implicit conversion*/) {
|
||||
|
||||
// accept tuple, list, numpy array any sequence
|
||||
py::sequence seq;
|
||||
try {
|
||||
seq = py::reinterpret_borrow<py::sequence>(roi);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (seq.size() != 4 && seq.size() != 2)
|
||||
return false;
|
||||
// Check if each element is an int
|
||||
for (auto item : seq) {
|
||||
if (!py::isinstance<py::int_>(item)) {
|
||||
return false;
|
||||
}
|
||||
// If invoked with datetime.delta object, same as in chrono.h
|
||||
if (PyDelta_Check(src.ptr())) {
|
||||
value = duration_cast<nanoseconds>(
|
||||
days(PyDateTime_DELTA_GET_DAYS(src.ptr())) +
|
||||
seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) +
|
||||
microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))
|
||||
|
||||
);
|
||||
return true;
|
||||
}
|
||||
// If invoked with a float we assume it is seconds and convert, same as in chrono.h
|
||||
if (PyFloat_Check(src.ptr())) {
|
||||
value = duration_cast<nanoseconds>(duration<double>(PyFloat_AsDouble(src.ptr())));
|
||||
return true;
|
||||
}
|
||||
// If invoked with an int we assume it is nanoseconds and convert, same as in chrono.h
|
||||
if (PyLong_Check(src.ptr())) {
|
||||
value = duration_cast<nanoseconds>(duration<int64_t>(PyLong_AsLongLong(src.ptr())));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Lastly if we were actually called with a DurationWrapper object we get
|
||||
// the number of nanoseconds and create a std::chrono::nanoseconds from it
|
||||
py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper");
|
||||
if (py::isinstance(src, py_cls)){
|
||||
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
|
||||
value = nanoseconds(cls->count());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion part 2 (C++ -> Python)
|
||||
* import the module to get a handle to the wrapped class
|
||||
* Default construct an object of (wrapped) DurationWrapper
|
||||
* set the count from chrono::nanoseconds and return
|
||||
*/
|
||||
static handle cast(std::chrono::nanoseconds src, return_value_policy /* policy */, handle /* parent */) {
|
||||
py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper");
|
||||
py::object* obj = new py::object;
|
||||
*obj = py_cls();
|
||||
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
|
||||
dur->set_count(src.count());
|
||||
return *obj;
|
||||
value.xmin = seq[0].cast<int>();
|
||||
value.xmax = seq[1].cast<int>();
|
||||
|
||||
if (seq.size() == 4) {
|
||||
value.ymin = seq[2].cast<int>();
|
||||
value.ymax = seq[3].cast<int>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace pybind11
|
||||
85
python/tests/conftest.py
Normal file
85
python/tests/conftest.py
Normal file
@@ -0,0 +1,85 @@
|
||||
import pytest
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
current_dir = Path(__file__).resolve().parents[2]
|
||||
|
||||
scripts_dir = current_dir / "tests" / "scripts"
|
||||
|
||||
sys.path.append(str(scripts_dir))
|
||||
|
||||
print(sys.path)
|
||||
|
||||
from utils_for_test import (
|
||||
Log,
|
||||
LogLevel,
|
||||
cleanup,
|
||||
startReceiver,
|
||||
startDetectorVirtualServer,
|
||||
loadConfig,
|
||||
loadBasicSettings,
|
||||
)
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--with-detector-simulators", action="store_true", default=False, help="Run tests that require detector simulators"
|
||||
)
|
||||
|
||||
def pytest_configure(config):
|
||||
config.addinivalue_line("markers", "withdetectorsimulators: mark test as needing detector simulators to run")
|
||||
|
||||
def pytest_collection_modifyitems(config, items):
|
||||
if config.getoption("--with-detector-simulators"):
|
||||
return
|
||||
skip = pytest.mark.skip(reason="need --with-detector-simulators option to run")
|
||||
for item in items:
|
||||
if "withdetectorsimulators" in item.keywords:
|
||||
item.add_marker(skip)
|
||||
|
||||
#helper fixture for servers
|
||||
@pytest.fixture
|
||||
def servers(request):
|
||||
try:
|
||||
return request.param # comes from @pytest.mark.parametrize(..., indirect=True)
|
||||
except AttributeError:
|
||||
# fallback default if the test did not parametrize
|
||||
return ['eiger', 'jungfrau', 'mythen3', 'gotthard2', 'ctb', 'moench', 'xilinx_ctb']
|
||||
return request.param
|
||||
|
||||
@pytest.fixture
|
||||
def test_with_simulators(servers):
|
||||
""" Fixture to automatically setup virtual detector servers for testing. """
|
||||
|
||||
LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_PythonAPI_test'
|
||||
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
|
||||
|
||||
with open(MAIN_LOG_FNAME, 'w') as fp:
|
||||
try:
|
||||
nmods = 2
|
||||
for server in servers:
|
||||
for ninterfaces in range(1,2):
|
||||
if ninterfaces == 2 and server != 'jungfrau' and server != 'moench':
|
||||
continue
|
||||
|
||||
msg = f'Starting Python API Tests for {server}'
|
||||
|
||||
if server == 'jungfrau' or server == 'moench':
|
||||
msg += f' with {ninterfaces} interfaces'
|
||||
|
||||
Log(LogLevel.INFOBLUE, msg, fp)
|
||||
cleanup(fp)
|
||||
startDetectorVirtualServer(server, nmods, fp)
|
||||
startReceiver(nmods, fp)
|
||||
d = loadConfig(name=server, log_file_fp=fp, num_mods=nmods, num_frames=1, num_interfaces=ninterfaces)
|
||||
loadBasicSettings(name=server, d=d, fp=fp)
|
||||
yield # run test
|
||||
cleanup(fp) # teardown
|
||||
except Exception as e:
|
||||
with open(MAIN_LOG_FNAME, 'a') as fp_error:
|
||||
traceback.print_exc(file=fp_error)
|
||||
Log(LogLevel.ERROR, f'Tests Failed.', fp)
|
||||
cleanup(fp)
|
||||
|
||||
|
||||
48
python/tests/test_pythonAPI.py
Normal file
48
python/tests/test_pythonAPI.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from conftest import test_with_simulators
|
||||
|
||||
from slsdet import Detector
|
||||
|
||||
@pytest.mark.withdetectorsimulators
|
||||
@pytest.mark.parametrize("servers", [["moench"]], indirect=True)
|
||||
def test_rx_ROI_moench(test_with_simulators, servers):
|
||||
""" Test setting and getting rx_ROI property of Detector class for moench. """
|
||||
|
||||
d = Detector()
|
||||
d.rx_roi = (0, 10, 10, 20)
|
||||
roi = d.rx_roi
|
||||
assert roi == [(0, 10, 10, 20)]
|
||||
|
||||
d.rx_roi = [5,15,15,25]
|
||||
|
||||
assert d.rx_roi == [(5,15,15,25)]
|
||||
|
||||
d.rx_roi = [[0,10,0,20], [5,20,410,420]]
|
||||
|
||||
roi = d.rx_roi
|
||||
assert roi == [(0,10,0,20), (5,20,410,420)]
|
||||
|
||||
d.rx_clearroi()
|
||||
roi = d.rx_roi
|
||||
assert roi == [(-1,-1,-1,-1)]
|
||||
|
||||
@pytest.mark.withdetectorsimulators
|
||||
@pytest.mark.parametrize("servers", [["mythen3"]], indirect=True)
|
||||
def test_rx_ROI_mythen(test_with_simulators, servers):
|
||||
""" Test setting and getting rx_ROI property of Detector class for mythen. """
|
||||
|
||||
d = Detector()
|
||||
d.rx_roi = (0, 10)
|
||||
roi = d.rx_roi
|
||||
assert roi == [(0, 10, -1, -1)]
|
||||
|
||||
#d.rx_roi = [[5,15, 0, 1]] # not allowed for mythen3
|
||||
|
||||
d.rx_roi = [0,10, -1, -1]
|
||||
|
||||
assert d.rx_roi == [(0,10,-1,-1)]
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Testing functions from utils.py
|
||||
|
||||
import pytest
|
||||
from slsdet.utils import *
|
||||
from slsdet import IpAddr, MacAddr, DurationWrapper
|
||||
from slsdet import IpAddr, MacAddr, DurationWrapper, RegisterAddress, RegisterValue, BitAddress
|
||||
import datetime as dt
|
||||
import pathlib
|
||||
from pathlib import Path
|
||||
@@ -199,6 +199,7 @@ def test_make_mac_from_tuple():
|
||||
MacAddr("84:a9:3e:24:32:aa"))
|
||||
|
||||
|
||||
|
||||
def test_make_path_from_str():
|
||||
assert make_path("/") == Path("/")
|
||||
assert make_path("/home") == Path("/home")
|
||||
|
||||
@@ -3,15 +3,21 @@
|
||||
add_executable(using_logger using_logger.cpp)
|
||||
target_link_libraries(using_logger
|
||||
slsSupportShared
|
||||
pthread
|
||||
rt
|
||||
)
|
||||
|
||||
set_target_properties(using_logger PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
|
||||
add_executable(using_registers using_registers.cpp)
|
||||
target_link_libraries(using_registers
|
||||
slsDetectorShared
|
||||
)
|
||||
set_target_properties(using_registers PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
|
||||
# add_executable(result useResult.cpp)
|
||||
# target_link_libraries(result
|
||||
# slsDetectorShared
|
||||
|
||||
@@ -3,15 +3,23 @@
|
||||
#include "sls/logger.h"
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
using sls::logINFO;
|
||||
using sls::logINFORED;
|
||||
using sls::logINFOBLUE;
|
||||
using sls::logINFOGREEN;
|
||||
using sls::logERROR;
|
||||
using sls::logWARNING;
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
//compare old and new
|
||||
std::cout << "Compare output between old and new:\n";
|
||||
LOG(logINFO) << "Some info message";
|
||||
LOG(logERROR) << "This is an error";
|
||||
LOG(logWARNING) << "While this is only a warning"; prefix="/afs/psi.ch/project/sls_det_software/dhanya_softwareDevelopment/mySoft/slsDetectorPackage/"
|
||||
p=${file#"$prefix"}
|
||||
|
||||
LOG(logWARNING) << "While this is only a warning";
|
||||
|
||||
//Logging level can be configure at runtime
|
||||
std::cout << "\n\n";
|
||||
std::cout << "The default macro controlled level is: "
|
||||
|
||||
49
sample/using_registers.cpp
Normal file
49
sample/using_registers.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
/* This example assumes that you have a ctb configured or using the virtual ctb detector server*/
|
||||
|
||||
#include "sls/Detector.h"
|
||||
#include "sls/bit_utils.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void somefunc(uint32_t addr){
|
||||
std::cout << "somefunc called with: " << addr << std::endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
// Config file has the following defines
|
||||
// define addr somereg 0x5
|
||||
// define bit mybit somereg 7
|
||||
|
||||
sls::Detector d;
|
||||
auto somereg = d.getRegisterDefinition("somereg");
|
||||
d.writeRegister(somereg, sls::RegisterValue(0));
|
||||
auto val = d.readRegister(somereg);
|
||||
|
||||
std::cout << "somereg has the address: " << somereg << " and value " << val.squash() << std::endl;
|
||||
|
||||
|
||||
auto mybit = d.getBitDefinition("mybit");
|
||||
std::cout << "mybit refers to register: " << mybit.address() << " bit nr: " << mybit.bitPosition() << std::endl;
|
||||
d.setBit(mybit);
|
||||
val = d.readRegister(somereg);
|
||||
std::cout << "somereg has the address: " << somereg << " and value " << val.squash() << std::endl;
|
||||
std::cout << "mybit: " << d.getBit(mybit) << std::endl;
|
||||
|
||||
|
||||
//Let's define a bit
|
||||
sls::BitAddress newbit(sls::RegisterAddress(0x6), 4);
|
||||
d.setBitDefinition("newbit", newbit);
|
||||
//This can now be usef from command line "g getbit newbit"
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t addr = somereg; //I'm not sure this should compile
|
||||
somefunc(somereg); //This should also not compile
|
||||
|
||||
|
||||
}
|
||||
@@ -76,11 +76,8 @@ foreach(exe ${JUNGFRAU_EXECUTABLES})
|
||||
target_link_libraries(${exe}
|
||||
PUBLIC
|
||||
slsSupportStatic
|
||||
pthread
|
||||
tiffio
|
||||
fmt::fmt
|
||||
#-L/usr/lib64/
|
||||
#-lm -lstdc++ -lrt
|
||||
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
|
||||
@@ -69,7 +69,6 @@ foreach(exe ${MOENCH_EXECUTABLES})
|
||||
PUBLIC
|
||||
slsSupportStatic
|
||||
${ZeroMQ_LIBRARIES}
|
||||
pthread
|
||||
tiffio
|
||||
|
||||
PRIVATE
|
||||
|
||||
@@ -37,7 +37,9 @@ target_compile_definitions(ctbDetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(ctbDetectorServer_virtual
|
||||
PUBLIC pthread rt m slsProjectCSettings
|
||||
PUBLIC
|
||||
m
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(ctbDetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -30,7 +30,8 @@ target_compile_definitions(eigerDetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(eigerDetectorServer_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
PUBLIC
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(eigerDetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -31,7 +31,8 @@ target_compile_definitions(gotthard2DetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(gotthard2DetectorServer_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
PUBLIC
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(gotthard2DetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -29,7 +29,8 @@ target_compile_definitions(jungfrauDetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(jungfrauDetectorServer_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
PUBLIC
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(jungfrauDetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -29,7 +29,8 @@ target_compile_definitions(moenchDetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(moenchDetectorServer_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
PUBLIC
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(moenchDetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -33,7 +33,8 @@ target_compile_definitions(mythen3DetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(mythen3DetectorServer_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
PUBLIC
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(mythen3DetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -31,7 +31,9 @@ target_compile_definitions(xilinx_ctbDetectorServer_virtual
|
||||
)
|
||||
|
||||
target_link_libraries(xilinx_ctbDetectorServer_virtual
|
||||
PUBLIC pthread rt m slsProjectCSettings
|
||||
PUBLIC
|
||||
m
|
||||
slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(xilinx_ctbDetectorServer_virtual PROPERTIES
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Prepare MH02 configuration
|
||||
reg 0xC00C 0x00000041
|
||||
reg 0xC00C 0x00040041
|
||||
reg 0xC010 0x01200004
|
||||
|
||||
# configure Matterhorn SPI
|
||||
@@ -14,7 +14,7 @@ reg 0xC120 0x1
|
||||
reg 0xC120 0x0
|
||||
|
||||
# set MSB LSB inversions and polarity for transceiver
|
||||
reg 0xC120 0x61e0
|
||||
reg 0xC120 0x1e0
|
||||
|
||||
# Enable MH02 PLL clock
|
||||
pattern enable_clock_pattern.pyat
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
# turn off clock
|
||||
setbit 0xC00C 16
|
||||
setbit 0xC014 0
|
||||
clearbit 0xB018 15
|
||||
setbit 0xB010 15
|
||||
sleep 1
|
||||
|
||||
# reset Matterhorn periphery
|
||||
@@ -9,8 +9,7 @@ setbit 0xC014 1
|
||||
sleep 1
|
||||
|
||||
# turn on clock
|
||||
clearbit 0xC00C 16
|
||||
setbit 0xC014 0
|
||||
clearbit 0xB010 15
|
||||
sleep 1
|
||||
|
||||
# reset rx transceiver datapath
|
||||
|
||||
@@ -28,11 +28,11 @@ target_link_libraries(slsDetectorObject
|
||||
PUBLIC
|
||||
slsProjectOptions
|
||||
slsSupportStatic
|
||||
pthread
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
)
|
||||
|
||||
|
||||
set(DETECTOR_LIBRARY_TARGETS slsDetectorObject)
|
||||
|
||||
|
||||
@@ -97,8 +97,7 @@ if(SLS_USE_TEXTCLIENT)
|
||||
add_executable(${val1} src/CmdApp.cpp)
|
||||
|
||||
target_link_libraries(${val1}
|
||||
slsDetectorStatic
|
||||
pthread
|
||||
slsDetectorStatic
|
||||
)
|
||||
SET_SOURCE_FILES_PROPERTIES( src/Caller.cpp PROPERTIES COMPILE_FLAGS "-Wno-unused-variable -Wno-unused-but-set-variable")
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@ class Caller {
|
||||
static void EmptyDataCallBack(detectorData *data, uint64_t frameIndex,
|
||||
uint32_t subFrameIndex, void *this_pointer);
|
||||
|
||||
std::string bitoperations(int action);
|
||||
RegisterAddress parseAddress(const std::string &saddr) const;
|
||||
bool parseValidate();
|
||||
BitAddress parseBitAddress() const;
|
||||
|
||||
FunctionMap functions{
|
||||
{"list", &Caller::list},
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ _sd() {
|
||||
local IS_PATH=0
|
||||
|
||||
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
__acquire() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
@@ -682,6 +682,54 @@ fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__define_bit() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__define_reg() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__definelist_bit() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
}
|
||||
__definelist_reg() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
}
|
||||
__delay() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
_sd() {
|
||||
|
||||
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
__acquire() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
@@ -606,6 +606,54 @@ fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__define_bit() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__define_reg() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__definelist_bit() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
}
|
||||
__definelist_reg() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
}
|
||||
__delay() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
|
||||
@@ -2761,6 +2761,90 @@ sleep:
|
||||
- argc: 2
|
||||
arg_types: [ int, special::time_unit ]
|
||||
|
||||
define_reg:
|
||||
is_description: true
|
||||
actions:
|
||||
GET:
|
||||
argc: 1
|
||||
arg_types: [ std::string ]
|
||||
PUT:
|
||||
argc: 2
|
||||
arg_types: [ std::string, int ]
|
||||
|
||||
define_bit:
|
||||
is_description: true
|
||||
actions:
|
||||
GET:
|
||||
args:
|
||||
- argc: 1
|
||||
arg_types: [ std::string ]
|
||||
- argc: 2
|
||||
arg_types: [ std::string, int ]
|
||||
PUT:
|
||||
argc: 3
|
||||
arg_types: [ std::string, std::string, int ]
|
||||
|
||||
definelist_reg:
|
||||
is_description: true
|
||||
actions:
|
||||
GET:
|
||||
argc: 0
|
||||
|
||||
definelist_bit:
|
||||
is_description: true
|
||||
actions:
|
||||
GET:
|
||||
argc: 0
|
||||
|
||||
reg:
|
||||
is_description: true
|
||||
actions:
|
||||
GET:
|
||||
argc: 1
|
||||
arg_types: [ std::string]
|
||||
PUT:
|
||||
args:
|
||||
- argc: 2
|
||||
arg_types: [ uint32_t, uint32_t ]
|
||||
- argc: 3
|
||||
arg_types: [ uint32_t, uint32_t, special::validate ]
|
||||
|
||||
|
||||
getbit:
|
||||
is_description: true
|
||||
actions:
|
||||
GET:
|
||||
args:
|
||||
- argc: 1
|
||||
arg_types: [ std::string ]
|
||||
- argc: 2
|
||||
arg_types: [ std::string, std::string ]
|
||||
|
||||
|
||||
setbit:
|
||||
is_description: true
|
||||
actions:
|
||||
PUT:
|
||||
args:
|
||||
- argc: 1
|
||||
arg_types: [ std::string ]
|
||||
- argc: 2
|
||||
arg_types: [ std::string, std::string ]
|
||||
- argc: 3
|
||||
arg_types: [ std::string, std::string, special::validate ]
|
||||
|
||||
clearbit:
|
||||
is_description: true
|
||||
actions:
|
||||
PUT:
|
||||
args:
|
||||
- argc: 1
|
||||
arg_types: [ std::string ]
|
||||
- argc: 2
|
||||
arg_types: [ std::string, std::string ]
|
||||
- argc: 3
|
||||
arg_types: [ std::string, std::string, special::validate ]
|
||||
|
||||
|
||||
################# special commands ##########################
|
||||
|
||||
@@ -4172,36 +4256,6 @@ update:
|
||||
input_types: [ std::string, std::string ]
|
||||
output: [ '"successful"' ]
|
||||
|
||||
reg:
|
||||
help: "[address] [32 bit value][(optional)--validate]\n\t[Mythen3][Gotthard2] Reads/writes to a 32 bit register in hex. Advanced Function!\n\tGoes to stop server. Hence, can be called while calling blocking acquire().\n\t\t Use --validate to force validation when writing to it.\n\t[Eiger] +0x100 for only left, +0x200 for only right."
|
||||
actions:
|
||||
GET:
|
||||
argc: 1
|
||||
require_det_id: true
|
||||
function: readRegister
|
||||
input: [ 'args[0]' ]
|
||||
input_types: [ uint32_t ]
|
||||
cast_input: [ true ]
|
||||
output: [ OutStringHex(t) ]
|
||||
PUT:
|
||||
require_det_id: true
|
||||
function: writeRegister
|
||||
output: [ '"["', 'args[0]', '", "', 'args[1]', '"]"' ]
|
||||
args:
|
||||
- argc: 2
|
||||
input: [ 'args[0]', 'args[1]', '"0"' ]
|
||||
input_types: [ uint32_t, uint32_t, bool ]
|
||||
arg_types: [ uint32_t, uint32_t ]
|
||||
cast_input: [ true, true, true ]
|
||||
- argc: 3
|
||||
arg_types: [ uint32_t, uint32_t, special::validate ]
|
||||
exceptions:
|
||||
- condition: 'args[2] != "--validate"'
|
||||
message: '"Could not scan third argument. Did you mean --validate?"'
|
||||
input: [ 'args[0]', 'args[1]', '"1"' ]
|
||||
input_types: [ uint32_t, uint32_t, bool ]
|
||||
cast_input: [ true, true, true ]
|
||||
|
||||
adcreg:
|
||||
help: "[address] [value]\n\t[Jungfrau][Moench][Ctb] Writes to an adc register in hex. Advanced user Function!"
|
||||
actions:
|
||||
@@ -4214,62 +4268,7 @@ adcreg:
|
||||
cast_input: [ true, true ]
|
||||
output: [ ToString(args) ]
|
||||
|
||||
getbit:
|
||||
help: "[reg address in hex] [bit index]\n\tGets bit in address."
|
||||
actions:
|
||||
GET:
|
||||
argc: 2
|
||||
exceptions:
|
||||
- condition: 'StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31'
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
require_det_id: true
|
||||
function: getBit
|
||||
input: [ 'args[0]', 'args[1]' ]
|
||||
input_types: [ uint32_t, int ]
|
||||
cast_input: [ true, true ]
|
||||
output: [ OutString(t) ]
|
||||
|
||||
Setbit:
|
||||
template: true
|
||||
actions:
|
||||
PUT:
|
||||
require_det_id: true
|
||||
function: setBit
|
||||
output: [ '"["', 'args[0]', '", "', 'args[1]', '"]"' ]
|
||||
args:
|
||||
- argc: 2
|
||||
exceptions:
|
||||
- condition: 'StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31'
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
input: [ 'args[0]', 'args[1]', '"0"' ]
|
||||
input_types: [ uint32_t, int, bool ]
|
||||
arg_types: [ uint32_t, int ]
|
||||
cast_input: [ true, true, true ]
|
||||
- argc: 3
|
||||
arg_types: [ uint32_t, int, special::validate ]
|
||||
exceptions:
|
||||
- condition: 'StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31'
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
- condition: 'args[2] != "--validate"'
|
||||
message: '"Could not scan third argument. Did you mean --validate?"'
|
||||
input: [ 'args[0]', 'args[1]', '"1"' ]
|
||||
input_types: [ uint32_t, int, bool ]
|
||||
cast_input: [ true, true, true ]
|
||||
|
||||
|
||||
setbit:
|
||||
inherit_actions: Setbit
|
||||
help: "[reg address in hex] [bit index]\n\tSets bit in address.\n\tUse --validate to force validation."
|
||||
actions:
|
||||
PUT:
|
||||
function: setBit
|
||||
|
||||
clearbit:
|
||||
inherit_actions: Setbit
|
||||
help: "[reg address in hex] [bit index]\n\tClears bit in address.\n\tUse --validate to force validation."
|
||||
actions:
|
||||
PUT:
|
||||
function: clearBit
|
||||
|
||||
initialchecks:
|
||||
help: "[0, 1]\n\t[Mythen3][Gotthard2] Enable or disable intial compatibility and other checks at detector start up. It is enabled by default. Must come before 'hostname' command to take effect. Can be used to reprogram fpga when current firmware is incompatible.\n\tAdvanced User function!"
|
||||
|
||||
@@ -1096,74 +1096,49 @@ clearbit:
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- int
|
||||
argc: 2
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- true
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
exceptions:
|
||||
- condition: StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
function: clearBit
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
- '"0"'
|
||||
input_types:
|
||||
- uint32_t
|
||||
- int
|
||||
- bool
|
||||
output:
|
||||
- '"["'
|
||||
- args[0]
|
||||
- '", "'
|
||||
- args[1]
|
||||
- '"]"'
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- int
|
||||
- special::validate
|
||||
argc: 3
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- true
|
||||
- std::string
|
||||
- std::string
|
||||
argc: 2
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
exceptions:
|
||||
- condition: StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
- condition: args[2] != "--validate"
|
||||
message: '"Could not scan third argument. Did you mean --validate?"'
|
||||
function: clearBit
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
- '"1"'
|
||||
input_types:
|
||||
- uint32_t
|
||||
- int
|
||||
- bool
|
||||
output:
|
||||
- '"["'
|
||||
- args[0]
|
||||
- '", "'
|
||||
- args[1]
|
||||
- '"]"'
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- std::string
|
||||
- std::string
|
||||
- special::validate
|
||||
argc: 3
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
command_name: clearbit
|
||||
function_alias: clearbit
|
||||
help: "[reg address in hex] [bit index]\n\tClears bit in address.\n\tUse --validate\
|
||||
\ to force validation."
|
||||
help: ''
|
||||
infer_action: true
|
||||
template: true
|
||||
is_description: true
|
||||
clearbusy:
|
||||
actions:
|
||||
PUT:
|
||||
@@ -2500,6 +2475,132 @@ defaultpattern:
|
||||
\ to go back to initial settings."
|
||||
infer_action: true
|
||||
template: true
|
||||
define_bit:
|
||||
actions:
|
||||
GET:
|
||||
args:
|
||||
- arg_types:
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
- arg_types:
|
||||
- std::string
|
||||
- int
|
||||
argc: 2
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- std::string
|
||||
- std::string
|
||||
- int
|
||||
argc: 3
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
command_name: define_bit
|
||||
function_alias: define_bit
|
||||
help: ''
|
||||
infer_action: true
|
||||
is_description: true
|
||||
define_reg:
|
||||
actions:
|
||||
GET:
|
||||
args:
|
||||
- arg_types:
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- std::string
|
||||
- int
|
||||
argc: 2
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
command_name: define_reg
|
||||
function_alias: define_reg
|
||||
help: ''
|
||||
infer_action: true
|
||||
is_description: true
|
||||
definelist_bit:
|
||||
actions:
|
||||
GET:
|
||||
args:
|
||||
- arg_types: []
|
||||
argc: 0
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
command_name: definelist_bit
|
||||
function_alias: definelist_bit
|
||||
help: ''
|
||||
infer_action: true
|
||||
is_description: true
|
||||
definelist_reg:
|
||||
actions:
|
||||
GET:
|
||||
args:
|
||||
- arg_types: []
|
||||
argc: 0
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
command_name: definelist_reg
|
||||
function_alias: definelist_reg
|
||||
help: ''
|
||||
infer_action: true
|
||||
is_description: true
|
||||
delay:
|
||||
actions:
|
||||
GET:
|
||||
@@ -4706,32 +4807,35 @@ getbit:
|
||||
GET:
|
||||
args:
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- int
|
||||
argc: 2
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
exceptions:
|
||||
- condition: StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
function: getBit
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
input_types:
|
||||
- uint32_t
|
||||
- int
|
||||
output:
|
||||
- OutString(t)
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
- arg_types:
|
||||
- std::string
|
||||
- std::string
|
||||
argc: 2
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
command_name: getbit
|
||||
function_alias: getbit
|
||||
help: "[reg address in hex] [bit index]\n\tGets bit in address."
|
||||
help: ''
|
||||
infer_action: true
|
||||
is_description: true
|
||||
hardwareversion:
|
||||
actions:
|
||||
GET:
|
||||
@@ -7870,20 +7974,16 @@ reg:
|
||||
GET:
|
||||
args:
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input:
|
||||
- true
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: readRegister
|
||||
input:
|
||||
- args[0]
|
||||
input_types:
|
||||
- uint32_t
|
||||
output:
|
||||
- OutStringHex(t)
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: true
|
||||
PUT:
|
||||
args:
|
||||
@@ -7891,68 +7991,34 @@ reg:
|
||||
- uint32_t
|
||||
- uint32_t
|
||||
argc: 2
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- true
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: writeRegister
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
- '"0"'
|
||||
input_types:
|
||||
- uint32_t
|
||||
- uint32_t
|
||||
- bool
|
||||
output:
|
||||
- '"["'
|
||||
- args[0]
|
||||
- '", "'
|
||||
- args[1]
|
||||
- '"]"'
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- uint32_t
|
||||
- special::validate
|
||||
argc: 3
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- true
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
exceptions:
|
||||
- condition: args[2] != "--validate"
|
||||
message: '"Could not scan third argument. Did you mean --validate?"'
|
||||
function: writeRegister
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
- '"1"'
|
||||
input_types:
|
||||
- uint32_t
|
||||
- uint32_t
|
||||
- bool
|
||||
output:
|
||||
- '"["'
|
||||
- args[0]
|
||||
- '", "'
|
||||
- args[1]
|
||||
- '"]"'
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
command_name: reg
|
||||
function_alias: reg
|
||||
help: "[address] [32 bit value][(optional)--validate]\n\t[Mythen3][Gotthard2] Reads/writes\
|
||||
\ to a 32 bit register in hex. Advanced Function!\n\tGoes to stop server. Hence,\
|
||||
\ can be called while calling blocking acquire().\n\t\t Use --validate to force\
|
||||
\ validation when writing to it.\n\t[Eiger] +0x100 for only left, +0x200 for only\
|
||||
\ right."
|
||||
help: ''
|
||||
infer_action: true
|
||||
is_description: true
|
||||
resetdacs:
|
||||
actions:
|
||||
PUT:
|
||||
@@ -9577,74 +9643,49 @@ setbit:
|
||||
PUT:
|
||||
args:
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- int
|
||||
argc: 2
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- true
|
||||
- std::string
|
||||
argc: 1
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
exceptions:
|
||||
- condition: StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
function: setBit
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
- '"0"'
|
||||
input_types:
|
||||
- uint32_t
|
||||
- int
|
||||
- bool
|
||||
output:
|
||||
- '"["'
|
||||
- args[0]
|
||||
- '", "'
|
||||
- args[1]
|
||||
- '"]"'
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- uint32_t
|
||||
- int
|
||||
- special::validate
|
||||
argc: 3
|
||||
cast_input:
|
||||
- true
|
||||
- true
|
||||
- true
|
||||
- std::string
|
||||
- std::string
|
||||
argc: 2
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
exceptions:
|
||||
- condition: StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31
|
||||
message: '"Bit number out of range: " + args[1]'
|
||||
- condition: args[2] != "--validate"
|
||||
message: '"Could not scan third argument. Did you mean --validate?"'
|
||||
function: setBit
|
||||
input:
|
||||
- args[0]
|
||||
- args[1]
|
||||
- '"1"'
|
||||
input_types:
|
||||
- uint32_t
|
||||
- int
|
||||
- bool
|
||||
output:
|
||||
- '"["'
|
||||
- args[0]
|
||||
- '", "'
|
||||
- args[1]
|
||||
- '"]"'
|
||||
require_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
- arg_types:
|
||||
- std::string
|
||||
- std::string
|
||||
- special::validate
|
||||
argc: 3
|
||||
cast_input: []
|
||||
check_det_id: false
|
||||
convert_det_id: true
|
||||
function: ''
|
||||
input: []
|
||||
input_types: []
|
||||
output: []
|
||||
require_det_id: false
|
||||
store_result_in_t: false
|
||||
command_name: setbit
|
||||
function_alias: setbit
|
||||
help: "[reg address in hex] [bit index]\n\tSets bit in address.\n\tUse --validate\
|
||||
\ to force validation."
|
||||
help: ''
|
||||
infer_action: true
|
||||
template: true
|
||||
is_description: true
|
||||
settings:
|
||||
actions:
|
||||
GET:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
#include "sls/Pattern.h"
|
||||
#include "sls/Result.h"
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include <chrono>
|
||||
@@ -1837,6 +1838,61 @@ class Detector {
|
||||
/** [CTB][Xilinx CTB] */
|
||||
std::string getSlowADCName(const defs::dacIndex i) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
int getRegisterDefinitionsCount() const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
void setRegisterDefinition(const std::string &name, RegisterAddress addr);
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
bool hasRegisterDefinition(const std::string &name) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
bool hasRegisterDefinition(RegisterAddress addr) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
RegisterAddress getRegisterDefinitionAddress(const std::string &name) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
std::string getRegisterDefinitionName(RegisterAddress addr) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
void clearRegisterDefinitions();
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
void
|
||||
setRegisterDefinitions(const std::map<std::string, RegisterAddress> &list);
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
std::map<std::string, RegisterAddress> getRegisterDefinitions() const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
int getBitDefinitionsCount() const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
void setBitDefinition(const std::string &name, BitAddress addr);
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
bool hasBitDefinition(const std::string &name) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
bool hasBitDefinition(BitAddress addr) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] returns bit position and address */
|
||||
BitAddress getBitDefinitionAddress(const std::string &name) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
std::string getBitDefinitionName(BitAddress addr) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
void clearBitDefinitions();
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
void setBitDefinitions(const std::map<std::string, BitAddress> &list);
|
||||
|
||||
/** [CTB][Xilinx CTB] */
|
||||
std::map<std::string, BitAddress> getBitDefinitions() const;
|
||||
|
||||
///@}
|
||||
|
||||
/** @name Xilinx CTB Specific */
|
||||
@@ -2045,26 +2101,71 @@ class Detector {
|
||||
/** Advanced user Function! \n
|
||||
* Goes to stop server. Hence, can be called while calling blocking
|
||||
* acquire(). \n [Eiger] Address is +0x100 for only left, +0x200 for only
|
||||
* right. */
|
||||
Result<uint32_t> readRegister(uint32_t addr, Positions pos = {}) const;
|
||||
* right.*/
|
||||
Result<RegisterValue> readRegister(RegisterAddress addr,
|
||||
Positions pos = {}) const;
|
||||
|
||||
/** Advanced user Function! \n
|
||||
* Goes to stop server. Hence, can be called while calling blocking
|
||||
* acquire(). \n [Eiger] Address is +0x100 for only left, +0x200 for only
|
||||
* right. */
|
||||
void writeRegister(uint32_t addr, uint32_t val, bool validate = false,
|
||||
Positions pos = {});
|
||||
* right.*/
|
||||
void writeRegister(RegisterAddress addr, RegisterValue val,
|
||||
bool validate = false, Positions pos = {});
|
||||
|
||||
/** Advanced user Function! */
|
||||
void setBit(uint32_t addr, int bitnr, bool validate = false,
|
||||
/** Advanced user Function! */
|
||||
void setBit(BitAddress addr, bool validate = false, Positions pos = {});
|
||||
|
||||
/** Advanced user Function!*/
|
||||
void clearBit(BitAddress addr, bool validate = false, Positions pos = {});
|
||||
|
||||
/** Advanced user Function! */
|
||||
Result<int> getBit(BitAddress addr, Positions pos = {}) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] Advanced user Function! */
|
||||
Result<RegisterValue> readRegister(const std::string ®_name,
|
||||
Positions pos = {}) const;
|
||||
|
||||
/** [CTB][Xilinx CTB] Advanced user Function! */
|
||||
void writeRegister(const std::string ®_name, RegisterValue val,
|
||||
bool validate = false, Positions pos = {});
|
||||
|
||||
/** [CTB][Xilinx CTB] Advanced user Function! */
|
||||
void setBit(const std::string &bit_name, bool validate = false,
|
||||
Positions pos = {});
|
||||
|
||||
/** Advanced user Function! */
|
||||
void clearBit(uint32_t addr, int bitnr, bool validate = false,
|
||||
/** [CTB][Xilinx CTB] Advanced user Function! */
|
||||
void clearBit(const std::string &bit_name, bool validate = false,
|
||||
Positions pos = {});
|
||||
|
||||
/** Advanced user Function! */
|
||||
Result<int> getBit(uint32_t addr, int bitnr, Positions pos = {});
|
||||
/** [CTB][Xilinx CTB] Advanced user Function! */
|
||||
Result<int> getBit(const std::string &bit_name, Positions pos = {}) const;
|
||||
|
||||
/** Deprecated Advanced user Function! */
|
||||
[[deprecated("Use the overload taking RegisterAddress instead of "
|
||||
"uint32_t")]] Result<uint32_t>
|
||||
readRegister(uint32_t addr, Positions pos = {}) const;
|
||||
|
||||
/** Deprecated Advanced user Function! */
|
||||
[[deprecated("Use the overload taking RegisterAddress and RegisterValue "
|
||||
"instead of uint32_t")]] void
|
||||
writeRegister(uint32_t addr, uint32_t val, bool validate = false,
|
||||
Positions pos = {});
|
||||
|
||||
/** Deprecated Advanced user Function! */
|
||||
[[deprecated("Use the overload taking BitAddress instead of uint32_t and "
|
||||
"int")]] void
|
||||
setBit(uint32_t addr, int bitnr, bool validate = false, Positions pos = {});
|
||||
|
||||
/** Deprecated Advanced user Function! */
|
||||
[[deprecated("Use the overload taking BitAddress instead of uint32_t and "
|
||||
"int")]] void
|
||||
clearBit(uint32_t addr, int bitnr, bool validate = false,
|
||||
Positions pos = {});
|
||||
|
||||
/** Deprecated Advanced user Function! */
|
||||
[[deprecated("Use the overload taking BitAddress instead of uint32_t and "
|
||||
"int")]] Result<int>
|
||||
getBit(uint32_t addr, int bitnr, Positions pos = {}) const;
|
||||
|
||||
/** [Jungfrau][Moench][Mythen3][Gotthard2][CTB] Advanced user
|
||||
* Function! */
|
||||
|
||||
@@ -1453,100 +1453,6 @@ std::string Caller::chipversion(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::clearbit(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([reg address in hex] [bit index]
|
||||
Clears bit in address.
|
||||
Use --validate to force validation. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (1 && args.size() != 2 && args.size() != 3) {
|
||||
throw RuntimeError("Wrong number of arguments for action PUT");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<int>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to int");
|
||||
}
|
||||
try {
|
||||
StringTo<bool>("0");
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 2 to bool");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<int>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to int");
|
||||
}
|
||||
try {
|
||||
StringTo<bool>("1");
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 2 to bool");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError(
|
||||
"INTERNAL ERROR: Invalid action: supported actions are ['PUT']");
|
||||
}
|
||||
|
||||
// generate code for each action
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (args.size() == 2) {
|
||||
if (StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31) {
|
||||
throw RuntimeError("Bit number out of range: " + args[1]);
|
||||
}
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<int>(args[1]);
|
||||
auto arg2 = StringTo<bool>("0");
|
||||
det->clearBit(arg0, arg1, arg2, std::vector<int>{det_id});
|
||||
os << "[" << args[0] << ", " << args[1] << "]" << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
if (StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31) {
|
||||
throw RuntimeError("Bit number out of range: " + args[1]);
|
||||
}
|
||||
if (args[2] != "--validate") {
|
||||
throw RuntimeError(
|
||||
"Could not scan third argument. Did you mean --validate?");
|
||||
}
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<int>(args[1]);
|
||||
auto arg2 = StringTo<bool>("1");
|
||||
det->clearBit(arg0, arg1, arg2, std::vector<int>{det_id});
|
||||
os << "[" << args[0] << ", " << args[1] << "]" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::clearbusy(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
@@ -5955,60 +5861,6 @@ std::string Caller::gates(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::getbit(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([reg address in hex] [bit index]
|
||||
Gets bit in address. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (1 && args.size() != 2) {
|
||||
throw RuntimeError("Wrong number of arguments for action GET");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<int>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to int");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError(
|
||||
"INTERNAL ERROR: Invalid action: supported actions are ['GET']");
|
||||
}
|
||||
|
||||
// generate code for each action
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (args.size() == 2) {
|
||||
if (StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31) {
|
||||
throw RuntimeError("Bit number out of range: " + args[1]);
|
||||
}
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<int>(args[1]);
|
||||
auto t = det->getBit(arg0, arg1, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::hardwareversion(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
@@ -8454,7 +8306,7 @@ std::string Caller::patternstart(int action) {
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N(
|
||||
[Mythen3][Xilinx Ctb] Starts Pattern )V0G0N"
|
||||
[Mythen3][Ctb][Xilinx Ctb] Starts Pattern )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
@@ -10096,119 +9948,6 @@ std::string Caller::rebootcontroller(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::reg(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([address] [32 bit value][(optional)--validate]
|
||||
[Mythen3][Gotthard2] Reads/writes to a 32 bit register in hex. Advanced Function!
|
||||
Goes to stop server. Hence, can be called while calling blocking acquire().
|
||||
Use --validate to force validation when writing to it.
|
||||
[Eiger] +0x100 for only left, +0x200 for only right. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (1 && args.size() != 1) {
|
||||
throw RuntimeError("Wrong number of arguments for action GET");
|
||||
}
|
||||
|
||||
if (args.size() == 1) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (1 && args.size() != 2 && args.size() != 3) {
|
||||
throw RuntimeError("Wrong number of arguments for action PUT");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<uint32_t>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<bool>("0");
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 2 to bool");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<uint32_t>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<bool>("1");
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 2 to bool");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError("INTERNAL ERROR: Invalid action: supported actions "
|
||||
"are ['GET', 'PUT']");
|
||||
}
|
||||
|
||||
// generate code for each action
|
||||
if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (args.size() == 1) {
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto t = det->readRegister(arg0, std::vector<int>{det_id});
|
||||
os << OutStringHex(t) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (args.size() == 2) {
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<uint32_t>(args[1]);
|
||||
auto arg2 = StringTo<bool>("0");
|
||||
det->writeRegister(arg0, arg1, arg2, std::vector<int>{det_id});
|
||||
os << "[" << args[0] << ", " << args[1] << "]" << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
if (args[2] != "--validate") {
|
||||
throw RuntimeError(
|
||||
"Could not scan third argument. Did you mean --validate?");
|
||||
}
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<uint32_t>(args[1]);
|
||||
auto arg2 = StringTo<bool>("1");
|
||||
det->writeRegister(arg0, arg1, arg2, std::vector<int>{det_id});
|
||||
os << "[" << args[0] << ", " << args[1] << "]" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::resetdacs(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
@@ -12384,100 +12123,6 @@ std::string Caller::serialnumber(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::setbit(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([reg address in hex] [bit index]
|
||||
Sets bit in address.
|
||||
Use --validate to force validation. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// check if action and arguments are valid
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (1 && args.size() != 2 && args.size() != 3) {
|
||||
throw RuntimeError("Wrong number of arguments for action PUT");
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<int>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to int");
|
||||
}
|
||||
try {
|
||||
StringTo<bool>("0");
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 2 to bool");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
try {
|
||||
StringTo<uint32_t>(args[0]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 0 to uint32_t");
|
||||
}
|
||||
try {
|
||||
StringTo<int>(args[1]);
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 1 to int");
|
||||
}
|
||||
try {
|
||||
StringTo<bool>("1");
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not convert argument 2 to bool");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError(
|
||||
"INTERNAL ERROR: Invalid action: supported actions are ['PUT']");
|
||||
}
|
||||
|
||||
// generate code for each action
|
||||
if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (args.size() == 2) {
|
||||
if (StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31) {
|
||||
throw RuntimeError("Bit number out of range: " + args[1]);
|
||||
}
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<int>(args[1]);
|
||||
auto arg2 = StringTo<bool>("0");
|
||||
det->setBit(arg0, arg1, arg2, std::vector<int>{det_id});
|
||||
os << "[" << args[0] << ", " << args[1] << "]" << '\n';
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
if (StringTo<int>(args[1]) < 0 || StringTo<int>(args[1]) > 31) {
|
||||
throw RuntimeError("Bit number out of range: " + args[1]);
|
||||
}
|
||||
if (args[2] != "--validate") {
|
||||
throw RuntimeError(
|
||||
"Could not scan third argument. Did you mean --validate?");
|
||||
}
|
||||
auto arg0 = StringTo<uint32_t>(args[0]);
|
||||
auto arg1 = StringTo<int>(args[1]);
|
||||
auto arg2 = StringTo<bool>("1");
|
||||
det->setBit(arg0, arg1, arg2, std::vector<int>{det_id});
|
||||
os << "[" << args[0] << ", " << args[1] << "]" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::settings(int action) {
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "CmdParser.h"
|
||||
#include "HelpDacs.h"
|
||||
#include "sls/Detector.h"
|
||||
|
||||
#include "sls/bit_utils.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -107,6 +107,10 @@ class Caller {
|
||||
std::string dbitpipeline(int action);
|
||||
std::string defaultdac(int action);
|
||||
std::string defaultpattern(int action);
|
||||
std::string define_bit(int action);
|
||||
std::string define_reg(int action);
|
||||
std::string definelist_bit(int action);
|
||||
std::string definelist_reg(int action);
|
||||
std::string delay(int action);
|
||||
std::string delayl(int action);
|
||||
std::string detectorserverversion(int action);
|
||||
@@ -398,6 +402,11 @@ class Caller {
|
||||
static void EmptyDataCallBack(detectorData *data, uint64_t frameIndex,
|
||||
uint32_t subFrameIndex, void *this_pointer);
|
||||
|
||||
std::string bitoperations(int action);
|
||||
RegisterAddress parseAddress(const std::string &saddr) const;
|
||||
bool parseValidate();
|
||||
BitAddress parseBitAddress() const;
|
||||
|
||||
FunctionMap functions{
|
||||
{"list", &Caller::list},
|
||||
|
||||
@@ -451,6 +460,10 @@ class Caller {
|
||||
{"dbitpipeline", &Caller::dbitpipeline},
|
||||
{"defaultdac", &Caller::defaultdac},
|
||||
{"defaultpattern", &Caller::defaultpattern},
|
||||
{"define_bit", &Caller::define_bit},
|
||||
{"define_reg", &Caller::define_reg},
|
||||
{"definelist_bit", &Caller::definelist_bit},
|
||||
{"definelist_reg", &Caller::definelist_reg},
|
||||
{"delay", &Caller::delay},
|
||||
{"delayl", &Caller::delayl},
|
||||
{"detectorserverversion", &Caller::detectorserverversion},
|
||||
|
||||
@@ -1437,4 +1437,398 @@ std::string Caller::sleep(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::define_reg(int action) {
|
||||
std::ostringstream os;
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[Ctb][Xilinx Ctb]"
|
||||
"\n\t[reg name] [reg address]"
|
||||
"\n\n\tSets a user defined register in shared memory. The name "
|
||||
"can be upto 32 characters long."
|
||||
"\n\teg."
|
||||
"\n\tsls_detector_put define_reg test_reg 0x200"
|
||||
"\n\n\tOne can retrieve the address using the name and vice "
|
||||
"versa."
|
||||
"\n\teg."
|
||||
"\n\tsls_detector_get define_reg test_reg"
|
||||
"\n\tsls_detector_get define_reg 0x200"
|
||||
"\n\n\tOne can then use this user-defined name in other commands "
|
||||
"instead of hard coding the address such as for reg, setbit, "
|
||||
"clearbit and getbit commands."
|
||||
"\n\teg."
|
||||
"\n\tsls_detector_put reg test_reg 0x1"
|
||||
"\n\tsls_detector_put setbit test_reg 2"
|
||||
"\n\tsls_detector_put clearbit test_reg 2"
|
||||
"\n\tsls_detector_get getbit test_reg 2"
|
||||
<< '\n';
|
||||
return os.str();
|
||||
}
|
||||
auto det_type = det->getDetectorType().squash();
|
||||
if (det_type != defs::XILINX_CHIPTESTBOARD &&
|
||||
det_type != defs::CHIPTESTBOARD) {
|
||||
throw RuntimeError(
|
||||
"define_reg command only supported for ctb and xilinx_ctb");
|
||||
}
|
||||
if (det_id != -1) {
|
||||
throw RuntimeError("Cannot use define at module level. Use the default "
|
||||
"multi-module level");
|
||||
}
|
||||
if (action == defs::GET_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
// get name from address
|
||||
if (is_hex_or_dec_uint(args[0])) {
|
||||
auto addr = RegisterAddress(args[0]);
|
||||
auto t = det->getRegisterDefinitionName(addr);
|
||||
os << t << '\n';
|
||||
}
|
||||
// get address from name
|
||||
else {
|
||||
auto t = det->getRegisterDefinitionAddress(args[0]);
|
||||
os << t.str() << '\n';
|
||||
}
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
auto name = args[0];
|
||||
auto addr = RegisterAddress(args[1]);
|
||||
det->setRegisterDefinition(name, addr);
|
||||
os << "addr " << name << ' ' << addr.str() << '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::define_bit(int action) {
|
||||
std::ostringstream os;
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[Ctb][Xilinx Ctb]"
|
||||
"\n\t[bit name] [regiser name/address] [bit position]"
|
||||
"\n\n\tSets a user defined bit name in shared memory "
|
||||
"representing the register address and the bit position. The "
|
||||
"address can be named prior using define_reg command. The name "
|
||||
"can be upto 32 characters long."
|
||||
"\n\teg."
|
||||
"\n\tsls_detector_put define_bit test_bit test_reg 2"
|
||||
"\n\tsls_detector_put define_bit test_bit 0x200 2"
|
||||
"\n\n\tOne can retrieve the bit address using the name and vice "
|
||||
"versa using both register name or address and bit position."
|
||||
"\n\teg."
|
||||
"\n\tsls_detector_get define_bit test_bit"
|
||||
"\n\tsls_detector_get define_bit test_reg 2"
|
||||
"\n\tsls_detector_get define_bit 0x200 2"
|
||||
"\n\n\tOne can then use this user-defined name in other commands "
|
||||
"such as for setbit, clearbit and getbit commands. When using "
|
||||
"bit names, please dont use register name or address as bit name "
|
||||
"is already tied to a specific register."
|
||||
"\n\teg."
|
||||
"\n\tsls_detector_put setbit test_bit"
|
||||
"\n\tsls_detector_put clearbit test_bit"
|
||||
"\n\tsls_detector_get getbit test_bit"
|
||||
<< '\n';
|
||||
return os.str();
|
||||
}
|
||||
auto det_type = det->getDetectorType().squash();
|
||||
if (det_type != defs::XILINX_CHIPTESTBOARD &&
|
||||
det_type != defs::CHIPTESTBOARD) {
|
||||
throw RuntimeError(
|
||||
"define_bit command only supported for ctb and xilinx_ctb");
|
||||
}
|
||||
if (det_id != -1) {
|
||||
throw RuntimeError("Cannot use define at module level. Use the default "
|
||||
"multi-module level");
|
||||
}
|
||||
if (action == defs::GET_ACTION) {
|
||||
// get position from name
|
||||
if (args.size() == 1) {
|
||||
auto t = det->getBitDefinitionAddress(args[0]);
|
||||
bool found_addr = det->hasRegisterDefinition(t.address());
|
||||
if (found_addr) {
|
||||
os << '[' << det->getRegisterDefinitionName(t.address()) << ", "
|
||||
<< std::to_string(t.bitPosition()) << "]\n";
|
||||
} else {
|
||||
os << t.str() << '\n';
|
||||
}
|
||||
}
|
||||
// get name from position and address
|
||||
else if (args.size() == 2) {
|
||||
auto reg = parseAddress(args[0]);
|
||||
BitAddress addr(reg.str(), args[1]);
|
||||
try {
|
||||
auto t = det->getBitDefinitionName(addr);
|
||||
os << t << '\n';
|
||||
} catch (const RuntimeError &e) {
|
||||
std::string err_str = e.what();
|
||||
if (err_str.find("No bit definition found") !=
|
||||
std::string::npos &&
|
||||
!is_hex_or_dec_uint(args[0])) {
|
||||
err_str += " and addr = " + args[0];
|
||||
throw RuntimeError(err_str);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
} else {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 3) {
|
||||
WrongNumberOfParameters(3);
|
||||
}
|
||||
if (!is_int(args[2])) {
|
||||
throw RuntimeError("Bit position must be an integer value.");
|
||||
}
|
||||
auto name = args[0];
|
||||
auto reg = parseAddress(args[1]);
|
||||
BitAddress addr(reg.str(), args[2]);
|
||||
det->setBitDefinition(name, addr);
|
||||
os << ToString(args) << '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::definelist_reg(int action) {
|
||||
std::ostringstream os;
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "List of user-defined register definitions in shared memory."
|
||||
<< '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
throw RuntimeError("cannot put");
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
auto det_type = det->getDetectorType().squash();
|
||||
if (det_type != defs::XILINX_CHIPTESTBOARD &&
|
||||
det_type != defs::CHIPTESTBOARD) {
|
||||
throw RuntimeError(
|
||||
"definelist_reg command only supported for ctb and xilinx_ctb");
|
||||
}
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getRegisterDefinitions();
|
||||
os << '\n' << ToString(t) << '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::definelist_bit(int action) {
|
||||
std::ostringstream os;
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "List of user-defined bit definitions in shared memory." << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
throw RuntimeError("cannot put");
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
auto det_type = det->getDetectorType().squash();
|
||||
if (det_type != defs::XILINX_CHIPTESTBOARD &&
|
||||
det_type != defs::CHIPTESTBOARD) {
|
||||
throw RuntimeError(
|
||||
"definelist_bit command only supported for ctb and xilinx_ctb");
|
||||
}
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getBitDefinitions();
|
||||
os << "\n[";
|
||||
for (const auto &[key, val] : t) {
|
||||
os << key << ": ";
|
||||
bool found_addr = det->hasRegisterDefinition(val.address());
|
||||
if (found_addr) {
|
||||
os << '[' << det->getRegisterDefinitionName(val.address())
|
||||
<< ", " << std::to_string(val.bitPosition()) << "]";
|
||||
} else {
|
||||
os << val.str();
|
||||
}
|
||||
if (&key != &t.rbegin()->first) {
|
||||
os << ", ";
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
os << "]\n";
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::reg(int action) {
|
||||
std::ostringstream os;
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[address] [32 bit value][(optional)--validate]"
|
||||
"\n\tReads/writes to a 32 bit register in hex."
|
||||
"\n\tAdvanced Function!\n\tGoes to stop server. Hence, can be "
|
||||
"called while calling blocking acquire()."
|
||||
"\n\t\t Use --validate to enforce validation when writing to "
|
||||
"register."
|
||||
"\n\t[Eiger] +0x100 for only left, +0x200 for only right."
|
||||
"\n\t[Ctb][Xilinx_Ctb] Address can also be a user-defined name "
|
||||
"that was set previously using the define command."
|
||||
"\n\t\teg."
|
||||
"\n\t\tsls_detector_put reg 0x200 0xFFF --validate"
|
||||
"\n\t\tsls_detector_get reg test_reg"
|
||||
"\n\t\tsls_detector_put reg test_reg 0xFF"
|
||||
<< '\n';
|
||||
} else {
|
||||
if (action == defs::PUT_ACTION) {
|
||||
if (args.size() < 2 || args.size() > 3) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
auto validate = parseValidate();
|
||||
auto addr = parseAddress(args[0]);
|
||||
auto val = RegisterValue(args[1]);
|
||||
det->writeRegister(addr, val, validate, std::vector<int>{det_id});
|
||||
os << addr.str() << " " << val.str() << '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
auto addr = parseAddress(args[0]);
|
||||
auto t = det->readRegister(addr, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string Caller::getbit(int action) { return bitoperations(action); }
|
||||
|
||||
std::string Caller::setbit(int action) { return bitoperations(action); }
|
||||
|
||||
std::string Caller::clearbit(int action) { return bitoperations(action); }
|
||||
|
||||
std::string Caller::bitoperations(int action) {
|
||||
std::ostringstream os;
|
||||
if (action == defs::HELP_ACTION) {
|
||||
if (cmd == "getbit") {
|
||||
os << "[reg address in hex] [bit index]\n\tGets bit in address."
|
||||
<< '\n';
|
||||
} else if (cmd == "setbit") {
|
||||
os << "[reg address in hex] [bit index]\n\tSets bit in "
|
||||
"address.\n\tUse --validate to force validation."
|
||||
<< '\n';
|
||||
} else if (cmd == "clearbit") {
|
||||
os << "[reg address in hex] [bit index]\n\tClears bit in "
|
||||
"address.\n\tUse --validate to force validation."
|
||||
<< '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown command");
|
||||
}
|
||||
os << "\n\t\t[Ctb][Xilinx_Ctb] Address or bit position can also be a "
|
||||
"user-defined name that was set previously using the define "
|
||||
"command. When using bit names, avoid register name/ address as "
|
||||
"the bit name is tied to a specific register already."
|
||||
"\n\n\teg."
|
||||
"\n\tsls_detector_get getbit 0x200 2"
|
||||
"\n\tsls_detector_get getbit test_reg 2"
|
||||
"\n\tsls_detector_get getbit test_bit"
|
||||
"\n\tsls_detector_put setbit 0x200 2"
|
||||
"\n\tsls_detector_put setbit test_reg 2"
|
||||
"\n\tsls_detector_put setbit test_bit"
|
||||
"\n\tsls_detector_put clearbit test_bit";
|
||||
os << '\n';
|
||||
} else {
|
||||
if (action != defs::GET_ACTION && action != defs::PUT_ACTION) {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
|
||||
auto validate = parseValidate();
|
||||
auto BitAddress = parseBitAddress();
|
||||
if (action == defs::GET_ACTION) {
|
||||
if (cmd == "setbit" || cmd == "clearbit")
|
||||
throw RuntimeError("Cannot get");
|
||||
|
||||
auto t = det->getBit(BitAddress, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
} else {
|
||||
if (cmd == "getbit")
|
||||
throw RuntimeError("Cannot put");
|
||||
if (cmd == "setbit")
|
||||
det->setBit(BitAddress, validate, std::vector<int>{det_id});
|
||||
else if (cmd == "clearbit")
|
||||
det->clearBit(BitAddress, validate, std::vector<int>{det_id});
|
||||
else
|
||||
throw RuntimeError("Unknown command");
|
||||
os << ToString(args) << "\n";
|
||||
}
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
RegisterAddress Caller::parseAddress(const std::string &saddr) const {
|
||||
if (is_hex_or_dec_uint(saddr)) {
|
||||
return RegisterAddress(saddr);
|
||||
}
|
||||
auto det_type = det->getDetectorType().squash();
|
||||
if (det_type != defs::XILINX_CHIPTESTBOARD &&
|
||||
det_type != defs::CHIPTESTBOARD) {
|
||||
throw RuntimeError(
|
||||
"Could not parse address " + saddr +
|
||||
". User defined register definitions only supported for ctb and "
|
||||
"xilinx_ctb. Use an actual hard coded address for this detector.");
|
||||
}
|
||||
return det->getRegisterDefinitionAddress(saddr);
|
||||
}
|
||||
|
||||
bool Caller::parseValidate() {
|
||||
auto it = std::find(args.begin(), args.end(), "--validate");
|
||||
bool validate = (it != args.end());
|
||||
|
||||
// throw for any -- options other than --validate
|
||||
if (!validate) {
|
||||
auto invalid_it =
|
||||
std::find_if(args.begin(), args.end(), [](const auto &s) {
|
||||
// only looks for the first characters
|
||||
return s.rfind("--", 0) == 0 && s != "--validate";
|
||||
});
|
||||
if (invalid_it != args.end()) {
|
||||
throw RuntimeError("Unknown option '" + *invalid_it +
|
||||
"'. Did you mean '--validate'?");
|
||||
}
|
||||
}
|
||||
|
||||
// --validate should be the last argument
|
||||
else {
|
||||
if (it != args.end() - 1) {
|
||||
throw RuntimeError("'--validate' should be the last argument.");
|
||||
}
|
||||
args.pop_back();
|
||||
}
|
||||
return validate;
|
||||
}
|
||||
|
||||
BitAddress Caller::parseBitAddress() const {
|
||||
int argsSize = args.size();
|
||||
std::string addr_or_bitname = args[0];
|
||||
|
||||
// bit name
|
||||
if (argsSize == 1) {
|
||||
auto det_type = det->getDetectorType().squash();
|
||||
if (det_type != defs::XILINX_CHIPTESTBOARD &&
|
||||
det_type != defs::CHIPTESTBOARD) {
|
||||
throw RuntimeError("Could not parse bit name " + addr_or_bitname +
|
||||
". User defined bit definitions only supported "
|
||||
"for ctb and xilinx_ctb. Use an actual hard "
|
||||
"coded bit position for this detector.");
|
||||
}
|
||||
return det->getBitDefinitionAddress(addr_or_bitname);
|
||||
}
|
||||
|
||||
// address and bit position
|
||||
else if (argsSize == 2) {
|
||||
auto reg = parseAddress(addr_or_bitname);
|
||||
return BitAddress(reg.str(), args[1]);
|
||||
} else {
|
||||
throw RuntimeError("Command " + cmd +
|
||||
" expected (1-4) parameter/s but got " +
|
||||
std::to_string(args.size()) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -238,4 +238,125 @@ std::vector<std::string> CtbConfig::getSlowADCNames() const {
|
||||
|
||||
const char *CtbConfig::shm_tag() { return shm_tag_; }
|
||||
|
||||
int CtbConfig::getRegisterNamesCount() const { return num_regs; }
|
||||
|
||||
void CtbConfig::setRegisterName(const std::string &name, RegisterAddress addr) {
|
||||
addEntry<RegisterDefinition, RegisterAddress>(
|
||||
name, addr, registers, num_regs, max_regs, "register");
|
||||
}
|
||||
|
||||
bool CtbConfig::hasRegisterName(const std::string &name) const {
|
||||
return lookupEntryByName<RegisterDefinition, RegisterAddress>(
|
||||
name, registers, num_regs)
|
||||
.has_value();
|
||||
}
|
||||
|
||||
bool CtbConfig::hasRegisterAddress(RegisterAddress addr) const {
|
||||
return lookupEntryByValue<RegisterDefinition, RegisterAddress>(
|
||||
addr, registers, num_regs)
|
||||
.has_value();
|
||||
}
|
||||
|
||||
RegisterAddress CtbConfig::getRegisterAddress(const std::string &name) const {
|
||||
auto val = lookupEntryByName<RegisterDefinition, RegisterAddress>(
|
||||
name, registers, num_regs);
|
||||
if (!val.has_value()) {
|
||||
throw RuntimeError("No register definition found for name: " + name);
|
||||
}
|
||||
return val.value();
|
||||
}
|
||||
|
||||
std::string CtbConfig::getRegisterName(RegisterAddress addr) const {
|
||||
auto val = lookupEntryByValue<RegisterDefinition, RegisterAddress>(
|
||||
addr, registers, num_regs);
|
||||
if (!val.has_value()) {
|
||||
throw RuntimeError("No register definition found for address: " +
|
||||
addr.str());
|
||||
}
|
||||
return val.value();
|
||||
}
|
||||
|
||||
void CtbConfig::clearRegisterNames() {
|
||||
memset(registers, 0, sizeof(registers));
|
||||
num_regs = 0;
|
||||
}
|
||||
|
||||
void CtbConfig::setRegisterNames(
|
||||
const std::map<std::string, RegisterAddress> &list) {
|
||||
if (list.size() >= max_regs) {
|
||||
throw RuntimeError("Register names need to be of size less than " +
|
||||
std::to_string(max_regs));
|
||||
}
|
||||
clearRegisterNames();
|
||||
for (const auto &[name, value] : list) {
|
||||
setRegisterName(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, RegisterAddress> CtbConfig::getRegisterNames() const {
|
||||
std::map<std::string, RegisterAddress> names;
|
||||
for (size_t i = 0; i != num_regs; ++i)
|
||||
names[registers[i].name()] = registers[i].value();
|
||||
return names;
|
||||
}
|
||||
|
||||
int CtbConfig::getBitNamesCount() const { return num_bits; }
|
||||
|
||||
void CtbConfig::setBitName(const std::string &name, BitAddress bitPos) {
|
||||
addEntry<BitDefinition, BitAddress>(name, bitPos, bits, num_bits, max_bits,
|
||||
"bit");
|
||||
}
|
||||
|
||||
bool CtbConfig::hasBitName(const std::string &name) const {
|
||||
return lookupEntryByName<BitDefinition, BitAddress>(name, bits, num_bits)
|
||||
.has_value();
|
||||
}
|
||||
|
||||
bool CtbConfig::hasBitAddress(BitAddress bitPos) const {
|
||||
return lookupEntryByValue<BitDefinition, BitAddress>(bitPos, bits, num_bits)
|
||||
.has_value();
|
||||
}
|
||||
|
||||
BitAddress CtbConfig::getBitAddress(const std::string &name) const {
|
||||
auto val =
|
||||
lookupEntryByName<BitDefinition, BitAddress>(name, bits, num_bits);
|
||||
if (!val.has_value()) {
|
||||
throw RuntimeError("No bit definition found for name: " + name);
|
||||
}
|
||||
return val.value();
|
||||
}
|
||||
|
||||
std::string CtbConfig::getBitName(BitAddress bitPos) const {
|
||||
auto val =
|
||||
lookupEntryByValue<BitDefinition, BitAddress>(bitPos, bits, num_bits);
|
||||
if (!val.has_value()) {
|
||||
throw RuntimeError("No bit definition found for bit position: " +
|
||||
bitPos.str());
|
||||
}
|
||||
return val.value();
|
||||
}
|
||||
|
||||
void CtbConfig::clearBitNames() {
|
||||
memset(bits, 0, sizeof(bits));
|
||||
num_bits = 0;
|
||||
}
|
||||
|
||||
void CtbConfig::setBitNames(const std::map<std::string, BitAddress> &list) {
|
||||
if (list.size() >= max_bits) {
|
||||
throw RuntimeError("Bit names need to be of size less than " +
|
||||
std::to_string(max_bits));
|
||||
}
|
||||
clearBitNames();
|
||||
for (const auto &[name, value] : list) {
|
||||
setBitName(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, BitAddress> CtbConfig::getBitNames() const {
|
||||
std::map<std::string, BitAddress> names;
|
||||
for (size_t i = 0; i != num_bits; ++i)
|
||||
names[bits[i].name()] = bits[i].value();
|
||||
return names;
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,31 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/string_utils.h"
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace sls {
|
||||
|
||||
#define CTB_SHMAPIVERSION 0x250820
|
||||
#define CTB_SHMVERSION 0x250820
|
||||
inline constexpr size_t CTB_NAME_LENGTH = 32;
|
||||
|
||||
class RegisterDefinition {
|
||||
private:
|
||||
char name_[CTB_NAME_LENGTH]{};
|
||||
RegisterAddress addr_;
|
||||
|
||||
public:
|
||||
RegisterDefinition() noexcept = default;
|
||||
RegisterDefinition(const std::string &name, RegisterAddress address)
|
||||
: addr_(address) {
|
||||
if (name.empty()) {
|
||||
throw sls::RuntimeError("Register name cannot be empty.");
|
||||
}
|
||||
strcpy_checked(name_, name);
|
||||
}
|
||||
|
||||
std::string name() const noexcept { return name_; }
|
||||
RegisterAddress value() const noexcept { return addr_; }
|
||||
void setValue(RegisterAddress address) noexcept { addr_ = address; }
|
||||
};
|
||||
|
||||
class BitDefinition {
|
||||
private:
|
||||
char name_[CTB_NAME_LENGTH]{};
|
||||
BitAddress bitPos_;
|
||||
|
||||
public:
|
||||
BitDefinition() noexcept = default;
|
||||
BitDefinition(const std::string &name, BitAddress bitPos)
|
||||
: bitPos_(bitPos) {
|
||||
if (name.empty()) {
|
||||
throw sls::RuntimeError("Bit name cannot be empty.");
|
||||
}
|
||||
strcpy_checked(name_, name);
|
||||
}
|
||||
|
||||
std::string name() const noexcept { return name_; }
|
||||
BitAddress value() const noexcept { return bitPos_; }
|
||||
void setValue(BitAddress bitPos) noexcept { bitPos_ = bitPos; }
|
||||
};
|
||||
|
||||
class CtbConfig {
|
||||
public:
|
||||
/** fixed pattern */
|
||||
int shmversion{CTB_SHMVERSION};
|
||||
static constexpr int SHM_VERSION = 0x251215;
|
||||
int shmversion{SHM_VERSION};
|
||||
bool isValid{true}; // false if freed to block access from python or c++ api
|
||||
/** end of fixed pattern */
|
||||
|
||||
private:
|
||||
static constexpr size_t name_length = 20;
|
||||
static constexpr const char *shm_tag_ = "ctbdacs";
|
||||
static constexpr size_t name_length = CTB_NAME_LENGTH;
|
||||
static constexpr size_t num_dacs = 18;
|
||||
static constexpr size_t num_adcs = 32;
|
||||
static constexpr size_t num_signals = 64;
|
||||
static constexpr size_t num_powers = 5;
|
||||
static constexpr size_t num_slowADCs = 8;
|
||||
static constexpr const char *shm_tag_ = "ctbdacs";
|
||||
char dacnames[name_length * num_dacs]{};
|
||||
char adcnames[name_length * num_adcs]{};
|
||||
char signalnames[name_length * num_signals]{};
|
||||
char powernames[name_length * num_powers]{};
|
||||
char slowADCnames[name_length * num_slowADCs]{};
|
||||
|
||||
static constexpr size_t max_regs = 64;
|
||||
static constexpr size_t max_bits = 64;
|
||||
size_t num_regs{0};
|
||||
size_t num_bits{0};
|
||||
RegisterDefinition registers[max_regs];
|
||||
BitDefinition bits[max_bits];
|
||||
|
||||
void check_dac_index(size_t i) const;
|
||||
void check_adc_index(size_t i) const;
|
||||
void check_signal_index(size_t i) const;
|
||||
@@ -33,12 +90,99 @@ class CtbConfig {
|
||||
void check_slow_adc_index(size_t i) const;
|
||||
void check_size(const std::string &name) const;
|
||||
|
||||
template <typename T>
|
||||
std::optional<T *> findEntryByName(const std::string &name, T *array,
|
||||
size_t count) {
|
||||
auto it = std::find_if(array, array + count,
|
||||
[&name](T &e) { return (e.name() == name); });
|
||||
|
||||
if (it != array + count)
|
||||
return it;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<const T *> findEntryByName(const std::string &name,
|
||||
const T *array,
|
||||
size_t count) const {
|
||||
auto it = std::find_if(array, array + count, [&name](const T &e) {
|
||||
return (e.name() == name);
|
||||
});
|
||||
|
||||
if (it != array + count)
|
||||
return it;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T, typename Tval>
|
||||
std::optional<T *> findEntryByValue(Tval value, T *array, size_t count) {
|
||||
auto it = std::find_if(array, array + count,
|
||||
[&value](T &e) { return e.value() == value; });
|
||||
|
||||
if (it != array + count)
|
||||
return it;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T, typename Tval>
|
||||
std::optional<const T *> findEntryByValue(Tval value, const T *array,
|
||||
size_t count) const {
|
||||
auto it = std::find_if(array, array + count, [&value](const T &e) {
|
||||
return e.value() == value;
|
||||
});
|
||||
|
||||
if (it != array + count)
|
||||
return it;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T, typename Tval>
|
||||
std::optional<const Tval> lookupEntryByName(const std::string &name,
|
||||
const T *array,
|
||||
size_t count) const {
|
||||
auto entry = findEntryByName<T>(name, array, count);
|
||||
return (entry ? std::optional<Tval>((*entry)->value()) : std::nullopt);
|
||||
}
|
||||
|
||||
template <typename T, typename Tval>
|
||||
std::optional<std::string> lookupEntryByValue(Tval value, const T *array,
|
||||
size_t count) const {
|
||||
auto entry = findEntryByValue<T>(value, array, count);
|
||||
return (entry ? std::optional<std::string>((*entry)->name())
|
||||
: std::nullopt);
|
||||
}
|
||||
|
||||
template <typename T, typename Tval>
|
||||
void addEntry(const std::string &name, Tval value, T *array, size_t &count,
|
||||
size_t max_count, const std::string &type_name) {
|
||||
check_size(name);
|
||||
|
||||
// exists: overwrite value
|
||||
if (auto entry = findEntryByName<T>(name, array, count)) {
|
||||
(*entry)->setValue(value);
|
||||
return;
|
||||
}
|
||||
|
||||
// check size
|
||||
if (count >= max_count) {
|
||||
throw RuntimeError("Maximum number of " + type_name +
|
||||
" reached. Clear shared memory and try again.");
|
||||
}
|
||||
|
||||
// check value exists
|
||||
if (auto entry = findEntryByValue<T>(value, array, count)) {
|
||||
throw RuntimeError(value.str() + " already assigned to " +
|
||||
type_name + " '" + (*entry)->name() +
|
||||
"'. Cannot assign to '" + name + "'");
|
||||
}
|
||||
|
||||
// add new entry
|
||||
array[count] = T(name, value);
|
||||
++(count);
|
||||
}
|
||||
|
||||
public:
|
||||
CtbConfig();
|
||||
CtbConfig(const CtbConfig &) = default;
|
||||
CtbConfig(CtbConfig &&) = default;
|
||||
CtbConfig &operator=(const CtbConfig &) = default;
|
||||
~CtbConfig() = default;
|
||||
|
||||
void setDacNames(const std::vector<std::string> &names);
|
||||
void setDacName(size_t index, const std::string &name);
|
||||
@@ -65,6 +209,26 @@ class CtbConfig {
|
||||
std::string getSlowADCName(size_t index) const;
|
||||
std::vector<std::string> getSlowADCNames() const;
|
||||
static const char *shm_tag();
|
||||
|
||||
int getRegisterNamesCount() const;
|
||||
void setRegisterName(const std::string &name, RegisterAddress addr);
|
||||
bool hasRegisterName(const std::string &name) const;
|
||||
bool hasRegisterAddress(RegisterAddress addr) const;
|
||||
RegisterAddress getRegisterAddress(const std::string &name) const;
|
||||
std::string getRegisterName(RegisterAddress addr) const;
|
||||
void clearRegisterNames();
|
||||
void setRegisterNames(const std::map<std::string, RegisterAddress> &list);
|
||||
std::map<std::string, RegisterAddress> getRegisterNames() const;
|
||||
|
||||
int getBitNamesCount() const;
|
||||
void setBitName(const std::string &name, BitAddress bitPos);
|
||||
bool hasBitName(const std::string &name) const;
|
||||
bool hasBitAddress(BitAddress bitPos) const;
|
||||
BitAddress getBitAddress(const std::string &name) const;
|
||||
std::string getBitName(BitAddress bitPos) const;
|
||||
void clearBitNames();
|
||||
void setBitNames(const std::map<std::string, BitAddress> &list);
|
||||
std::map<std::string, BitAddress> getBitNames() const;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
|
||||
@@ -2377,26 +2377,21 @@ void Detector::setLEDEnable(bool enable, Positions pos) {
|
||||
}
|
||||
|
||||
void Detector::setDacNames(const std::vector<std::string> names) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named dacs only for CTB");
|
||||
pimpl->setCtbDacNames(names);
|
||||
}
|
||||
|
||||
std::vector<std::string> Detector::getDacNames() const {
|
||||
std::vector<std::string> names;
|
||||
auto type = getDetectorType().squash();
|
||||
if (type == defs::CHIPTESTBOARD || type == defs::XILINX_CHIPTESTBOARD)
|
||||
if (pimpl->isChipTestBoard())
|
||||
return pimpl->getCtbDacNames();
|
||||
|
||||
std::vector<std::string> names;
|
||||
for (const auto &index : getDacList())
|
||||
names.push_back(ToString(index));
|
||||
return names;
|
||||
}
|
||||
|
||||
defs::dacIndex Detector::getDacIndex(const std::string &name) const {
|
||||
auto type = getDetectorType().squash();
|
||||
if (type == defs::CHIPTESTBOARD || type == defs::XILINX_CHIPTESTBOARD) {
|
||||
if (pimpl->isChipTestBoard()) {
|
||||
auto names = getDacNames();
|
||||
auto it = std::find(names.begin(), names.end(), name);
|
||||
if (it == names.end())
|
||||
@@ -2407,37 +2402,24 @@ defs::dacIndex Detector::getDacIndex(const std::string &name) const {
|
||||
}
|
||||
|
||||
void Detector::setDacName(const defs::dacIndex i, const std::string &name) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named dacs only for CTB");
|
||||
pimpl->setCtbDacName(i, name);
|
||||
}
|
||||
|
||||
std::string Detector::getDacName(const defs::dacIndex i) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype == defs::CHIPTESTBOARD || dettype == defs::XILINX_CHIPTESTBOARD)
|
||||
if (pimpl->isChipTestBoard())
|
||||
return pimpl->getCtbDacName(i);
|
||||
return ToString(i);
|
||||
}
|
||||
|
||||
void Detector::setAdcNames(const std::vector<std::string> names) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named adcs only for CTB");
|
||||
pimpl->setCtbAdcNames(names);
|
||||
}
|
||||
|
||||
std::vector<std::string> Detector::getAdcNames() const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named adcs only for CTB");
|
||||
return pimpl->getCtbAdcNames();
|
||||
}
|
||||
|
||||
int Detector::getAdcIndex(const std::string &name) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named adcs only for CTB");
|
||||
auto names = getAdcNames();
|
||||
auto it = std::find(names.begin(), names.end(), name);
|
||||
if (it == names.end())
|
||||
@@ -2446,37 +2428,22 @@ int Detector::getAdcIndex(const std::string &name) const {
|
||||
}
|
||||
|
||||
void Detector::setAdcName(const int index, const std::string &name) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named adcs only for CTB");
|
||||
pimpl->setCtbAdcName(index, name);
|
||||
}
|
||||
|
||||
std::string Detector::getAdcName(const int i) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named adcs only for CTB");
|
||||
return pimpl->getCtbAdcName(i);
|
||||
}
|
||||
|
||||
void Detector::setSignalNames(const std::vector<std::string> names) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
pimpl->setCtbSignalNames(names);
|
||||
}
|
||||
|
||||
std::vector<std::string> Detector::getSignalNames() const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
return pimpl->getCtbSignalNames();
|
||||
}
|
||||
|
||||
int Detector::getSignalIndex(const std::string &name) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
auto names = getSignalNames();
|
||||
auto it = std::find(names.begin(), names.end(), name);
|
||||
if (it == names.end())
|
||||
@@ -2485,38 +2452,22 @@ int Detector::getSignalIndex(const std::string &name) const {
|
||||
}
|
||||
|
||||
void Detector::setSignalName(const int index, const std::string &name) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
pimpl->setCtbSignalName(index, name);
|
||||
}
|
||||
|
||||
std::string Detector::getSignalName(const int i) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
return pimpl->getCtbSignalName(i);
|
||||
}
|
||||
|
||||
void Detector::setPowerNames(const std::vector<std::string> names) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (getDetectorType().squash() != defs::CHIPTESTBOARD &&
|
||||
dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named powers only for CTB");
|
||||
pimpl->setCtbPowerNames(names);
|
||||
}
|
||||
|
||||
std::vector<std::string> Detector::getPowerNames() const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named powers only for CTB");
|
||||
return pimpl->getCtbPowerNames();
|
||||
}
|
||||
|
||||
defs::dacIndex Detector::getPowerIndex(const std::string &name) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named powers only for CTB");
|
||||
auto names = getPowerNames();
|
||||
auto it = std::find(names.begin(), names.end(), name);
|
||||
if (it == names.end())
|
||||
@@ -2526,37 +2477,22 @@ defs::dacIndex Detector::getPowerIndex(const std::string &name) const {
|
||||
|
||||
void Detector::setPowerName(const defs::dacIndex index,
|
||||
const std::string &name) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named powers only for CTB");
|
||||
pimpl->setCtbPowerName(index, name);
|
||||
}
|
||||
|
||||
std::string Detector::getPowerName(const defs::dacIndex i) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named powers only for CTB");
|
||||
return pimpl->getCtbPowerName(i);
|
||||
}
|
||||
|
||||
void Detector::setSlowADCNames(const std::vector<std::string> names) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named SlowADCs only for CTB");
|
||||
pimpl->setCtbSlowADCNames(names);
|
||||
}
|
||||
|
||||
std::vector<std::string> Detector::getSlowADCNames() const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named SlowADCs only for CTB");
|
||||
return pimpl->getCtbSlowADCNames();
|
||||
}
|
||||
|
||||
defs::dacIndex Detector::getSlowADCIndex(const std::string &name) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named SlowADCs only for CTB");
|
||||
auto names = getSlowADCNames();
|
||||
auto it = std::find(names.begin(), names.end(), name);
|
||||
if (it == names.end())
|
||||
@@ -2566,19 +2502,86 @@ defs::dacIndex Detector::getSlowADCIndex(const std::string &name) const {
|
||||
|
||||
void Detector::setSlowADCName(const defs::dacIndex index,
|
||||
const std::string &name) {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named SlowADCs only for CTB");
|
||||
pimpl->setCtbSlowADCName(index, name);
|
||||
}
|
||||
|
||||
std::string Detector::getSlowADCName(const defs::dacIndex i) const {
|
||||
auto dettype = getDetectorType().squash();
|
||||
if (dettype != defs::CHIPTESTBOARD && dettype != defs::XILINX_CHIPTESTBOARD)
|
||||
throw RuntimeError("Named SlowADCs only for CTB");
|
||||
return pimpl->getCtbSlowADCName(i);
|
||||
}
|
||||
|
||||
int Detector::getRegisterDefinitionsCount() const {
|
||||
return pimpl->getRegisterDefinitionsCount();
|
||||
}
|
||||
|
||||
void Detector::setRegisterDefinition(const std::string &name,
|
||||
RegisterAddress addr) {
|
||||
pimpl->setRegisterDefinition(name, addr);
|
||||
}
|
||||
|
||||
bool Detector::hasRegisterDefinition(const std::string &name) const {
|
||||
return pimpl->hasRegisterDefinition(name);
|
||||
}
|
||||
|
||||
bool Detector::hasRegisterDefinition(RegisterAddress addr) const {
|
||||
return pimpl->hasRegisterDefinition(addr);
|
||||
}
|
||||
|
||||
RegisterAddress
|
||||
Detector::getRegisterDefinitionAddress(const std::string &name) const {
|
||||
return pimpl->getRegisterDefinitionAddress(name);
|
||||
}
|
||||
|
||||
std::string Detector::getRegisterDefinitionName(RegisterAddress addr) const {
|
||||
return pimpl->getRegisterDefinitionName(addr);
|
||||
}
|
||||
|
||||
void Detector::clearRegisterDefinitions() { pimpl->clearRegisterDefinitions(); }
|
||||
|
||||
void Detector::setRegisterDefinitions(
|
||||
const std::map<std::string, RegisterAddress> &list) {
|
||||
pimpl->setRegisterDefinitions(list);
|
||||
}
|
||||
|
||||
std::map<std::string, RegisterAddress>
|
||||
Detector::getRegisterDefinitions() const {
|
||||
return pimpl->getRegisterDefinitions();
|
||||
}
|
||||
|
||||
int Detector::getBitDefinitionsCount() const {
|
||||
return pimpl->getBitDefinitionsCount();
|
||||
}
|
||||
|
||||
void Detector::setBitDefinition(const std::string &name, BitAddress addr) {
|
||||
pimpl->setBitDefinition(name, addr);
|
||||
}
|
||||
|
||||
bool Detector::hasBitDefinition(const std::string &name) const {
|
||||
return pimpl->hasBitDefinition(name);
|
||||
}
|
||||
|
||||
bool Detector::hasBitDefinition(BitAddress addr) const {
|
||||
return pimpl->hasBitDefinition(addr);
|
||||
}
|
||||
|
||||
BitAddress Detector::getBitDefinitionAddress(const std::string &name) const {
|
||||
return pimpl->getBitDefinitionAddress(name);
|
||||
}
|
||||
|
||||
std::string Detector::getBitDefinitionName(BitAddress addr) const {
|
||||
return pimpl->getBitDefinitionName(addr);
|
||||
}
|
||||
|
||||
void Detector::clearBitDefinitions() { pimpl->clearBitDefinitions(); }
|
||||
|
||||
void Detector::setBitDefinitions(
|
||||
const std::map<std::string, BitAddress> &list) {
|
||||
pimpl->setBitDefinitions(list);
|
||||
}
|
||||
|
||||
std::map<std::string, BitAddress> Detector::getBitDefinitions() const {
|
||||
return pimpl->getBitDefinitions();
|
||||
}
|
||||
|
||||
// Xilinx Ctb Specific
|
||||
|
||||
void Detector::configureTransceiver(Positions pos) {
|
||||
@@ -2782,26 +2785,78 @@ void Detector::setUpdateMode(const bool updatemode, Positions pos) {
|
||||
}
|
||||
}
|
||||
|
||||
Result<RegisterValue> Detector::readRegister(RegisterAddress addr,
|
||||
Positions pos) const {
|
||||
return pimpl->readRegister(addr, pos);
|
||||
}
|
||||
|
||||
void Detector::writeRegister(RegisterAddress addr, RegisterValue val,
|
||||
bool validate, Positions pos) {
|
||||
pimpl->writeRegister(addr, val, validate, pos);
|
||||
}
|
||||
|
||||
void Detector::setBit(BitAddress addr, bool validate, Positions pos) {
|
||||
pimpl->setBit(addr, validate, pos);
|
||||
}
|
||||
|
||||
void Detector::clearBit(BitAddress addr, bool validate, Positions pos) {
|
||||
pimpl->clearBit(addr, validate, pos);
|
||||
}
|
||||
|
||||
Result<int> Detector::getBit(BitAddress addr, Positions pos) const {
|
||||
return pimpl->getBit(addr, pos);
|
||||
}
|
||||
|
||||
Result<RegisterValue> Detector::readRegister(const std::string ®_name,
|
||||
Positions pos) const {
|
||||
return pimpl->readRegister(reg_name, pos);
|
||||
}
|
||||
|
||||
void Detector::writeRegister(const std::string ®_name, RegisterValue val,
|
||||
bool validate, Positions pos) {
|
||||
pimpl->writeRegister(reg_name, val, validate, pos);
|
||||
}
|
||||
|
||||
void Detector::setBit(const std::string &bit_name, bool validate,
|
||||
Positions pos) {
|
||||
pimpl->setBit(bit_name, validate, pos);
|
||||
}
|
||||
|
||||
void Detector::clearBit(const std::string &bit_name, bool validate,
|
||||
Positions pos) {
|
||||
pimpl->clearBit(bit_name, validate, pos);
|
||||
}
|
||||
|
||||
Result<int> Detector::getBit(const std::string &bit_name, Positions pos) const {
|
||||
return pimpl->getBit(bit_name, pos);
|
||||
}
|
||||
|
||||
Result<uint32_t> Detector::readRegister(uint32_t addr, Positions pos) const {
|
||||
return pimpl->Parallel(&Module::readRegister, pos, addr);
|
||||
auto t = pimpl->readRegister(RegisterAddress(addr), pos);
|
||||
Result<uint32_t> res;
|
||||
for (const auto &val : t) {
|
||||
res.push_back(val.value());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void Detector::writeRegister(uint32_t addr, uint32_t val, bool validate,
|
||||
Positions pos) {
|
||||
pimpl->Parallel(&Module::writeRegister, pos, addr, val, validate);
|
||||
pimpl->writeRegister(RegisterAddress(addr), RegisterValue(val), validate,
|
||||
pos);
|
||||
}
|
||||
|
||||
void Detector::setBit(uint32_t addr, int bitnr, bool validate, Positions pos) {
|
||||
pimpl->Parallel(&Module::setBit, pos, addr, bitnr, validate);
|
||||
pimpl->setBit(BitAddress(RegisterAddress(addr), bitnr), validate, pos);
|
||||
}
|
||||
|
||||
void Detector::clearBit(uint32_t addr, int bitnr, bool validate,
|
||||
Positions pos) {
|
||||
pimpl->Parallel(&Module::clearBit, pos, addr, bitnr, validate);
|
||||
pimpl->clearBit(BitAddress(RegisterAddress(addr), bitnr), validate, pos);
|
||||
}
|
||||
|
||||
Result<int> Detector::getBit(uint32_t addr, int bitnr, Positions pos) {
|
||||
return pimpl->Parallel(&Module::getBit, pos, addr, bitnr);
|
||||
Result<int> Detector::getBit(uint32_t addr, int bitnr, Positions pos) const {
|
||||
return pimpl->getBit(BitAddress(RegisterAddress(addr), bitnr), pos);
|
||||
}
|
||||
|
||||
void Detector::executeFirmwareTest(Positions pos) {
|
||||
|
||||
@@ -80,10 +80,10 @@ void DetectorImpl::initSharedMemory() {
|
||||
}
|
||||
if (ctb_shm.exists()) {
|
||||
ctb_shm.openSharedMemory(true);
|
||||
if (ctb_shm()->shmversion != CTB_SHMVERSION) {
|
||||
if (ctb_shm()->shmversion != CtbConfig::SHM_VERSION) {
|
||||
LOG(logERROR)
|
||||
<< "CTB shared memory version mismatch (expected 0x"
|
||||
<< std::hex << CTB_SHMVERSION << " but got 0x"
|
||||
<< std::hex << CtbConfig::SHM_VERSION << " but got 0x"
|
||||
<< ctb_shm()->shmversion << std::dec
|
||||
<< ". Free Shared memory to continue.";
|
||||
ctb_shm.unmapSharedMemory();
|
||||
@@ -1935,86 +1935,314 @@ void DetectorImpl::setBadChannels(const std::vector<int> list, Positions pos) {
|
||||
}
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbDacNames() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named DACs only for CTB");
|
||||
return ctb_shm()->getDacNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbDacNames(const std::vector<std::string> &names) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named DACs only for CTB");
|
||||
ctb_shm()->setDacNames(names);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getCtbDacName(defs::dacIndex i) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named DACs only for CTB");
|
||||
return ctb_shm()->getDacName(static_cast<int>(i));
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbDacName(const defs::dacIndex index,
|
||||
const std::string &name) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named DACs only for CTB");
|
||||
ctb_shm()->setDacName(index, name);
|
||||
}
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbAdcNames() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named ADCs only for CTB");
|
||||
return ctb_shm()->getAdcNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbAdcNames(const std::vector<std::string> &names) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named ADCs only for CTB");
|
||||
ctb_shm()->setAdcNames(names);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getCtbAdcName(const int i) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named ADCs only for CTB");
|
||||
return ctb_shm()->getAdcName(i);
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbAdcName(const int index, const std::string &name) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named ADCs only for CTB");
|
||||
ctb_shm()->setAdcName(index, name);
|
||||
}
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbSignalNames() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
return ctb_shm()->getSignalNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbSignalNames(const std::vector<std::string> &names) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
ctb_shm()->setSignalNames(names);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getCtbSignalName(const int i) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
return ctb_shm()->getSignalName(i);
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbSignalName(const int index, const std::string &name) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named signals only for CTB");
|
||||
ctb_shm()->setSignalName(index, name);
|
||||
}
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbPowerNames() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Powers only for CTB");
|
||||
return ctb_shm()->getPowerNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbPowerNames(const std::vector<std::string> &names) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Powers only for CTB");
|
||||
ctb_shm()->setPowerNames(names);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getCtbPowerName(const defs::dacIndex i) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Powers only for CTB");
|
||||
return ctb_shm()->getPowerName(static_cast<int>(i - defs::V_POWER_A));
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbPowerName(const defs::dacIndex index,
|
||||
const std::string &name) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Powers only for CTB");
|
||||
ctb_shm()->setPowerName(static_cast<int>(index - defs::V_POWER_A), name);
|
||||
}
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbSlowADCNames() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Slow ADCs only for CTB");
|
||||
return ctb_shm()->getSlowADCNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbSlowADCNames(const std::vector<std::string> &names) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Slow ADCs only for CTB");
|
||||
ctb_shm()->setSlowADCNames(names);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getCtbSlowADCName(const defs::dacIndex i) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Slow ADCs only for CTB");
|
||||
return ctb_shm()->getSlowADCName(static_cast<int>(i - defs::SLOW_ADC0));
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbSlowADCName(const defs::dacIndex index,
|
||||
const std::string &name) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Named Slow ADCs only for CTB");
|
||||
ctb_shm()->setSlowADCName(static_cast<int>(index - defs::SLOW_ADC0), name);
|
||||
}
|
||||
|
||||
int DetectorImpl::getRegisterDefinitionsCount() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
return ctb_shm()->getRegisterNamesCount();
|
||||
}
|
||||
|
||||
void DetectorImpl::setRegisterDefinition(const std::string &name,
|
||||
RegisterAddress addr) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
ctb_shm()->setRegisterName(name, addr);
|
||||
}
|
||||
|
||||
bool DetectorImpl::hasRegisterDefinition(const std::string &name) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
return ctb_shm()->hasRegisterName(name);
|
||||
}
|
||||
|
||||
bool DetectorImpl::hasRegisterDefinition(RegisterAddress addr) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
return ctb_shm()->hasRegisterAddress(addr);
|
||||
}
|
||||
|
||||
RegisterAddress
|
||||
DetectorImpl::getRegisterDefinitionAddress(const std::string &name) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
return ctb_shm()->getRegisterAddress(name);
|
||||
}
|
||||
|
||||
std::string
|
||||
DetectorImpl::getRegisterDefinitionName(RegisterAddress addr) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
return ctb_shm()->getRegisterName(addr);
|
||||
}
|
||||
|
||||
void DetectorImpl::clearRegisterDefinitions() {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
ctb_shm()->clearRegisterNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setRegisterDefinitions(
|
||||
const std::map<std::string, RegisterAddress> &list) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
ctb_shm()->setRegisterNames(list);
|
||||
}
|
||||
|
||||
std::map<std::string, RegisterAddress>
|
||||
DetectorImpl::getRegisterDefinitions() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Register Definitions only for CTB");
|
||||
return ctb_shm()->getRegisterNames();
|
||||
}
|
||||
|
||||
int DetectorImpl::getBitDefinitionsCount() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
return ctb_shm()->getBitNamesCount();
|
||||
}
|
||||
|
||||
void DetectorImpl::setBitDefinition(const std::string &name,
|
||||
BitAddress bitPos) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
ctb_shm()->setBitName(name, bitPos);
|
||||
}
|
||||
|
||||
bool DetectorImpl::hasBitDefinition(const std::string &name) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
return ctb_shm()->hasBitName(name);
|
||||
}
|
||||
|
||||
bool DetectorImpl::hasBitDefinition(BitAddress bitPos) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
return ctb_shm()->hasBitAddress(bitPos);
|
||||
}
|
||||
|
||||
BitAddress
|
||||
DetectorImpl::getBitDefinitionAddress(const std::string &name) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
return ctb_shm()->getBitAddress(name);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getBitDefinitionName(BitAddress bitPos) const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
return ctb_shm()->getBitName(bitPos);
|
||||
}
|
||||
|
||||
void DetectorImpl::clearBitDefinitions() {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
ctb_shm()->clearBitNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setBitDefinitions(
|
||||
const std::map<std::string, BitAddress> &list) {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
ctb_shm()->setBitNames(list);
|
||||
}
|
||||
|
||||
std::map<std::string, BitAddress> DetectorImpl::getBitDefinitions() const {
|
||||
if (!isChipTestBoard())
|
||||
throw RuntimeError("Bit Definitions only for CTB");
|
||||
return ctb_shm()->getBitNames();
|
||||
}
|
||||
|
||||
Result<RegisterValue> DetectorImpl::readRegister(const std::string ®_name,
|
||||
Positions pos) const {
|
||||
if (!isChipTestBoard()) {
|
||||
throw RuntimeError("Register Definitions only for CTB. Use hard coded "
|
||||
"values instead.");
|
||||
}
|
||||
auto addr = getRegisterDefinitionAddress(reg_name);
|
||||
return readRegister(addr, pos);
|
||||
}
|
||||
|
||||
void DetectorImpl::writeRegister(const std::string ®_name, RegisterValue val,
|
||||
bool validate, Positions pos) {
|
||||
if (!isChipTestBoard()) {
|
||||
throw RuntimeError("Register Definitions only for CTB. Use hard coded "
|
||||
"values instead.");
|
||||
}
|
||||
auto addr = getRegisterDefinitionAddress(reg_name);
|
||||
writeRegister(addr, val, validate, pos);
|
||||
}
|
||||
|
||||
void DetectorImpl::setBit(const std::string &bit_name, bool validate,
|
||||
Positions pos) {
|
||||
if (!isChipTestBoard()) {
|
||||
throw RuntimeError(
|
||||
"Bit Definitions only for CTB. Use hard coded values instead.");
|
||||
}
|
||||
auto addr = getBitDefinitionAddress(bit_name);
|
||||
setBit(addr, validate, pos);
|
||||
}
|
||||
|
||||
void DetectorImpl::clearBit(const std::string &bit_name, bool validate,
|
||||
Positions pos) {
|
||||
if (!isChipTestBoard()) {
|
||||
throw RuntimeError(
|
||||
"Bit Definitions only for CTB. Use hard coded values instead.");
|
||||
}
|
||||
auto addr = getBitDefinitionAddress(bit_name);
|
||||
clearBit(addr, validate, pos);
|
||||
}
|
||||
|
||||
Result<int> DetectorImpl::getBit(const std::string &bit_name,
|
||||
Positions pos) const {
|
||||
if (!isChipTestBoard()) {
|
||||
throw RuntimeError(
|
||||
"Bit Definitions only for CTB. Use hard coded values instead.");
|
||||
}
|
||||
auto addr = getBitDefinitionAddress(bit_name);
|
||||
return getBit(addr, pos);
|
||||
}
|
||||
|
||||
Result<RegisterValue> DetectorImpl::readRegister(RegisterAddress addr,
|
||||
Positions pos) const {
|
||||
return Parallel(&Module::readRegister, pos, addr);
|
||||
}
|
||||
|
||||
void DetectorImpl::writeRegister(RegisterAddress addr, RegisterValue val,
|
||||
bool validate, Positions pos) {
|
||||
Parallel(&Module::writeRegister, pos, addr, val, validate);
|
||||
}
|
||||
|
||||
void DetectorImpl::setBit(BitAddress addr, bool validate, Positions pos) {
|
||||
Parallel(&Module::setBit, pos, addr, validate);
|
||||
}
|
||||
|
||||
void DetectorImpl::clearBit(BitAddress addr, bool validate, Positions pos) {
|
||||
Parallel(&Module::clearBit, pos, addr, validate);
|
||||
}
|
||||
|
||||
Result<int> DetectorImpl::getBit(BitAddress addr, Positions pos) const {
|
||||
return Parallel(&Module::getBit, pos, addr);
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -183,6 +183,11 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
|
||||
bool isAllPositions(Positions pos) const;
|
||||
|
||||
inline bool isChipTestBoard() const {
|
||||
return (shm()->detType == defs::CHIPTESTBOARD ||
|
||||
shm()->detType == defs::XILINX_CHIPTESTBOARD);
|
||||
}
|
||||
|
||||
/** set acquiring flag in shared memory */
|
||||
void setAcquiringFlag(bool flag);
|
||||
|
||||
@@ -328,6 +333,42 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
void setCtbSlowADCNames(const std::vector<std::string> &names);
|
||||
void setCtbSlowADCName(const defs::dacIndex index, const std::string &name);
|
||||
|
||||
int getRegisterDefinitionsCount() const;
|
||||
void setRegisterDefinition(const std::string &name, RegisterAddress addr);
|
||||
bool hasRegisterDefinition(const std::string &name) const;
|
||||
bool hasRegisterDefinition(RegisterAddress addr) const;
|
||||
RegisterAddress getRegisterDefinitionAddress(const std::string &name) const;
|
||||
std::string getRegisterDefinitionName(RegisterAddress addr) const;
|
||||
void clearRegisterDefinitions();
|
||||
void
|
||||
setRegisterDefinitions(const std::map<std::string, RegisterAddress> &list);
|
||||
std::map<std::string, RegisterAddress> getRegisterDefinitions() const;
|
||||
int getBitDefinitionsCount() const;
|
||||
void setBitDefinition(const std::string &name, BitAddress bitPos);
|
||||
bool hasBitDefinition(const std::string &name) const;
|
||||
bool hasBitDefinition(BitAddress bitPos) const;
|
||||
BitAddress getBitDefinitionAddress(const std::string &name) const;
|
||||
std::string getBitDefinitionName(BitAddress bitPos) const;
|
||||
void clearBitDefinitions();
|
||||
void setBitDefinitions(const std::map<std::string, BitAddress> &list);
|
||||
std::map<std::string, BitAddress> getBitDefinitions() const;
|
||||
|
||||
Result<RegisterValue> readRegister(const std::string ®_name,
|
||||
Positions pos) const;
|
||||
void writeRegister(const std::string ®_name, RegisterValue val,
|
||||
bool validate, Positions pos);
|
||||
void setBit(const std::string &bit_name, bool validate, Positions pos);
|
||||
void clearBit(const std::string &bit_name, bool validate, Positions pos);
|
||||
Result<int> getBit(const std::string &bit_name, Positions pos) const;
|
||||
|
||||
Result<RegisterValue> readRegister(RegisterAddress addr,
|
||||
Positions pos = {}) const;
|
||||
void writeRegister(RegisterAddress addr, RegisterValue val,
|
||||
bool validate = false, Positions pos = {});
|
||||
void setBit(BitAddress addr, bool validate = false, Positions pos = {});
|
||||
void clearBit(BitAddress addr, bool validate = false, Positions pos = {});
|
||||
Result<int> getBit(BitAddress addr, Positions pos = {}) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Creates/open shared memory, initializes detector structure and members
|
||||
|
||||
@@ -2568,17 +2568,16 @@ std::vector<int> Module::getReceiverDbitList() const {
|
||||
|
||||
void Module::setReceiverDbitList(std::vector<int> list) {
|
||||
LOG(logDEBUG1) << "Setting Receiver Dbit List";
|
||||
if (list.size() > 64) {
|
||||
throw RuntimeError("Dbit list size cannot be greater than 64\n");
|
||||
}
|
||||
|
||||
for (auto &it : list) {
|
||||
if (it < 0 || it > 63) {
|
||||
throw RuntimeError("Dbit list value must be between 0 and 63\n");
|
||||
}
|
||||
}
|
||||
std::sort(begin(list), end(list));
|
||||
auto last = std::unique(begin(list), end(list));
|
||||
list.erase(last, list.end());
|
||||
auto r = stableRemoveDuplicates(list);
|
||||
if (r) {
|
||||
LOG(logWARNING) << "Removed duplicated from receiver dbit list";
|
||||
}
|
||||
|
||||
StaticVector<int, MAX_RX_DBIT> arg = list;
|
||||
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);
|
||||
@@ -2916,29 +2915,30 @@ void Module::setUpdateMode(const bool updatemode) {
|
||||
<< "): Update Mode set to " << updatemode << "!";
|
||||
}
|
||||
|
||||
uint32_t Module::readRegister(uint32_t addr) const {
|
||||
return sendToDetectorStop<uint32_t>(F_READ_REGISTER, addr);
|
||||
RegisterValue Module::readRegister(RegisterAddress addr) const {
|
||||
return sendToDetectorStop<RegisterValue>(F_READ_REGISTER, addr.value());
|
||||
}
|
||||
|
||||
void Module::writeRegister(uint32_t addr, uint32_t val, bool validate) {
|
||||
uint32_t args[]{addr, val, static_cast<uint32_t>(validate)};
|
||||
void Module::writeRegister(RegisterAddress addr, RegisterValue val,
|
||||
bool validate) {
|
||||
uint32_t args[]{addr.value(), val.value(), static_cast<uint32_t>(validate)};
|
||||
return sendToDetectorStop(F_WRITE_REGISTER, args, nullptr);
|
||||
}
|
||||
|
||||
void Module::setBit(uint32_t addr, int n, bool validate) {
|
||||
uint32_t args[] = {addr, static_cast<uint32_t>(n),
|
||||
void Module::setBit(BitAddress bitAddr, bool validate) {
|
||||
uint32_t args[] = {bitAddr.address().value(), bitAddr.bitPosition(),
|
||||
static_cast<uint32_t>(validate)};
|
||||
sendToDetectorStop(F_SET_BIT, args, nullptr);
|
||||
}
|
||||
|
||||
void Module::clearBit(uint32_t addr, int n, bool validate) {
|
||||
uint32_t args[] = {addr, static_cast<uint32_t>(n),
|
||||
void Module::clearBit(BitAddress bitAddr, bool validate) {
|
||||
uint32_t args[] = {bitAddr.address().value(), bitAddr.bitPosition(),
|
||||
static_cast<uint32_t>(validate)};
|
||||
sendToDetectorStop(F_CLEAR_BIT, args, nullptr);
|
||||
}
|
||||
|
||||
int Module::getBit(uint32_t addr, int n) {
|
||||
uint32_t args[2] = {addr, static_cast<uint32_t>(n)};
|
||||
int Module::getBit(BitAddress bitAddr) const {
|
||||
uint32_t args[2] = {bitAddr.address().value(), bitAddr.bitPosition()};
|
||||
return sendToDetectorStop<int>(F_GET_BIT, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "sls/ClientSocket.h"
|
||||
#include "sls/Pattern.h"
|
||||
#include "sls/StaticVector.h"
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
@@ -579,11 +580,11 @@ class Module : public virtual slsDetectorDefs {
|
||||
void rebootController();
|
||||
bool getUpdateMode() const;
|
||||
void setUpdateMode(const bool updatemode);
|
||||
uint32_t readRegister(uint32_t addr) const;
|
||||
void writeRegister(uint32_t addr, uint32_t val, bool validate);
|
||||
void setBit(uint32_t addr, int n, bool validate);
|
||||
void clearBit(uint32_t addr, int n, bool validate);
|
||||
int getBit(uint32_t addr, int n);
|
||||
RegisterValue readRegister(RegisterAddress addr) const;
|
||||
void writeRegister(RegisterAddress addr, RegisterValue val, bool validate);
|
||||
void setBit(BitAddress bitAddr, bool validate);
|
||||
void clearBit(BitAddress bitAddr, bool validate);
|
||||
int getBit(BitAddress bitAddr) const;
|
||||
void executeFirmwareTest();
|
||||
void executeBusTest();
|
||||
void writeAdcRegister(uint32_t addr, uint32_t val);
|
||||
|
||||
@@ -28,25 +28,26 @@
|
||||
// ********************** Defines for shared memory. **********************
|
||||
// WARNING! before chaning these search the codebase for their usage!
|
||||
|
||||
// date when IsValid boolean introduced into every shm structure
|
||||
// (to look out for shm that still exists due to other mapped resources)
|
||||
#define SHM_IS_VALID_CHECK_VERSION 0x250820
|
||||
|
||||
//Max shared memory name length in macOS is 31 characters
|
||||
// Max shared memory name length in macOS is 31 characters
|
||||
#ifdef __APPLE__
|
||||
#define SHM_DETECTOR_PREFIX "/sls_"
|
||||
#define SHM_MODULE_PREFIX "_mod_"
|
||||
#define SHM_DETECTOR_PREFIX "/sls_"
|
||||
#define SHM_MODULE_PREFIX "_mod_"
|
||||
#else
|
||||
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
|
||||
#define SHM_MODULE_PREFIX "_module_"
|
||||
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
|
||||
#define SHM_MODULE_PREFIX "_module_"
|
||||
#endif
|
||||
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
// ************************************************************************
|
||||
|
||||
namespace sls {
|
||||
|
||||
class CtbConfig;
|
||||
|
||||
|
||||
template <typename T, typename U> constexpr bool is_type() {
|
||||
return std::is_same_v<std::decay_t<U>, T>;
|
||||
}
|
||||
@@ -94,17 +95,16 @@ template <typename T> class SharedMemory {
|
||||
unmapSharedMemory();
|
||||
}
|
||||
|
||||
/** memory is valid if it has the IsValid flag and is true */
|
||||
bool memoryHasValidFlag() const {
|
||||
if (shared_struct == nullptr) {
|
||||
throw SharedMemoryError(
|
||||
"Shared memory not mapped. Cannot check validity.");
|
||||
}
|
||||
// CtbConfig did not have shmversion before, so exact value check
|
||||
if constexpr (is_type<CtbConfig, T>()) {
|
||||
if (shared_struct->shmversion == SHM_IS_VALID_CHECK_VERSION) {
|
||||
return true;
|
||||
}
|
||||
} else if (shared_struct->shmversion >= SHM_IS_VALID_CHECK_VERSION) {
|
||||
// CtbConfig also works (shmversion didnt exist prior, but it would read
|
||||
// "20" = length size) so shmversion should always be >= isValid
|
||||
// introduced date (0x250820)
|
||||
if (shared_struct->shmversion >= SHM_IS_VALID_CHECK_VERSION) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -279,11 +279,12 @@ template <typename T> class SharedMemory {
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// On macOS, fstat returns the allocated size and not the requested size.
|
||||
// This means we can't check for size since we always get for example 16384 bytes.
|
||||
#ifdef __APPLE__
|
||||
// On macOS, fstat returns the allocated size and not the requested
|
||||
// size. This means we can't check for size since we always get for
|
||||
// example 16384 bytes.
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
auto actual_size = static_cast<size_t>(sb.st_size);
|
||||
auto expected_size = sizeof(T);
|
||||
if (actual_size != expected_size) {
|
||||
|
||||
@@ -400,6 +400,10 @@ int InferAction::chipversion() {
|
||||
|
||||
int InferAction::clearbit() {
|
||||
|
||||
if (args.size() == 1) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
@@ -788,6 +792,66 @@ int InferAction::defaultpattern() {
|
||||
}
|
||||
}
|
||||
|
||||
int InferAction::define_bit() {
|
||||
|
||||
if (args.size() == 1) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError("Could not infer action: Wrong number of arguments");
|
||||
}
|
||||
}
|
||||
|
||||
int InferAction::define_reg() {
|
||||
|
||||
if (args.size() == 1) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError("Could not infer action: Wrong number of arguments");
|
||||
}
|
||||
}
|
||||
|
||||
int InferAction::definelist_bit() {
|
||||
|
||||
if (args.size() == 0) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError("Could not infer action: Wrong number of arguments");
|
||||
}
|
||||
}
|
||||
|
||||
int InferAction::definelist_reg() {
|
||||
|
||||
if (args.size() == 0) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
throw RuntimeError("Could not infer action: Wrong number of arguments");
|
||||
}
|
||||
}
|
||||
|
||||
int InferAction::delay() {
|
||||
|
||||
if (args.size() == 0) {
|
||||
@@ -1498,6 +1562,10 @@ int InferAction::gates() {
|
||||
|
||||
int InferAction::getbit() {
|
||||
|
||||
if (args.size() == 1) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::GET_ACTION;
|
||||
}
|
||||
@@ -3055,6 +3123,10 @@ int InferAction::serialnumber() {
|
||||
|
||||
int InferAction::setbit() {
|
||||
|
||||
if (args.size() == 1) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
if (args.size() == 2) {
|
||||
return slsDetectorDefs::PUT_ACTION;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ class InferAction {
|
||||
int dbitpipeline();
|
||||
int defaultdac();
|
||||
int defaultpattern();
|
||||
int define_bit();
|
||||
int define_reg();
|
||||
int definelist_bit();
|
||||
int definelist_reg();
|
||||
int delay();
|
||||
int delayl();
|
||||
int detectorserverversion();
|
||||
@@ -394,6 +398,10 @@ class InferAction {
|
||||
{"dbitpipeline", &InferAction::dbitpipeline},
|
||||
{"defaultdac", &InferAction::defaultdac},
|
||||
{"defaultpattern", &InferAction::defaultpattern},
|
||||
{"define_bit", &InferAction::define_bit},
|
||||
{"define_reg", &InferAction::define_reg},
|
||||
{"definelist_bit", &InferAction::definelist_bit},
|
||||
{"definelist_reg", &InferAction::definelist_reg},
|
||||
{"delay", &InferAction::delay},
|
||||
{"delayl", &InferAction::delayl},
|
||||
{"detectorserverversion", &InferAction::detectorserverversion},
|
||||
|
||||
@@ -1330,4 +1330,367 @@ TEST_CASE("led", "[.cmdcall]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("define_reg", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
|
||||
auto prev_reg_defines = det.getRegisterDefinitions();
|
||||
auto prev_bit_defines = det.getBitDefinitions();
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
|
||||
{
|
||||
// invalid puts
|
||||
// missing arg
|
||||
REQUIRE_THROWS(caller.call("define_reg", {}, -1, GET));
|
||||
// missing arg
|
||||
REQUIRE_THROWS(caller.call("define_reg", {"TEST_REG"}, -1, PUT));
|
||||
// invalid module id
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_reg", {"TEST_REG", "0x201"}, 0, PUT));
|
||||
|
||||
// valid put
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_reg", {"TEST_REG", "0x200"}, -1, PUT));
|
||||
// modify reg
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_reg", {"TEST_REG", "0x201"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_reg", {"TEST_REG2", "0x202"}, -1, PUT));
|
||||
|
||||
// invalid puts
|
||||
// existing reg addr
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_reg", {"TEST_REG3", "0x201"}, -1, PUT));
|
||||
|
||||
// valid gets
|
||||
{
|
||||
// get by name
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_reg", {"TEST_REG"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "define_reg 0x201\n");
|
||||
}
|
||||
{
|
||||
// get by addr
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_reg", {"0x201"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "define_reg TEST_REG\n");
|
||||
}
|
||||
|
||||
// invalid gets
|
||||
// doesnt exist
|
||||
REQUIRE_THROWS(caller.call("define_reg", {"TEST_REG3"}, -1, GET));
|
||||
REQUIRE_THROWS(caller.call("define_reg", {"0x203"}, -1, GET));
|
||||
// ensure correct exception message
|
||||
try {
|
||||
caller.call("define_reg", {"0x203"}, -1, GET);
|
||||
} catch (const std::exception &e) {
|
||||
REQUIRE(std::string(e.what()) ==
|
||||
"No register definition found for address: 0x203");
|
||||
}
|
||||
}
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
|
||||
det.setRegisterDefinitions(prev_reg_defines);
|
||||
det.setBitDefinitions(prev_bit_defines);
|
||||
|
||||
} else {
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_reg", {"TEST_REG", "0x200"}, -1, PUT));
|
||||
REQUIRE_THROWS(caller.call("define_reg", {"TEST_REG"}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("define_bit", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
|
||||
auto prev_reg_defines = det.getRegisterDefinitions();
|
||||
auto prev_bit_defines = det.getBitDefinitions();
|
||||
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
det.setRegisterDefinition("TEST_REG", RegisterAddress(0x201));
|
||||
det.setRegisterDefinition("TEST_REG2", RegisterAddress(0x202));
|
||||
|
||||
{
|
||||
// invalid puts
|
||||
// skipped register
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_bit", {"TEST_BIT", "1"}, -1, PUT));
|
||||
// named register doesnt exist
|
||||
REQUIRE_THROWS(caller.call(
|
||||
"define_bit", {"TEST_BIT", "RANDOM_REG", "1"}, -1, PUT));
|
||||
// invalid bit position
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define", {"TEST_BIT", "TEST_REG", "32"}, -1, PUT));
|
||||
|
||||
// valid puts
|
||||
REQUIRE_NOTHROW(caller.call(
|
||||
"define_bit", {"TEST_BIT", "TEST_REG2", "1"}, -1, PUT));
|
||||
// modify reg
|
||||
REQUIRE_NOTHROW(caller.call(
|
||||
"define_bit", {"TEST_BIT", "TEST_REG", "1"}, -1, PUT));
|
||||
|
||||
// modify position
|
||||
REQUIRE_NOTHROW(caller.call(
|
||||
"define_bit", {"TEST_BIT", "TEST_REG", "2"}, -1, PUT));
|
||||
// another bit to same reg
|
||||
REQUIRE_NOTHROW(caller.call(
|
||||
"define_bit", {"TEST_BIT2", "TEST_REG", "4"}, -1, PUT));
|
||||
// bit to a different reg
|
||||
REQUIRE_NOTHROW(caller.call(
|
||||
"define_bit", {"TEST_BIT3", "TEST_REG2", "3"}, -1, PUT));
|
||||
|
||||
// valid gets
|
||||
{
|
||||
// get by name
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_bit", {"TEST_BIT"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "define_bit [TEST_REG, 2]\n");
|
||||
}
|
||||
{
|
||||
// get by addr+pos name
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_bit", {"TEST_REG", "2"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "define_bit TEST_BIT\n");
|
||||
}
|
||||
{
|
||||
// get by addr val + pos
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("define_bit", {"0x201", "2"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "define_bit TEST_BIT\n");
|
||||
}
|
||||
|
||||
// invalid gets
|
||||
// bit doesnt exist
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_bit", {"TEST_REG", "3"}, -1, GET));
|
||||
// addr doesnt exist
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_bit", {"TEST_REG3", "2"}, -1, GET));
|
||||
// ensure correct exception message
|
||||
try {
|
||||
caller.call("define_bit", {"TEST_REG", "3"}, -1, GET);
|
||||
} catch (const std::exception &e) {
|
||||
REQUIRE(std::string(e.what()) ==
|
||||
"No bit definition found for bit position: [0x201, 3] "
|
||||
"and addr = TEST_REG");
|
||||
}
|
||||
}
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
|
||||
det.setRegisterDefinitions(prev_reg_defines);
|
||||
det.setBitDefinitions(prev_bit_defines);
|
||||
|
||||
} else {
|
||||
REQUIRE_THROWS(
|
||||
caller.call("define_bit", {"TEST_BIT", "0x200", "2"}, -1, PUT));
|
||||
REQUIRE_THROWS(caller.call("define_bit", {"0x200", "2"}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("using define for reg, setbit, getbit and clearbit",
|
||||
"[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
|
||||
if (det.isVirtualDetectorServer().tsquash(
|
||||
"inconsistent virtual values")) {
|
||||
|
||||
auto prev_reg_defines = det.getRegisterDefinitions();
|
||||
auto prev_bit_defines = det.getBitDefinitions();
|
||||
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
det.setRegisterDefinition("TEST_REG", RegisterAddress(0x201));
|
||||
det.setRegisterDefinition("TEST_REG2", RegisterAddress(0x202));
|
||||
det.setBitDefinition("TEST_BIT",
|
||||
BitAddress(RegisterAddress(0x201), 2));
|
||||
det.setBitDefinition("TEST_BIT2",
|
||||
BitAddress(RegisterAddress(0x201), 4));
|
||||
det.setBitDefinition("TEST_BIT3",
|
||||
BitAddress(RegisterAddress(0x202), 3));
|
||||
|
||||
auto prev_val_addr = det.readRegister(RegisterAddress(0x201));
|
||||
auto prev_val_addr2 = det.readRegister(RegisterAddress(0x202));
|
||||
|
||||
// invalid puts
|
||||
// doesnt exist addr
|
||||
REQUIRE_THROWS(
|
||||
caller.call("reg", {"RANDOM_REG", "0xf00"}, -1, PUT));
|
||||
REQUIRE_THROWS(
|
||||
caller.call("clearbit", {"RANDOM_REG", "TEST_BIT"}, -1, PUT));
|
||||
REQUIRE_THROWS(
|
||||
caller.call("setbit", {"RANDOM_REG", "TEST_BIT"}, -1, PUT));
|
||||
REQUIRE_THROWS(
|
||||
caller.call("getbit", {"RANDOM_REG", "TEST_BIT"}, -1, GET));
|
||||
// using bit name for reg (only hardcoded values allowed)
|
||||
REQUIRE_THROWS(
|
||||
caller.call("reg", {"TEST_REG", "TEST_BIT"}, -1, PUT));
|
||||
// using bit name and reg (only bit names or both reg and bit
|
||||
// hardcoded allowed)
|
||||
REQUIRE_THROWS(
|
||||
caller.call("clearbit", {"TEST_REG", "TEST_BIT"}, -1, PUT));
|
||||
REQUIRE_THROWS(
|
||||
caller.call("setbit", {"TEST_REG", "TEST_BIT"}, -1, PUT));
|
||||
REQUIRE_THROWS(
|
||||
caller.call("getbit", {"TEST_REG", "TEST_BIT"}, -1, GET));
|
||||
|
||||
// valid puts and gets
|
||||
{
|
||||
// reg hard coded value of 0
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("reg", {"TEST_REG", "0x0"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("reg", {"TEST_REG"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "reg 0x0\n");
|
||||
}
|
||||
{
|
||||
// reg hard coded value
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("reg", {"TEST_REG", "0x10"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("reg", {"TEST_REG"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "reg 0x10\n");
|
||||
}
|
||||
{
|
||||
// set bit
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(caller.call("setbit", {"TEST_BIT"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("setbit", {"TEST_REG", "2"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("reg", {"TEST_REG"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "reg 0x14\n");
|
||||
}
|
||||
{
|
||||
// get bit
|
||||
std::ostringstream oss, oss2;
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("getbit", {"TEST_REG", "2"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "getbit 1\n");
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("getbit", {"TEST_BIT"}, -1, GET, oss2));
|
||||
REQUIRE(oss2.str() == "getbit 1\n");
|
||||
}
|
||||
{
|
||||
// clear bit
|
||||
std::ostringstream oss;
|
||||
REQUIRE_NOTHROW(caller.call("clearbit", {"TEST_BIT"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(
|
||||
caller.call("clearbit", {"TEST_REG", "2"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(caller.call("reg", {"TEST_REG"}, -1, GET, oss));
|
||||
REQUIRE(oss.str() == "reg 0x10\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.writeRegister(RegisterAddress(0x201),
|
||||
RegisterValue(prev_val_addr[i]), false, {i});
|
||||
det.writeRegister(RegisterAddress(0x202),
|
||||
RegisterValue(prev_val_addr2[i]), false, {i});
|
||||
}
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
|
||||
det.setRegisterDefinitions(prev_reg_defines);
|
||||
det.setBitDefinitions(prev_bit_defines);
|
||||
}
|
||||
|
||||
} else {
|
||||
REQUIRE_THROWS(caller.call("reg", {"TEST_REG", "0x200"}, -1, PUT));
|
||||
REQUIRE_THROWS(caller.call("reg", {"TEST_REG"}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("definelist_reg", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
|
||||
auto prev_reg_defines = det.getRegisterDefinitions();
|
||||
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
det.setRegisterDefinition("TEST_REG", RegisterAddress(0x201));
|
||||
det.setRegisterDefinition("TEST_REG2", RegisterAddress(0x202));
|
||||
|
||||
// invalid
|
||||
// cannot put
|
||||
REQUIRE_THROWS(
|
||||
caller.call("definelist_reg", {"TEST_REG", "0x201"}, -1, PUT));
|
||||
// too many args
|
||||
REQUIRE_THROWS(caller.call("definelist_reg", {"TEST_MACRO"}, -1, GET));
|
||||
|
||||
// valid
|
||||
REQUIRE_NOTHROW(caller.call("definelist_reg", {}, -1, GET));
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
|
||||
det.setRegisterDefinitions(prev_reg_defines);
|
||||
} else {
|
||||
REQUIRE_THROWS(caller.call("definelist_reg", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("definelist_bit", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
|
||||
auto prev_reg_defines = det.getRegisterDefinitions();
|
||||
auto prev_bit_defines = det.getBitDefinitions();
|
||||
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
det.setRegisterDefinition("TEST_REG", RegisterAddress(0x201));
|
||||
det.setRegisterDefinition("TEST_REG2", RegisterAddress(0x202));
|
||||
det.setBitDefinition("TEST_BIT", BitAddress(RegisterAddress(0x201), 2));
|
||||
det.setBitDefinition("TEST_BIT2",
|
||||
BitAddress(RegisterAddress(0x201), 4));
|
||||
det.setBitDefinition("TEST_BIT3",
|
||||
BitAddress(RegisterAddress(0x202), 3));
|
||||
|
||||
// invalid
|
||||
// cannot put
|
||||
REQUIRE_THROWS(
|
||||
caller.call("definelist_bit", {"TEST_BIT", "0x201", "2"}, -1, PUT));
|
||||
// too many args
|
||||
REQUIRE_THROWS(caller.call("definelist_bit", {"TEST_BIT"}, -1, GET));
|
||||
|
||||
// valid
|
||||
REQUIRE_NOTHROW(caller.call("definelist_bit", {}, -1, GET));
|
||||
det.clearRegisterDefinitions();
|
||||
det.clearBitDefinitions();
|
||||
|
||||
det.setRegisterDefinitions(prev_reg_defines);
|
||||
det.setBitDefinitions(prev_bit_defines);
|
||||
} else {
|
||||
REQUIRE_THROWS(caller.call("definelist_bit", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
||||
@@ -3267,7 +3267,7 @@ TEST_CASE("update", "[.cmdcall]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("reg", "[.cmdcall]") {
|
||||
TEST_CASE("reg", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
@@ -3284,14 +3284,14 @@ TEST_CASE("reg", "[.cmdcall]") {
|
||||
{
|
||||
std::ostringstream oss1, oss2;
|
||||
caller.call("reg", {saddr, "0x6", "--validate"}, -1, PUT, oss1);
|
||||
REQUIRE(oss1.str() == "reg [" + saddr + ", 0x6]\n");
|
||||
REQUIRE(oss1.str() == "reg " + saddr + " 0x6\n");
|
||||
caller.call("reg", {saddr}, -1, GET, oss2);
|
||||
REQUIRE(oss2.str() == "reg 0x6\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss1, oss2;
|
||||
caller.call("reg", {saddr, "0x5"}, -1, PUT, oss1);
|
||||
REQUIRE(oss1.str() == "reg [" + saddr + ", 0x5]\n");
|
||||
REQUIRE(oss1.str() == "reg " + saddr + " 0x5\n");
|
||||
caller.call("reg", {saddr}, -1, GET, oss2);
|
||||
REQUIRE(oss2.str() == "reg 0x5\n");
|
||||
}
|
||||
@@ -3326,7 +3326,7 @@ TEST_CASE("adcreg", "[.cmdcall]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("setbit", "[.cmdcall]") {
|
||||
TEST_CASE("setbit", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
@@ -3356,7 +3356,7 @@ TEST_CASE("setbit", "[.cmdcall]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("clearbit", "[.cmdcall]") {
|
||||
TEST_CASE("clearbit", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
@@ -3386,7 +3386,7 @@ TEST_CASE("clearbit", "[.cmdcall]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("getbit", "[.cmdcall]") {
|
||||
TEST_CASE("getbit", "[.cmdcall][.definecmds]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
@@ -6,13 +6,16 @@
|
||||
#include "CtbConfig.h"
|
||||
#include "SharedMemory.h"
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
|
||||
namespace sls {
|
||||
|
||||
TEST_CASE("Default construction") {
|
||||
static_assert(sizeof(CtbConfig) ==
|
||||
(2 * sizeof(int) + (18 + 32 + 64 + 5 + 8) * 20),
|
||||
"Size of CtbConfig does not match ");
|
||||
/*TODO static_assert(sizeof(CtbConfig) ==
|
||||
(2 * sizeof(int) + (18 + 32 + 64 + 5 + 8) * 32) +
|
||||
(sizeof(size_t) * 2) + ((sizeof(uint32_t) + 32) * 64) +
|
||||
((32 + sizeof(uint32_t) + sizeof(int)) * 64), "Size of CtbConfig does not
|
||||
match "); //8952 (8696)*/
|
||||
|
||||
CtbConfig c;
|
||||
auto dacnames = c.getDacNames();
|
||||
@@ -46,6 +49,16 @@ TEST_CASE("Default construction") {
|
||||
REQUIRE(sensenames[1] == "SLOWADC1");
|
||||
REQUIRE(sensenames[2] == "SLOWADC2");
|
||||
REQUIRE(sensenames[3] == "SLOWADC3");
|
||||
auto regisernames = c.getRegisterNames();
|
||||
REQUIRE(regisernames.size() == 0);
|
||||
auto bitnames = c.getBitNames();
|
||||
REQUIRE(bitnames.size() == 0);
|
||||
REQUIRE(c.getRegisterNamesCount() == 0);
|
||||
auto registerNames = c.getRegisterNames();
|
||||
REQUIRE(registerNames.size() == 0);
|
||||
REQUIRE(c.getBitNamesCount() == 0);
|
||||
auto bitNames = c.getBitNames();
|
||||
REQUIRE(bitNames.size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Set and get a single dac name") {
|
||||
@@ -85,4 +98,164 @@ TEST_CASE("Move CtbConfig ") {
|
||||
REQUIRE(c2.getDacName(3) == "yetanothername");
|
||||
}
|
||||
|
||||
TEST_CASE("Add or modify a register name", "[.reg]") {
|
||||
CtbConfig c;
|
||||
auto addr = RegisterAddress(100);
|
||||
auto addr1 = RegisterAddress(300);
|
||||
|
||||
REQUIRE(c.getRegisterNamesCount() == 0);
|
||||
REQUIRE_THROWS(
|
||||
c.setRegisterName("reg1_with_a_really_long_name_to_crash", addr));
|
||||
// add an entry
|
||||
REQUIRE_NOTHROW(c.setRegisterName("reg1", addr));
|
||||
REQUIRE(c.getRegisterName(addr) == "reg1");
|
||||
REQUIRE(c.getRegisterAddress("reg1") == addr);
|
||||
REQUIRE(c.getRegisterNamesCount() == 1);
|
||||
// modify an entry
|
||||
REQUIRE_NOTHROW(c.setRegisterName("reg1", addr1));
|
||||
REQUIRE(c.getRegisterAddress("reg1") == addr1);
|
||||
REQUIRE(c.getRegisterName(addr1) == "reg1");
|
||||
// clear all entries
|
||||
REQUIRE_NOTHROW(c.clearRegisterNames());
|
||||
REQUIRE(c.getRegisterNamesCount() == 0);
|
||||
REQUIRE_THROWS(c.getRegisterName(addr));
|
||||
REQUIRE_THROWS(c.getRegisterAddress("reg1"));
|
||||
REQUIRE_THROWS(c.getRegisterName(addr1));
|
||||
}
|
||||
|
||||
TEST_CASE("Add a register list", "[.reg]") {
|
||||
CtbConfig c;
|
||||
REQUIRE(c.getRegisterNamesCount() == 0);
|
||||
|
||||
// add a list
|
||||
std::map<std::string, RegisterAddress> list = {
|
||||
{"reg1", RegisterAddress(0x100)},
|
||||
{"reg2", RegisterAddress(0x200)},
|
||||
{"reg3", RegisterAddress(0x300)}};
|
||||
REQUIRE_NOTHROW(c.setRegisterNames(list));
|
||||
REQUIRE(c.getRegisterNamesCount() == static_cast<int>(list.size()));
|
||||
auto names = c.getRegisterNames();
|
||||
REQUIRE(names.size() == 3);
|
||||
|
||||
// TODO std::set<RegisterAddress> seen_values;
|
||||
for (const auto &[key, val] : list) {
|
||||
// check for duplicate keys, and key-value match
|
||||
REQUIRE(names.count(key) == 1);
|
||||
REQUIRE(names.at(key) == val);
|
||||
|
||||
// check for duplicate values
|
||||
// TODO REQUIRE(seen_values.count(val) == 0);
|
||||
// TODO seen_values.insert(val);
|
||||
}
|
||||
|
||||
// clear all entries
|
||||
REQUIRE_NOTHROW(c.clearRegisterNames());
|
||||
REQUIRE(c.getRegisterNames().size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Finding a regiser name or address", "[.reg]") {
|
||||
CtbConfig c;
|
||||
RegisterAddress addr1(0x100);
|
||||
RegisterAddress addr2(0x200);
|
||||
RegisterAddress addr3(0x300);
|
||||
|
||||
// find nothing
|
||||
REQUIRE(c.getRegisterNamesCount() == 0);
|
||||
REQUIRE_THROWS(c.getRegisterName(addr1));
|
||||
REQUIRE_THROWS(c.getRegisterAddress("reg1"));
|
||||
|
||||
std::map<std::string, RegisterAddress> list = {
|
||||
{"reg1", addr1}, {"reg2", addr2}, {"reg3", addr3}};
|
||||
REQUIRE_NOTHROW(c.setRegisterNames(list));
|
||||
|
||||
// find
|
||||
REQUIRE(c.getRegisterName(addr1) == "reg1");
|
||||
REQUIRE(c.getRegisterName(addr2) == "reg2");
|
||||
REQUIRE(c.getRegisterAddress("reg3") == addr3);
|
||||
}
|
||||
|
||||
TEST_CASE("Add or modify a bit name", "[.reg]") {
|
||||
CtbConfig c;
|
||||
RegisterAddress addr(0x100);
|
||||
BitAddress pos(addr, 2);
|
||||
BitAddress pos1(addr, 5);
|
||||
|
||||
REQUIRE(c.getBitNamesCount() == 0);
|
||||
|
||||
REQUIRE_THROWS(c.setBitName("bit1_with_a_really_long_name_to_crash",
|
||||
BitAddress(addr, 100)));
|
||||
REQUIRE_THROWS(c.setBitName("bit1", BitAddress(addr, 32)));
|
||||
REQUIRE_THROWS(c.setBitName("bit1", BitAddress(addr, -1)));
|
||||
|
||||
// add an entry
|
||||
REQUIRE_NOTHROW(c.setBitName("bit1", pos));
|
||||
REQUIRE(c.getBitName(pos) == "bit1");
|
||||
REQUIRE(c.getBitAddress("bit1") == pos);
|
||||
REQUIRE(c.getBitNamesCount() == 1);
|
||||
// modify an entry
|
||||
REQUIRE_NOTHROW(c.setBitName("bit1", pos1));
|
||||
REQUIRE(c.getBitAddress("bit1") == pos1);
|
||||
REQUIRE(c.getBitName(pos1) == "bit1");
|
||||
// clear all entries
|
||||
REQUIRE_NOTHROW(c.clearBitNames());
|
||||
REQUIRE(c.getBitNamesCount() == 0);
|
||||
REQUIRE_THROWS(c.getBitName(pos));
|
||||
REQUIRE_THROWS(c.getBitAddress("bit1"));
|
||||
REQUIRE_THROWS(c.getBitName(pos1));
|
||||
}
|
||||
|
||||
TEST_CASE("Add a bit list", "[.reg]") {
|
||||
CtbConfig c;
|
||||
REQUIRE(c.getBitNamesCount() == 0);
|
||||
|
||||
RegisterAddress addr(0x100);
|
||||
BitAddress pos1(addr, 2);
|
||||
BitAddress pos2(addr, 21);
|
||||
|
||||
BitAddress pos3(addr, 31);
|
||||
|
||||
// add a list
|
||||
std::map<std::string, BitAddress> list = {
|
||||
{"bit1", pos1}, {"bit2", pos2}, {"bit3", pos3}};
|
||||
REQUIRE_NOTHROW(c.setBitNames(list));
|
||||
REQUIRE(c.getBitNamesCount() == 3);
|
||||
auto names = c.getBitNames();
|
||||
REQUIRE(names.size() == 3);
|
||||
|
||||
// TODO std::set<BitAddress> seen_values;
|
||||
for (const auto &[key, val] : list) {
|
||||
// check for duplicate keys, and key-value match
|
||||
REQUIRE(names.count(key) == 1);
|
||||
REQUIRE(names.at(key) == val);
|
||||
|
||||
// check for duplicate values
|
||||
// TODO REQUIRE(seen_values.count(val) == 0);
|
||||
// TODO seen_values.insert(val);
|
||||
}
|
||||
|
||||
// clear all entries
|
||||
REQUIRE_NOTHROW(c.clearBitNames());
|
||||
REQUIRE(c.getBitNames().size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Finding a bit value", "[.reg]") {
|
||||
CtbConfig c;
|
||||
RegisterAddress addr(0x100);
|
||||
BitAddress pos(addr, 2);
|
||||
BitAddress pos1(addr, 21);
|
||||
BitAddress pos2(addr, 31);
|
||||
|
||||
// find nothing
|
||||
REQUIRE(c.getBitNamesCount() == 0);
|
||||
REQUIRE_THROWS(c.getBitAddress("bit"));
|
||||
|
||||
std::map<std::string, BitAddress> list = {
|
||||
{"bit0", pos}, {"bit1", pos1}, {"bit2", pos2}};
|
||||
REQUIRE_NOTHROW(c.setBitNames(list));
|
||||
|
||||
// find
|
||||
REQUIRE(c.getBitAddress("bit2") == pos2);
|
||||
REQUIRE(c.getBitName(pos1) == "bit1");
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
||||
@@ -39,15 +39,13 @@ void freeShm(const int dindex, const int mIndex) {
|
||||
|
||||
constexpr int shm_id = 10;
|
||||
|
||||
//macOS does not expose shm in the filesystem
|
||||
// macOS does not expose shm in the filesystem
|
||||
#ifndef __APPLE__
|
||||
|
||||
const std::string file_path =
|
||||
std::string("/dev/shm/slsDetectorPackage_detector_") +
|
||||
std::to_string(shm_id);
|
||||
|
||||
|
||||
|
||||
TEST_CASE("Free obsolete (without isValid)", "[detector][shm]") {
|
||||
|
||||
// ensure its clean to start
|
||||
@@ -106,8 +104,8 @@ TEST_CASE("Create SharedMemory read and write", "[detector][shm]") {
|
||||
|
||||
const char *env_p = std::getenv(SHM_ENV_NAME);
|
||||
std::string env_name = env_p ? ("_" + std::string(env_p)) : "";
|
||||
CHECK(shm.getName() == std::string(SHM_DETECTOR_PREFIX) +
|
||||
std::to_string(shm_id) + env_name);
|
||||
CHECK(shm.getName() ==
|
||||
std::string(SHM_DETECTOR_PREFIX) + std::to_string(shm_id) + env_name);
|
||||
shm()->x = 3;
|
||||
shm()->y = 5.7;
|
||||
strcpy_safe(shm()->mess, "Some string");
|
||||
@@ -180,8 +178,8 @@ TEST_CASE("Move SharedMemory", "[detector][shm]") {
|
||||
std::string env_name = env_p ? ("_" + std::string(env_p)) : "";
|
||||
|
||||
SharedMemory<Data> shm(shm_id, -1);
|
||||
CHECK(shm.getName() == std::string(SHM_DETECTOR_PREFIX) +
|
||||
std::to_string(shm_id) + env_name);
|
||||
CHECK(shm.getName() ==
|
||||
std::string(SHM_DETECTOR_PREFIX) + std::to_string(shm_id) + env_name);
|
||||
shm.createSharedMemory();
|
||||
shm()->x = 9;
|
||||
|
||||
@@ -191,8 +189,8 @@ TEST_CASE("Move SharedMemory", "[detector][shm]") {
|
||||
CHECK(shm2()->x == 9);
|
||||
REQUIRE_THROWS(
|
||||
shm()); // trying to access should throw instead of returning a nullptr
|
||||
CHECK(shm2.getName() == std::string(SHM_DETECTOR_PREFIX) +
|
||||
std::to_string(shm_id) + env_name);
|
||||
CHECK(shm2.getName() ==
|
||||
std::string(SHM_DETECTOR_PREFIX) + std::to_string(shm_id) + env_name);
|
||||
shm2.removeSharedMemory();
|
||||
}
|
||||
|
||||
@@ -243,7 +241,8 @@ TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") {
|
||||
setenv(SHM_ENV_NAME, "myprefix", 1);
|
||||
|
||||
SharedMemory<Data> shm(0, -1, "ctbdacs");
|
||||
REQUIRE(shm.getName() == std::string(SHM_DETECTOR_PREFIX) + "0_myprefix_ctbdacs");
|
||||
REQUIRE(shm.getName() ==
|
||||
std::string(SHM_DETECTOR_PREFIX) + "0_myprefix_ctbdacs");
|
||||
|
||||
// Clean up after us
|
||||
if (old_slsdetname.empty())
|
||||
|
||||
@@ -49,7 +49,7 @@ target_link_libraries(slsReceiverObject
|
||||
slsProjectOptions
|
||||
slsSupportStatic
|
||||
PRIVATE
|
||||
slsProjectWarnings #don't propagate warnigns
|
||||
slsProjectWarnings #don't propagate warnings
|
||||
)
|
||||
|
||||
target_compile_definitions(slsReceiverObject
|
||||
@@ -118,8 +118,6 @@ if (SLS_USE_RECEIVER_BINARIES)
|
||||
target_link_libraries(slsReceiver PUBLIC
|
||||
PUBLIC
|
||||
slsReceiverStatic
|
||||
pthread
|
||||
rt
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
)
|
||||
@@ -138,8 +136,6 @@ if (SLS_USE_RECEIVER_BINARIES)
|
||||
target_link_libraries(slsMultiReceiver
|
||||
PUBLIC
|
||||
slsReceiverStatic
|
||||
pthread
|
||||
rt
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
)
|
||||
@@ -158,8 +154,6 @@ if (SLS_USE_RECEIVER_BINARIES)
|
||||
target_link_libraries(slsFrameSynchronizer
|
||||
PUBLIC
|
||||
slsReceiverStatic
|
||||
pthread
|
||||
rt
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
|
||||
|
||||
@@ -138,7 +138,8 @@ TEST_CASE("Parse version and help", "[detector]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Parse port and uid", "[detector]") {
|
||||
// TODO: fails on gitea CI due to uid issue, fix later
|
||||
TEST_CASE("Parse port and uid", "[.failsongitea][detector]") {
|
||||
uid_t uid = getuid();
|
||||
std::string uidStr = std::to_string(uid);
|
||||
uid_t invalidUid = uid + 1000;
|
||||
@@ -147,9 +148,12 @@ TEST_CASE("Parse port and uid", "[detector]") {
|
||||
for (auto app : {AppType::SingleReceiver, AppType::MultiReceiver,
|
||||
AppType::FrameSynchronizer}) {
|
||||
CommandLineOptions s(app);
|
||||
REQUIRE_THROWS(
|
||||
s.parse({"", "-p", "1234", "-u", invalidUidStr})); // invalid uid
|
||||
REQUIRE_THROWS(s.parse({"", "-p", "500"})); // invalid port
|
||||
|
||||
// TODO! This test fails on gitea CI probably because the user can set
|
||||
// the uid commenting it out for now. Revisit later. REQUIRE_THROWS(
|
||||
// s.parse({"", "-p", "1234", "-u", invalidUidStr})); // invalid uid
|
||||
|
||||
REQUIRE_THROWS(s.parse({"", "-p", "500"})); // invalid port
|
||||
|
||||
auto opts = s.parse({"", "-p", "1234", "-u", uidStr});
|
||||
std::visit(
|
||||
|
||||
@@ -64,7 +64,8 @@ class DataProcessorTest : public DataProcessor {
|
||||
* num_transceiver_bytes = 2 both bytes have a value of 125
|
||||
* num_digital_bytes is variable and is defined by number of samples
|
||||
* default num sample is 5
|
||||
* all bytes in digital data take a value of 255
|
||||
* all bytes in digital data take a value of 0xFF (alternating bits between 0,
|
||||
* 1)
|
||||
*/
|
||||
class DataProcessorTestFixture {
|
||||
public:
|
||||
@@ -106,7 +107,7 @@ class DataProcessorTestFixture {
|
||||
num_random_offset_bytes);
|
||||
}
|
||||
|
||||
void set_data() {
|
||||
void set_data(const std::bitset<8> pattern = 0xFF) {
|
||||
delete[] data;
|
||||
uint64_t max_bytes_per_bit =
|
||||
num_samples % 8 == 0 ? num_samples / 8 : num_samples / 8 + 1;
|
||||
@@ -118,7 +119,8 @@ class DataProcessorTestFixture {
|
||||
memset(data, dummy_value, num_analog_bytes); // set to dummy value
|
||||
memset(data + num_analog_bytes, 0,
|
||||
num_random_offset_bytes); // set to zero
|
||||
memset(data + num_analog_bytes + num_random_offset_bytes, 0xFF,
|
||||
memset(data + num_analog_bytes + num_random_offset_bytes,
|
||||
static_cast<uint8_t>(pattern.to_ulong()),
|
||||
num_digital_bytes); // all digital bits are one
|
||||
memset(data + num_digital_bytes + num_analog_bytes +
|
||||
num_random_offset_bytes,
|
||||
@@ -170,7 +172,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Remove Trailing Bits",
|
||||
TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all",
|
||||
"[.dataprocessor][.reorder]") {
|
||||
// parameters: num_samples, expected_num_digital_bytes,
|
||||
// expected_digital_part
|
||||
// expected_digital_part_for_each_bit
|
||||
auto parameters = GENERATE(
|
||||
std::make_tuple(5, 64, std::vector<uint8_t>{0b00011111}),
|
||||
std::make_tuple(10, 2 * 64, std::vector<uint8_t>{0xFF, 0b00000011}),
|
||||
@@ -264,11 +266,13 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false",
|
||||
// expected_digital_part
|
||||
auto parameters = GENERATE(
|
||||
std::make_tuple(5, std::vector<int>{1, 4, 5}, 5,
|
||||
std::vector<uint8_t>{0b00000111}),
|
||||
std::vector<uint8_t>{0b00000010}),
|
||||
std::make_tuple(5, std::vector<int>{1, 5, 4}, 5,
|
||||
std::vector<uint8_t>{0b00000100}),
|
||||
std::make_tuple(5, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60, 39}, 10,
|
||||
std::vector<uint8_t>{0xFF, 0b00000001}),
|
||||
std::vector<uint8_t>{0b11110000, 0b00000000}),
|
||||
std::make_tuple(5, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60}, 5,
|
||||
std::vector<uint8_t>{0xFF}));
|
||||
std::vector<uint8_t>{0b11110000}));
|
||||
|
||||
size_t num_samples, expected_num_digital_bytes;
|
||||
std::vector<uint8_t> expected_digital_part;
|
||||
@@ -281,7 +285,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false",
|
||||
generaldata->SetCtbDbitReorder(false);
|
||||
|
||||
set_num_samples(num_samples);
|
||||
set_data();
|
||||
set_data(0b01010101); // set digital data to 0x55 to have alternating bits
|
||||
|
||||
size_t expected_size =
|
||||
num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes;
|
||||
@@ -316,11 +320,15 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true",
|
||||
// expected_digital_part
|
||||
auto parameters = GENERATE(
|
||||
std::make_tuple(5, std::vector<int>{1, 4, 5}, 3,
|
||||
std::vector<uint8_t>{0b00011111}),
|
||||
std::vector<uint8_t>{0x00, 0b00011111, 0x00}),
|
||||
std::make_tuple(5, std::vector<int>{1, 5, 4}, 3,
|
||||
std::vector<uint8_t>{0x00, 0x00, 0b00011111}),
|
||||
std::make_tuple(10, std::vector<int>{1, 4, 5}, 6,
|
||||
std::vector<uint8_t>{0xFF, 0b00000011}),
|
||||
std::vector<uint8_t>{0x00, 0x00, 0b11111111, 0b00000011,
|
||||
0x00, 0x00}),
|
||||
std::make_tuple(8, std::vector<int>{1, 5, 3, 7, 8, 50, 42, 60, 39}, 9,
|
||||
std::vector<uint8_t>{0xFF}));
|
||||
std::vector<uint8_t>{0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x00}));
|
||||
|
||||
size_t num_samples, expected_num_digital_bytes;
|
||||
std::vector<uint8_t> expected_digital_part;
|
||||
@@ -333,7 +341,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true",
|
||||
generaldata->SetCtbDbitReorder(true);
|
||||
|
||||
set_num_samples(num_samples);
|
||||
set_data();
|
||||
set_data(0b01010101);
|
||||
|
||||
size_t expected_size =
|
||||
num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes;
|
||||
@@ -343,11 +351,8 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true",
|
||||
|
||||
memset(expected_data, dummy_value, num_analog_bytes);
|
||||
|
||||
for (size_t sample = 0; sample < bitlist.size(); ++sample) {
|
||||
memcpy(expected_data + num_analog_bytes +
|
||||
expected_digital_part.size() * sample,
|
||||
expected_digital_part.data(), expected_digital_part.size());
|
||||
}
|
||||
memcpy(expected_data + num_analog_bytes, expected_digital_part.data(),
|
||||
expected_digital_part.size());
|
||||
|
||||
memset(expected_data + expected_num_digital_bytes + num_analog_bytes,
|
||||
dummy_value, num_transceiver_bytes);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
|
||||
|
||||
set(SOURCES
|
||||
src/string_utils.cpp
|
||||
src/file_utils.cpp
|
||||
@@ -14,6 +17,7 @@ set(SOURCES
|
||||
src/sls_detector_exceptions.cpp
|
||||
src/md5_helper.cpp
|
||||
src/Version.cpp
|
||||
src/bit_utils.cpp
|
||||
)
|
||||
|
||||
# Header files to install as a part of the library
|
||||
@@ -26,6 +30,7 @@ set(PUBLICHEADERS
|
||||
include/sls/ToString.h
|
||||
include/sls/TypeTraits.h
|
||||
include/sls/TimeHelper.h
|
||||
include/sls/bit_utils.h
|
||||
)
|
||||
|
||||
# Additional headers to be installed if SLS_DEVEL_HEADERS
|
||||
@@ -89,12 +94,17 @@ target_link_libraries(slsSupportObject
|
||||
PUBLIC
|
||||
slsProjectOptions
|
||||
${STD_FS_LIB} # from helpers.cmake
|
||||
Threads::Threads # slsDetector and Receiver need this
|
||||
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
md5sls
|
||||
)
|
||||
|
||||
#RH8 glibc 2.28, RH9 glibc 2.34 linking rt is only needed with glibc < 2.34
|
||||
#but we do it for all Linux builds to avoid too many conditionals
|
||||
target_link_libraries (slsSupportObject PUBLIC $<$<PLATFORM_ID:Linux>:rt>)
|
||||
|
||||
#Treat both vendored and system zmq as interface for receiver binaries
|
||||
if(SLS_USE_SYSTEM_ZMQ)
|
||||
message(STATUS "slsSupportLib using ZEROMQ_TARGET=${ZEROMQ_TARGET}")
|
||||
|
||||
@@ -65,6 +65,7 @@ std::ostream &operator<<(std::ostream &os,
|
||||
std::string ToString(const slsDetectorDefs::pedestalParameters &r);
|
||||
std::ostream &operator<<(std::ostream &os,
|
||||
const slsDetectorDefs::pedestalParameters &r);
|
||||
|
||||
const std::string &ToString(const std::string &s);
|
||||
|
||||
/** Convert std::chrono::duration with specified output unit */
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
namespace sls {
|
||||
template <typename T> std::vector<int> getSetBits(T val) {
|
||||
@@ -18,4 +19,91 @@ template <typename T> std::vector<int> getSetBits(T val) {
|
||||
}
|
||||
return set_bits;
|
||||
}
|
||||
|
||||
class RegisterAddress {
|
||||
private:
|
||||
uint32_t value_{0};
|
||||
|
||||
public:
|
||||
constexpr RegisterAddress() noexcept = default;
|
||||
constexpr explicit RegisterAddress(uint32_t value) : value_(value) {}
|
||||
explicit RegisterAddress(const std::string &value);
|
||||
std::string str() const;
|
||||
constexpr uint32_t value() const noexcept { return value_; }
|
||||
|
||||
constexpr bool operator==(const RegisterAddress &other) const {
|
||||
return (value_ == other.value_);
|
||||
}
|
||||
constexpr bool operator!=(const RegisterAddress &other) const {
|
||||
return (value_ != other.value_);
|
||||
}
|
||||
};
|
||||
|
||||
class BitAddress {
|
||||
private:
|
||||
RegisterAddress addr_{0};
|
||||
uint32_t bitPos_{0};
|
||||
|
||||
public:
|
||||
constexpr BitAddress() noexcept = default;
|
||||
BitAddress(RegisterAddress address, uint32_t bitPosition);
|
||||
BitAddress(const std::string &address, const std::string &bitPosition);
|
||||
std::string str() const;
|
||||
constexpr RegisterAddress address() const noexcept { return addr_; }
|
||||
constexpr uint32_t bitPosition() const noexcept { return bitPos_; }
|
||||
|
||||
constexpr bool operator==(const BitAddress &other) const {
|
||||
return (addr_ == other.addr_ && bitPos_ == other.bitPos_);
|
||||
}
|
||||
constexpr bool operator!=(const BitAddress &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
class RegisterValue {
|
||||
private:
|
||||
uint32_t value_{0};
|
||||
|
||||
public:
|
||||
constexpr RegisterValue() noexcept = default;
|
||||
explicit constexpr RegisterValue(uint32_t value) noexcept : value_(value) {}
|
||||
explicit RegisterValue(const std::string &value);
|
||||
|
||||
std::string str() const;
|
||||
constexpr uint32_t value() const noexcept { return value_; }
|
||||
|
||||
constexpr RegisterValue &operator|=(const RegisterValue &rhs) noexcept {
|
||||
value_ |= rhs.value();
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr RegisterValue operator|(const RegisterValue &rhs) const noexcept {
|
||||
RegisterValue tmp(*this);
|
||||
tmp |= rhs;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
constexpr RegisterValue &operator|=(uint32_t rhs) noexcept {
|
||||
value_ |= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr RegisterValue operator|(uint32_t rhs) const noexcept {
|
||||
RegisterValue tmp(*this);
|
||||
tmp |= rhs;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
constexpr bool operator==(const RegisterValue &other) const noexcept {
|
||||
return value_ == other.value_;
|
||||
}
|
||||
constexpr bool operator!=(const RegisterValue &other) const noexcept {
|
||||
return value_ != other.value_;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const RegisterAddress &r);
|
||||
std::ostream &operator<<(std::ostream &os, const BitAddress &r);
|
||||
std::ostream &operator<<(std::ostream &os, const RegisterValue &r);
|
||||
|
||||
} // namespace sls
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@@ -155,6 +156,10 @@ template <typename Container> bool hasDuplicates(Container c) {
|
||||
return pos != c.end(); // if we found something there are duplicates
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sorts the container and removes duplicated elements
|
||||
* returns true if elements were removed otherwiese false
|
||||
*/
|
||||
template <typename T>
|
||||
typename std::enable_if<is_container<T>::value, bool>::type
|
||||
removeDuplicates(T &c) {
|
||||
@@ -167,6 +172,27 @@ removeDuplicates(T &c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removed duplicated entries while preserving the oder
|
||||
* returns true if elements were removed otherwiese false
|
||||
*/
|
||||
template <typename T>
|
||||
typename std::enable_if<is_container<T>::value, bool>::type
|
||||
stableRemoveDuplicates(T &c) {
|
||||
auto containerSize = c.size();
|
||||
std::set<typename T::value_type> seen;
|
||||
c.erase(std::remove_if(
|
||||
c.begin(), c.end(),
|
||||
[&](const typename T::value_type &val) {
|
||||
return !seen.insert(val).second; // erase if already seen
|
||||
}),
|
||||
c.end());
|
||||
if (c.size() != containerSize) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
||||
#endif // CONTAINER_UTILS_H
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -33,6 +34,35 @@ void strcpy_safe(char (&destination)[array_size], const std::string &source) {
|
||||
destination[array_size - 1] = '\0';
|
||||
}
|
||||
|
||||
// Runtime-checked variant — throws if it won't fit
|
||||
template <size_t array_size>
|
||||
void strcpy_checked(char (&destination)[array_size], const char *source) {
|
||||
if (!source)
|
||||
throw std::runtime_error("Null source pointer in strcpy_checked");
|
||||
|
||||
size_t len = std::strlen(source);
|
||||
if (len >= (array_size - 1)) {
|
||||
throw std::runtime_error("String length (" + std::to_string(len) +
|
||||
") should be less than " +
|
||||
std::to_string(array_size - 1) + " chars");
|
||||
}
|
||||
std::strncpy(destination, source, array_size - 1);
|
||||
destination[array_size - 1] = '\0';
|
||||
}
|
||||
|
||||
template <size_t array_size>
|
||||
void strcpy_checked(char (&destination)[array_size],
|
||||
const std::string &source) {
|
||||
if (source.size() >= (array_size - 1)) {
|
||||
throw std::runtime_error("String length (" +
|
||||
std::to_string(source.size()) +
|
||||
") should be less than " +
|
||||
std::to_string(array_size - 1) + " chars");
|
||||
}
|
||||
std::strncpy(destination, source.c_str(), array_size - 1);
|
||||
destination[array_size - 1] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
Removes all occurrences of the specified char from a c string
|
||||
Templated on array size to ensure no access after buffer limits.
|
||||
@@ -58,6 +88,8 @@ std::vector<std::string> split(const std::string &strToSplit, char delimeter);
|
||||
std::string RemoveUnit(std::string &str);
|
||||
|
||||
bool is_int(const std::string &s);
|
||||
/** '0x200' is also an int here */
|
||||
bool is_hex_or_dec_uint(const std::string &s);
|
||||
|
||||
bool replace_first(std::string *s, const std::string &substr,
|
||||
const std::string &repl);
|
||||
|
||||
69
slsSupportLib/src/bit_utils.cpp
Normal file
69
slsSupportLib/src/bit_utils.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
RegisterAddress::RegisterAddress(const std::string &value) {
|
||||
if (!is_hex_or_dec_uint(value)) {
|
||||
throw RuntimeError("Address must be an integer value.");
|
||||
}
|
||||
value_ = StringTo<uint32_t>(value);
|
||||
}
|
||||
|
||||
std::string RegisterAddress::str() const { return ToStringHex(value_); }
|
||||
|
||||
BitAddress::BitAddress(RegisterAddress address, uint32_t bitPosition)
|
||||
: addr_(address) {
|
||||
if (bitPosition > 31) {
|
||||
throw RuntimeError("Bit position must be between 0 and 31.");
|
||||
}
|
||||
bitPos_ = bitPosition;
|
||||
}
|
||||
|
||||
BitAddress::BitAddress(const std::string &address,
|
||||
const std::string &bitPosition) {
|
||||
addr_ = RegisterAddress(address);
|
||||
if (!is_hex_or_dec_uint(bitPosition)) {
|
||||
throw RuntimeError("Bit position must be an integer value.");
|
||||
}
|
||||
uint32_t bitPos = StringTo<uint32_t>(bitPosition);
|
||||
if (bitPos > 31) {
|
||||
throw RuntimeError("Bit position must be between 0 and 31.");
|
||||
}
|
||||
bitPos_ = bitPos;
|
||||
}
|
||||
|
||||
std::string BitAddress::str() const {
|
||||
std::ostringstream os;
|
||||
os << '[' << addr_.str() << ", " << ToString(bitPos_) << ']';
|
||||
return os.str();
|
||||
}
|
||||
|
||||
RegisterValue::RegisterValue(const std::string &value) {
|
||||
if (!is_hex_or_dec_uint(value)) {
|
||||
throw RuntimeError("Value must be an integer value.");
|
||||
}
|
||||
value_ = StringTo<uint32_t>(value);
|
||||
}
|
||||
|
||||
std::string RegisterValue::str() const { return ToStringHex(value_); }
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const RegisterAddress &r) {
|
||||
os << r.str();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const BitAddress &r) {
|
||||
os << r.str();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const RegisterValue &r) {
|
||||
os << r.str();
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -256,24 +256,22 @@ std::string getAbsolutePathFromCurrentProcess(const std::string &fname) {
|
||||
return fname;
|
||||
}
|
||||
|
||||
//in case PATH_MAX defines the longest possible path on linux and macOS
|
||||
//use string instead of char array to avoid overflow
|
||||
std::string path(PATH_MAX, '\0');
|
||||
// in case PATH_MAX defines the longest possible path on linux and macOS
|
||||
// use string instead of char array to avoid overflow
|
||||
std::string path(PATH_MAX, '\0');
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__)
|
||||
uint32_t size = PATH_MAX;
|
||||
if (_NSGetExecutablePath(path.data(), &size) != 0) {
|
||||
throw std::runtime_error("Failed to get executable path");
|
||||
}
|
||||
// Resolve any symlinks and .. components
|
||||
std::string resolved(PATH_MAX, '\0');
|
||||
std::string resolved(PATH_MAX, '\0');
|
||||
if (!realpath(path.data(), resolved.data())) {
|
||||
throw std::runtime_error("realpath failed for executable");
|
||||
}
|
||||
path = resolved;
|
||||
#else
|
||||
|
||||
#else
|
||||
|
||||
ssize_t len = readlink("/proc/self/exe", path.data(), PATH_MAX - 1);
|
||||
if (len < 0) {
|
||||
@@ -281,7 +279,7 @@ std::string getAbsolutePathFromCurrentProcess(const std::string &fname) {
|
||||
}
|
||||
path[len] = '\0';
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// get dir path and attach file name
|
||||
std::string absPath = (std::string(dirname(path.data())) + '/' + fname);
|
||||
|
||||
@@ -179,8 +179,7 @@ IpAddr InterfaceNameToIp(const std::string &ifn) {
|
||||
MacAddr InterfaceNameToMac(const std::string &inf) {
|
||||
|
||||
#ifdef __APPLE__
|
||||
throw RuntimeError(
|
||||
"InterfaceNameToMac not implemented on macOS yet");
|
||||
throw RuntimeError("InterfaceNameToMac not implemented on macOS yet");
|
||||
#else
|
||||
|
||||
// TODO! Copied from genericSocket needs to be refactored!
|
||||
|
||||
@@ -43,6 +43,15 @@ bool is_int(const std::string &s) {
|
||||
}) == s.end();
|
||||
}
|
||||
|
||||
bool is_hex_or_dec_uint(const std::string &s) {
|
||||
try {
|
||||
StringTo<uint32_t>(s);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool replace_first(std::string *s, const std::string &substr,
|
||||
const std::string &repl) {
|
||||
auto pos = s->find(substr);
|
||||
|
||||
@@ -84,8 +84,8 @@ TEST_CASE("Shutdown socket without hanging when waiting for data") {
|
||||
|
||||
// Start a thread and wait for package
|
||||
// if the socket is left open we would block
|
||||
std::future<bool> ret =
|
||||
std::async(std::launch::async, &UdpRxSocket::ReceivePacket, &s, (char *)&buff);
|
||||
std::future<bool> ret = std::async(
|
||||
std::launch::async, &UdpRxSocket::ReceivePacket, &s, (char *)&buff);
|
||||
|
||||
s.Shutdown();
|
||||
auto r = ret.get();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "catch.hpp"
|
||||
#include "sls/bit_utils.h"
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace sls {
|
||||
@@ -42,4 +43,148 @@ TEST_CASE("Get set bits from 523") {
|
||||
REQUIRE(vec == std::vector<int>{0, 1, 3, 9});
|
||||
}
|
||||
|
||||
TEST_CASE("Convert RegisterAddress using classes ", "[support][.bit_utils]") {
|
||||
std::vector<uint32_t> vec_addr{0x305, 0xffffffff, 0x0, 0x34550987,
|
||||
0x1fff1fff};
|
||||
std::vector<std::string> vec_ans{"0x305", "0xffffffff", "0x0", "0x34550987",
|
||||
"0x1fff1fff"};
|
||||
|
||||
for (size_t i = 0; i != vec_addr.size(); ++i) {
|
||||
auto reg0 = RegisterAddress(vec_addr[i]);
|
||||
auto reg1 = RegisterAddress(vec_ans[i]);
|
||||
auto reg2 = RegisterAddress(vec_addr[0]);
|
||||
|
||||
CHECK(reg0 == reg1);
|
||||
if (i != 0)
|
||||
CHECK(reg2 != reg1);
|
||||
CHECK(reg0.value() == vec_addr[i]);
|
||||
CHECK(reg1.value() == vec_addr[i]);
|
||||
CHECK(reg0.str() == vec_ans[i]);
|
||||
CHECK(reg1.str() == vec_ans[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Convert RegisterValue using classes ", "[support][.bit_utils]") {
|
||||
std::vector<uint32_t> vec_addr{0x305, 0xffffffff, 0x0, 500254562,
|
||||
0x1fff1fff};
|
||||
std::vector<std::string> vec_ans{"0x305", "0xffffffff", "0x0", "0x1dd14762",
|
||||
"0x1fff1fff"};
|
||||
|
||||
for (size_t i = 0; i != vec_addr.size(); ++i) {
|
||||
auto reg0 = RegisterValue(vec_addr[i]);
|
||||
auto reg1 = RegisterValue(vec_ans[i]);
|
||||
auto reg2 = RegisterValue(vec_addr[0]);
|
||||
|
||||
CHECK(reg0 == reg1);
|
||||
if (i != 0)
|
||||
CHECK(reg2 != reg1);
|
||||
CHECK(reg0.value() == vec_addr[i]);
|
||||
CHECK(reg1.value() == vec_addr[i]);
|
||||
CHECK(reg0.str() == vec_ans[i]);
|
||||
CHECK(reg1.str() == vec_ans[i]);
|
||||
CHECK((reg0 | 0xffffffffu) == RegisterValue(0xffffffffu));
|
||||
CHECK((reg0 | 0x0) == reg0);
|
||||
CHECK((reg0 | reg1) == reg0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Convert BitAddress using classes", "[support][.bit_utils]") {
|
||||
std::vector<RegisterAddress> vec_addr{
|
||||
RegisterAddress(0x305), RegisterAddress(0xffffffffu),
|
||||
RegisterAddress(0x0), RegisterAddress(0x34550987),
|
||||
RegisterAddress(0x1fff1fff)};
|
||||
std::vector<std::string> vec_addr_str{"0x305", "0xffffffff", "0x0",
|
||||
"0x34550987", "0x1fff1fff"};
|
||||
std::vector<uint32_t> vec_bitpos{0, 15, 31, 7, 23};
|
||||
std::vector<std::string> vec_bitpos_str{"0", "15", "31", "7", "23"};
|
||||
std::vector<std::string> vec_ans{
|
||||
"[0x305, 0]", "[0xffffffff, 15]", "[0x0, 31]",
|
||||
"[0x34550987, 7]", "[0x1fff1fff, 23]",
|
||||
};
|
||||
|
||||
for (size_t i = 0; i != vec_addr.size(); ++i) {
|
||||
auto reg0 = BitAddress(vec_addr[i], vec_bitpos[i]);
|
||||
|
||||
BitAddress reg1(vec_addr_str[i], vec_bitpos_str[i]);
|
||||
CHECK(reg1.address() == vec_addr[i]);
|
||||
CHECK(reg1.bitPosition() == vec_bitpos[i]);
|
||||
|
||||
auto reg2 = BitAddress(vec_addr[0], vec_bitpos[0]);
|
||||
|
||||
CHECK(reg0 == reg1);
|
||||
if (i != 0)
|
||||
CHECK(reg2 != reg1);
|
||||
CHECK(reg0.address() == vec_addr[i]);
|
||||
CHECK(reg1.address() == vec_addr[i]);
|
||||
CHECK(reg0.bitPosition() == vec_bitpos[i]);
|
||||
CHECK(reg1.bitPosition() == vec_bitpos[i]);
|
||||
CHECK(std::to_string(reg0.bitPosition()) == vec_bitpos_str[i]);
|
||||
CHECK(std::to_string(reg1.bitPosition()) == vec_bitpos_str[i]);
|
||||
|
||||
CHECK(reg0.str() == vec_ans[i]);
|
||||
CHECK(reg1.str() == vec_ans[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Output operator gives same result as string",
|
||||
"[support][.bit_utils]") {
|
||||
{
|
||||
RegisterAddress addr{"0x3456af"};
|
||||
std::ostringstream os;
|
||||
os << addr;
|
||||
CHECK(os.str() == "0x3456af");
|
||||
CHECK(os.str() == addr.str());
|
||||
}
|
||||
{
|
||||
BitAddress addr("0x3456af", "15");
|
||||
std::ostringstream os;
|
||||
os << addr;
|
||||
CHECK(os.str() == "[0x3456af, 15]");
|
||||
CHECK(os.str() == addr.str());
|
||||
}
|
||||
{
|
||||
RegisterValue addr{"0x3456af"};
|
||||
std::ostringstream os;
|
||||
os << addr;
|
||||
CHECK(os.str() == "0x3456af");
|
||||
CHECK(os.str() == addr.str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Strange input throws", "[support][.bit_utils]") {
|
||||
REQUIRE_THROWS(RegisterAddress("hej"));
|
||||
// ensure correct exception message
|
||||
try {
|
||||
RegisterAddress("hej");
|
||||
} catch (const std::exception &e) {
|
||||
REQUIRE(std::string(e.what()) == "Address must be an integer value.");
|
||||
}
|
||||
|
||||
REQUIRE_THROWS(BitAddress("0x305", "hej"));
|
||||
// ensure correct exception message
|
||||
try {
|
||||
BitAddress("0x305", "hej");
|
||||
} catch (const std::exception &e) {
|
||||
REQUIRE(std::string(e.what()) ==
|
||||
"Bit position must be an integer value.");
|
||||
}
|
||||
|
||||
REQUIRE_THROWS(BitAddress(RegisterAddress(0x305), 32));
|
||||
// ensure correct exception message
|
||||
try {
|
||||
BitAddress(RegisterAddress(0x305), 32);
|
||||
} catch (const std::exception &e) {
|
||||
REQUIRE(std::string(e.what()) ==
|
||||
"Bit position must be between 0 and 31.");
|
||||
}
|
||||
|
||||
REQUIRE_THROWS(RegisterValue("hej"));
|
||||
// ensure correct exception message
|
||||
try {
|
||||
RegisterValue("hej");
|
||||
} catch (const std::exception &e) {
|
||||
REQUIRE(std::string(e.what()) == "Value must be an integer value.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
||||
@@ -153,13 +153,34 @@ TEST_CASE("check for duplicates in vector of pairs") {
|
||||
REQUIRE(hasDuplicates(vec) == true);
|
||||
}
|
||||
|
||||
TEST_CASE("remove duplicates from vector") {
|
||||
TEST_CASE("sorts the vector and remove duplicates") {
|
||||
std::vector<int> v{5, 6, 5, 3};
|
||||
auto r = removeDuplicates(v);
|
||||
CHECK(r == true); // did indeed remove elements
|
||||
CHECK(v == std::vector<int>{3, 5, 6});
|
||||
}
|
||||
|
||||
TEST_CASE("remove duplicates but keep order") {
|
||||
std::vector<int> v{5, 6, 5, 3};
|
||||
auto r = stableRemoveDuplicates(v);
|
||||
CHECK(r == true); // did indeed remove elements
|
||||
CHECK(v == std::vector<int>{5, 6, 3});
|
||||
}
|
||||
|
||||
TEST_CASE("remove duplicates but keep order, all elements the same ") {
|
||||
std::vector<char> v{'c', 'c', 'c', 'c', 'c', 'c'};
|
||||
auto r = stableRemoveDuplicates(v);
|
||||
CHECK(r == true); // did indeed remove elements
|
||||
CHECK(v == std::vector<char>{'c'});
|
||||
}
|
||||
|
||||
TEST_CASE("remove duplicates but keep order, pattern ") {
|
||||
std::vector<int> v{8, 1, 2, 8, 8, 3, 2};
|
||||
auto r = stableRemoveDuplicates(v);
|
||||
CHECK(r == true); // did indeed remove elements
|
||||
CHECK(v == std::vector<int>{8, 1, 2, 3});
|
||||
}
|
||||
|
||||
TEST_CASE("remove duplicated empty vector") {
|
||||
std::vector<int> v;
|
||||
auto r = removeDuplicates(v);
|
||||
@@ -167,4 +188,11 @@ TEST_CASE("remove duplicated empty vector") {
|
||||
CHECK(v == std::vector<int>{});
|
||||
}
|
||||
|
||||
TEST_CASE("remove duplicated empty vector using stable version") {
|
||||
std::vector<int> v;
|
||||
auto r = stableRemoveDuplicates(v);
|
||||
CHECK(r == false); // no elements to remove
|
||||
CHECK(v == std::vector<int>{});
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
|
||||
@@ -24,7 +24,6 @@ target_link_libraries(tests
|
||||
PUBLIC
|
||||
slsProjectOptions
|
||||
slsSupportStatic
|
||||
pthread
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
)
|
||||
|
||||
@@ -113,7 +113,7 @@ def startTestsForAll(args, fp):
|
||||
startDetectorVirtualServer(server, args.num_mods, fp)
|
||||
startFrameSynchronizerPullSocket(server, fp)
|
||||
startFrameSynchronizer(args.num_mods, fp)
|
||||
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=args.num_mods, num_frames=args.num_frames)
|
||||
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, log_file_fp=fp, num_mods=args.num_mods, num_frames=args.num_frames)
|
||||
loadBasicSettings(name=server, d=d, fp=fp)
|
||||
acquire(fp, d)
|
||||
testFramesCaught(server, d, args.num_frames)
|
||||
|
||||
@@ -18,9 +18,11 @@ from utils_for_test import (
|
||||
RuntimeException,
|
||||
cleanup,
|
||||
startProcessInBackground,
|
||||
startReceiver,
|
||||
startDetectorVirtualServer,
|
||||
connectToVirtualServers,
|
||||
loadBasicSettings,
|
||||
loadConfig,
|
||||
runProcessWithLogFile
|
||||
)
|
||||
|
||||
@@ -28,45 +30,6 @@ LOG_PREFIX_FNAME = '/tmp/slsDetectorPackage_virtual_roi_test'
|
||||
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
|
||||
ROI_TEST_FNAME = LOG_PREFIX_FNAME + '_results_'
|
||||
|
||||
def startReceiver(num_mods, fp):
|
||||
if num_mods == 1:
|
||||
cmd = ['slsReceiver']
|
||||
else:
|
||||
cmd = ['slsMultiReceiver', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)]
|
||||
# in 10.0.0
|
||||
#cmd = ['slsMultiReceiver', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)]
|
||||
startProcessInBackground(cmd, fp)
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def loadConfigForRoi(name, fp, num_mods = 1, num_interfaces = 1):
|
||||
Log(LogLevel.INFO, 'Loading config')
|
||||
Log(LogLevel.INFO, 'Loading config', fp)
|
||||
try:
|
||||
d = connectToVirtualServers(name, num_mods)
|
||||
|
||||
if name == 'jungfrau' or name == 'moench':
|
||||
d.numinterfaces = num_interfaces
|
||||
|
||||
d.udp_dstport = DEFAULT_UDP_DST_PORTNO
|
||||
if name == 'eiger' or name == 'jungfrau' or name == 'moench':
|
||||
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
|
||||
|
||||
d.rx_hostname = 'localhost'
|
||||
d.udp_dstip = 'auto'
|
||||
if name != "eiger":
|
||||
d.udp_srcip = 'auto'
|
||||
if name == 'jungfrau' or name == 'moench':
|
||||
d.udp_dstip2 = 'auto'
|
||||
d.powerchip = 1
|
||||
|
||||
d.frames = 5
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeException(f'Could not load config for {name}. Error: {str(e)}') from e
|
||||
|
||||
return d
|
||||
|
||||
def startTestsForAll(fp):
|
||||
servers = [
|
||||
'eiger',
|
||||
@@ -89,7 +52,7 @@ def startTestsForAll(fp):
|
||||
cleanup(fp)
|
||||
startDetectorVirtualServer(server, nmods, fp)
|
||||
startReceiver(nmods, fp)
|
||||
d = loadConfigForRoi(name=server, fp=fp, num_mods=nmods, num_interfaces=ninterfaces)
|
||||
d = loadConfig(name=server, log_file_fp = fp, num_mods=nmods, num_frames=5, num_interfaces=ninterfaces)
|
||||
loadBasicSettings(name=server, d=d, fp=fp)
|
||||
|
||||
fname = ROI_TEST_FNAME + server + '.txt'
|
||||
|
||||
@@ -63,7 +63,7 @@ def startCmdTestsForAll(args, fp):
|
||||
cleanup(fp)
|
||||
startDetectorVirtualServer(name=server, num_mods=num_mods, fp=fp)
|
||||
startReceiver(num_mods, fp)
|
||||
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=num_mods)
|
||||
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, log_file_fp=fp, num_mods=num_mods)
|
||||
loadBasicSettings(name=server, d=d, fp=fp)
|
||||
runProcessWithLogFile('Cmd Tests (' + args.markers + ') for ' + server, cmd, fp, fname)
|
||||
except Exception as e:
|
||||
|
||||
@@ -16,7 +16,6 @@ SERVER_START_PORTNO=1900
|
||||
|
||||
init(autoreset=True)
|
||||
|
||||
|
||||
class LogLevel(Enum):
|
||||
INFO = 0
|
||||
INFORED = 1
|
||||
@@ -193,32 +192,51 @@ def connectToVirtualServers(name, num_mods, ctb_object=False):
|
||||
|
||||
return d
|
||||
|
||||
def startReceiver(num_mods, fp):
|
||||
if num_mods == 1:
|
||||
cmd = ['slsReceiver']
|
||||
else:
|
||||
cmd = ['slsMultiReceiver', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)]
|
||||
# in 10.0.0
|
||||
#cmd = ['slsMultiReceiver', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)]
|
||||
startProcessInBackground(cmd, fp)
|
||||
time.sleep(1)
|
||||
|
||||
def loadConfig(name, rx_hostname, settingsdir, fp, num_mods = 1, num_frames = 1):
|
||||
|
||||
def loadConfig(name, rx_hostname = 'localhost', settingsdir = None, log_file_fp = None, num_mods = 1, num_frames = 1, num_interfaces = 1):
|
||||
Log(LogLevel.INFO, 'Loading config')
|
||||
Log(LogLevel.INFO, 'Loading config', fp)
|
||||
Log(LogLevel.INFO, 'Loading config', log_file_fp)
|
||||
try:
|
||||
d = connectToVirtualServers(name, num_mods)
|
||||
|
||||
if name == 'jungfrau' or name == 'moench':
|
||||
d.numinterfaces = num_interfaces
|
||||
|
||||
d.udp_dstport = DEFAULT_UDP_DST_PORTNO
|
||||
if name == 'eiger':
|
||||
if name == 'eiger' or name == 'jungfrau' or name == 'moench':
|
||||
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
|
||||
|
||||
d.rx_hostname = rx_hostname
|
||||
|
||||
d.udp_dstip = 'auto'
|
||||
|
||||
if name != "eiger":
|
||||
d.udp_srcip = 'auto'
|
||||
|
||||
if name == "jungfrau" or name == "moench":
|
||||
d.udp_dstip2 = 'auto'
|
||||
|
||||
if name == "jungfrau" or name == "moench" or name == "xilinx_ctb":
|
||||
d.powerchip = 1
|
||||
|
||||
if name == "xilinx_ctb":
|
||||
d.configureTransceiver()
|
||||
|
||||
if name == "eiger":
|
||||
d.trimen = [4500, 5400, 6400]
|
||||
d.settingspath = settingsdir + '/eiger/'
|
||||
d.setThresholdEnergy(4500, detectorSettings.STANDARD)
|
||||
|
||||
if settingsdir is not None and name in ['eiger', 'mythen3']:
|
||||
d.settingspath = settingsdir + '/' + name + '/'
|
||||
d.trimen = [4500, 5400, 6400] if name == 'eiger' else [4000, 6000, 8000, 12000]
|
||||
d.setThresholdEnergy(4500, detectorSettings.STANDARD)
|
||||
|
||||
d.frames = num_frames
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -1,39 +1,14 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#echo $#
|
||||
#if [ $# = 0 ]; then
|
||||
# f=$0
|
||||
#else
|
||||
# f=$1
|
||||
#fi
|
||||
#echo $f
|
||||
if [ "x${BASH_ARGV[0]}" = "x" ]; then
|
||||
#if [ "x$f" = "x" ]; then
|
||||
if [ ! -f this_build_bin_path.sh ]; then
|
||||
f=$0
|
||||
echo "aaaa"
|
||||
#thispath=$(dirname ${BASH_ARGV[0]})
|
||||
thispath=$(dirname $f)
|
||||
p=$(cd ${thispath};pwd);
|
||||
THIS_PATH="$p/build/bin/"
|
||||
# echo "ERROR: must cd where/this/package/is before calling this_path.sh"
|
||||
# echo "Try sourcing it"
|
||||
else
|
||||
echo "bbb"
|
||||
THIS_PATH="$PWD/build/bin/";
|
||||
fi
|
||||
else
|
||||
thispath=$(dirname ${BASH_ARGV[0]})
|
||||
p=$(cd ${thispath};pwd);
|
||||
THIS_PATH="$p/build/bin/"
|
||||
echo "ccc"
|
||||
fi
|
||||
#!/bin/bash
|
||||
|
||||
echo "this_path="$THIS_PATH
|
||||
export PATH=$THIS_PATH:$PATH
|
||||
export LD_LIBRARY_PATH=$THIS_PATH:$LD_LIBRARY_PATH
|
||||
export PYTHONPATH=$THIS_PATH:$PYTHONPATH
|
||||
|
||||
echo "path="$PATH
|
||||
echo "ld_library_path="$LD_LIBRARY_PATH
|
||||
echo "pythonpath="$PYTHON_PATH
|
||||
# Since this script could be sourced, $0 is not sufficent, BASH_SOURCE[0] is necessary
|
||||
SCRIPT_LOCATION="$(realpath ${BASH_SOURCE[0]})"
|
||||
SCRIPT_LOCATION="$(dirname ${SCRIPT_LOCATION})"
|
||||
BUILDBIN_LOCATION="${SCRIPT_LOCATION}/build/bin"
|
||||
|
||||
if [ ! -d "${BUILDBIN_LOCATION}" ]; then
|
||||
echo Cannot find path ${BUILDBIN_LOCATION}
|
||||
else
|
||||
echo Adding ${BUILDBIN_LOCATION} to PATH and PYTHONPATH
|
||||
export PATH=${BUILDBIN_LOCATION}:${PATH}
|
||||
export PYTHONPATH=${BUILDBIN_LOCATION}:${PYTHONPATH}
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user