diff --git a/.gitignore b/.gitignore index 0a79fe941..e627f185f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ bin/ *.out *.toc *.o +*.so .* build RELEASE.txt diff --git a/.travis.yml b/.travis.yml index ed8f4e692..d6cd07a07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,39 +4,25 @@ language: cpp os: linux -env: - matrix: - - CONDA_PY=3.6 - - CONDA_PY=3.7 - - CONDA_PY=3.8 - - -dist: trusty +dist: bionic install: - sudo apt-get update - ldd --version - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" + - source "$HOME/miniconda/etc/profile.d/conda.sh" - rm -f miniconda.sh - hash -r - conda config --set always_yes yes --set changeps1 no - conda config --add channels conda-forge - conda config --add channels slsdetectorgroup - - conda update conda - - conda update --all - - conda install conda-build=3.17 - - conda install anaconda-client - - conda install conda-verify - - # Useful for debugging any issues with conda + - conda update -q conda - conda info -a - - # Replace dep1 dep2 ... with your dependencies - - conda create -q -n test-environment python=$CONDA_PY - - source activate test-environment + # Useful for debugging any issues with conda + - conda create -q -n testenv conda-build anaconda-client conda-verify + - conda activate testenv - conda-build . script: @@ -45,7 +31,7 @@ script: deploy: provider: script - script: find $HOME/miniconda/conda-bld/${TRAVIS_OS_NAME}-64 -name "*.tar.bz2" -exec anaconda -t $CONDA_TOKEN upload --force {} \; + script: find $HOME/miniconda/envs/testenv/conda-bld/${TRAVIS_OS_NAME}-64 -name "*.tar.bz2" -exec anaconda -t $CONDA_TOKEN upload --force {} \; on: branch: developer diff --git a/CMakeLists.txt b/CMakeLists.txt index 45649687e..0b7e23376 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.11) +cmake_minimum_required(VERSION 3.12) project(slsDetectorPackage) set(PROJECT_VERSION 5.0.0) include(CheckIPOSupported) @@ -126,7 +126,7 @@ install(TARGETS slsProjectOptions slsProjectWarnings rapidjson ) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_INSTALL_RPATH "$ORIGIN") +set(CMAKE_INSTALL_RPATH $ORIGIN) # set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) @@ -174,6 +174,7 @@ if (SLS_USE_INTEGRATION_TESTS) endif (SLS_USE_INTEGRATION_TESTS) if (SLS_USE_PYTHON) + set(PYBIND11_CPP_STANDARD -std=c++11) add_subdirectory(libs/pybind11) add_subdirectory(python) endif(SLS_USE_PYTHON) diff --git a/RELEASE.txt b/RELEASE.txt index e69de29bb..492ba483b 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -0,0 +1,2 @@ +Draft +- dr 4, 8, 16 in eiger -> speed 0, 32 stays same (speed 1) diff --git a/conda-recepie/build.sh b/conda-recepie/build.sh index 5791635b4..45607594c 100755 --- a/conda-recepie/build.sh +++ b/conda-recepie/build.sh @@ -1,3 +1,4 @@ + mkdir build mkdir install cd build @@ -6,7 +7,7 @@ cmake .. \ -DCMAKE_INSTALL_PREFIX=install \ -DSLS_USE_TEXTCLIENT=ON \ -DSLS_USE_RECEIVER=ON \ - -DSLS_USE_GUI=OFF \ + -DSLS_USE_GUI=ON \ -DSLS_USE_TESTS=ON \ -DSLS_USE_PYTHON=OFF \ -DCMAKE_BUILD_TYPE=Release \ diff --git a/conda-recepie/build_pylib.sh b/conda-recepie/build_pylib.sh index 0a423dbef..fb8723e22 100755 --- a/conda-recepie/build_pylib.sh +++ b/conda-recepie/build_pylib.sh @@ -1,14 +1,4 @@ -# mkdir $PREFIX/lib -# mkdir $PREFIX/include - - -# #Shared and static libraries -# cp build/bin/_sls_detector* $PREFIX/lib/. - - -# #Binaries -# cp -r build/bin/sls_detector $PREFIX/lib/. - +echo "|<-------- starting python build" cd python -${PYTHON} setup.py install \ No newline at end of file +${PYTHON} setup.py install diff --git a/conda-recepie/conda_build_config.yaml b/conda-recepie/conda_build_config.yaml new file mode 100644 index 000000000..b028cf132 --- /dev/null +++ b/conda-recepie/conda_build_config.yaml @@ -0,0 +1,7 @@ +python: + - 3.6 + - 3.7 + - 3.8 + +numpy: + - 1.17 \ No newline at end of file diff --git a/conda-recepie/copy_ctbgui.sh b/conda-recepie/copy_ctbgui.sh new file mode 100644 index 000000000..91ebc1a6d --- /dev/null +++ b/conda-recepie/copy_ctbgui.sh @@ -0,0 +1,9 @@ +mkdir $PREFIX/lib +mkdir $PREFIX/bin +mkdir $PREFIX/include + + + +cp build/bin/ctbGui $PREFIX/bin/. +cp build/bin/libctbRootLib.so $PREFIX/lib/. + diff --git a/conda-recepie/copy_gui.sh b/conda-recepie/copy_gui.sh index 26ce29890..956ec8073 100755 --- a/conda-recepie/copy_gui.sh +++ b/conda-recepie/copy_gui.sh @@ -1,15 +1,3 @@ - -mkdir $PREFIX/lib +#Copy the GUI mkdir $PREFIX/bin -mkdir $PREFIX/include - -#No libs for gui? - -#Binaries -cp build/bin/gui_client $PREFIX/bin/. cp build/bin/slsDetectorGui $PREFIX/bin/. - - -#Which headers do we need for development?? - -# cp include/some_lib.h $PREFIX/include/. \ No newline at end of file diff --git a/conda-recepie/meta.yaml b/conda-recepie/meta.yaml index a5189b4d8..361e1389a 100755 --- a/conda-recepie/meta.yaml +++ b/conda-recepie/meta.yaml @@ -8,6 +8,7 @@ source: build: number: 1 + binary_relocation: True rpaths: - lib/ @@ -16,10 +17,9 @@ requirements: - {{ compiler('c') }} - {{compiler('cxx')}} - cmake - # - qwt 6.* #require qt5 investigate befor activating gui - # - qt=4.8.7=7 - - zeromq=4.2.5=hfc679d8_5 - - pyzmq + - qwt 6.* + - qt 4.8.* + - zeromq - xorg-libx11 - xorg-libice - xorg-libxext @@ -51,70 +51,46 @@ requirements: outputs: - - name: sls_detector_lib + - name: slsdetlib script: copy_lib.sh - - name: sls_detector + requirements: + run: + - libstdcxx-ng + - libgcc-ng + - zeromq + + - name: slsdet + script: build_pylib.sh requirements: build: + - python - {{ compiler('c') }} - {{compiler('cxx')}} - - python {{ python }} + - {{ pin_subpackage('slsdetlib', exact=True) }} - setuptools - - sls_detector_lib - - pyzmq - - pybind11 2.4 + host: - python - - pybind11 2.4 - - pyzmq - - sls_detector_lib + + run: - libstdcxx-ng - libgcc-ng - run: - python - numpy - - sls_detector_lib=developer - - pyzmq - - libstdcxx-ng - - libgcc-ng + - {{ pin_subpackage('slsdetlib', exact=True) }} + + test: imports: - - sls_detector + - slsdet - # requirements: - # build: - # - {{ compiler('c') }} - # - {{compiler('cxx')}} - - # - name: sls_detector_gui - # version: "refactor" - # script: copy_gui.sh - # requirements: - # build: - # - {{ compiler('c') }} - # - {{compiler('cxx')}} - # - cmake - # - qwt 6.* - # - qt=4.8.7=7 - # - zeromq=4.2.5=hfc679d8_5 - # - pyzmq - # - xorg-libx11 - # - xorg-libice - # - xorg-libxext - # - xorg-libsm - # - xorg-libxau - # - xorg-libxrender - # - xorg-libxfixes - # - {{ cdt('mesa-libgl-devel') }} # [linux] - # - {{ cdt('mesa-libegl-devel') }} # [linux] - # - {{ cdt('mesa-dri-drivers') }} # [linux] - # - {{ cdt('libselinux') }} # [linux] - # - {{ cdt('libxdamage') }} # [linux] - # - {{ cdt('libxxf86vm') }} # [linux] - # run: - # - sls_detector_lib=refactor - # - qwt 6.* - # - qt=4.8.7=7 + - name: slsdetgui + script: copy_gui.sh + requirements: + run: + - {{ pin_subpackage('slsdetlib', exact=True) }} + - qwt 6.* + - qt 4.8.* diff --git a/ctbGui/CMakeLists.txt b/ctbGui/CMakeLists.txt index 79cc58177..1d2e43f56 100644 --- a/ctbGui/CMakeLists.txt +++ b/ctbGui/CMakeLists.txt @@ -71,6 +71,11 @@ target_link_libraries(ctbRootLib PUBLIC ${ROOT_EXE_LINKER_FLAGS} ) +set_target_properties( + ctbRootLib PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + target_link_libraries(ctbGui PUBLIC slsDetectorShared slsSupportLib @@ -80,4 +85,5 @@ target_link_libraries(ctbGui PUBLIC set_target_properties(ctbGui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) \ No newline at end of file diff --git a/docs/src/pyexamples.rst b/docs/src/pyexamples.rst index 7b3eb7b1d..e92d05fd9 100755 --- a/docs/src/pyexamples.rst +++ b/docs/src/pyexamples.rst @@ -12,7 +12,7 @@ file writing etc. .. code-block:: python - from sls_detector import Eiger + from slsdet import Eiger d = Eiger() threshold = range(0, 2000, 200) diff --git a/integrationTests/test-eigerIntegration.cpp b/integrationTests/test-eigerIntegration.cpp index fd7a28050..d0923a964 100644 --- a/integrationTests/test-eigerIntegration.cpp +++ b/integrationTests/test-eigerIntegration.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include "multiSlsDetector.h" +#include "DetectorImpl.h" #include "string_utils.h" #include "tests/globals.h" #include class MultiDetectorFixture { protected: - multiSlsDetector d; + DetectorImpl d; public: MultiDetectorFixture() : d(0, true, true) { diff --git a/integrationTests/test-integrationDectector.cpp b/integrationTests/test-integrationDectector.cpp index 620465f93..ec63afab1 100755 --- a/integrationTests/test-integrationDectector.cpp +++ b/integrationTests/test-integrationDectector.cpp @@ -3,7 +3,7 @@ #include "ClientSocket.h" #include "logger.h" -#include "multiSlsDetector.h" +#include "DetectorImpl.h" #include "slsDetector.h" #include "sls_detector_defs.h" @@ -252,7 +252,7 @@ TEST_CASE( int ratecorr = 125; // pick up multi detector from shm id 0 - multiSlsDetector m(0); + DetectorImpl m(0); // ensure eiger detector type, hostname and online REQUIRE(m.getDetectorTypeAsEnum() == c.type_enum); @@ -302,7 +302,7 @@ TEST_CASE("Chiptestboard Loading Patterns", "[.ctbintegration]") { SingleDetectorConfig c; // pick up multi detector from shm id 0 - multiSlsDetector m(0); + DetectorImpl m(0); // ensure ctb detector type, hostname and online REQUIRE(m.getDetectorTypeAsEnum() == c.type_enum); @@ -387,7 +387,7 @@ TEST_CASE("Chiptestboard Dbit offset, list, sampling, advinvert", "[.ctbintegrat SingleDetectorConfig c; // pick up multi detector from shm id 0 - multiSlsDetector m(0); + DetectorImpl m(0); // ensure ctb detector type, hostname and online REQUIRE(m.getDetectorTypeAsEnum() == c.type_enum); @@ -457,7 +457,7 @@ TEST_CASE("Eiger or Jungfrau startingfnum", "[.eigerintegration][.jungfrauintegr SingleDetectorConfig c; // pick up multi detector from shm id 0 - multiSlsDetector m(0); + DetectorImpl m(0); // ensure ctb detector type, hostname and online REQUIRE(((m.getDetectorTypeAsEnum() == slsDetectorDefs::detectorType::EIGER) || (m.getDetectorTypeAsEnum() == slsDetectorDefs::detectorType::JUNGFRAU))); @@ -495,7 +495,7 @@ TEST_CASE("Eiger readnlines", "[.eigerintegration][readnlines]") { SingleDetectorConfig c; // pick up multi detector from shm id 0 - multiSlsDetector m(0); + DetectorImpl m(0); // ensure detector type, hostname REQUIRE((m.getDetectorTypeAsEnum() == slsDetectorDefs::detectorType::EIGER)); diff --git a/integrationTests/test-integrationMulti.cpp b/integrationTests/test-integrationMulti.cpp index 617b84bbe..491b5ed7d 100755 --- a/integrationTests/test-integrationMulti.cpp +++ b/integrationTests/test-integrationMulti.cpp @@ -1,5 +1,5 @@ #include "catch.hpp" -#include "multiSlsDetector.h" +#include "DetectorImpl.h" #include "string_utils.h" #include "tests/globals.h" #include @@ -9,7 +9,7 @@ using namespace Catch::literals; TEST_CASE("Initialize a multi detector", "[.integration][.multi]") { auto hostnames = sls::split(test::hostname, '+'); - multiSlsDetector d(0, true, true); + DetectorImpl d(0, true, true); d.setHostname(test::hostname.c_str()); CHECK(d.getHostname() == test::hostname); @@ -28,7 +28,7 @@ TEST_CASE("Initialize a multi detector", "[.integration][.multi]") { TEST_CASE("Set and read timers", "[.integration][.multi]") { - multiSlsDetector d(0, true, true); + DetectorImpl d(0, true, true); d.setHostname(test::hostname.c_str()); // FRAME_NUMBER diff --git a/libs/pybind11 b/libs/pybind11 index 80d452484..4f72ef846 160000 --- a/libs/pybind11 +++ b/libs/pybind11 @@ -1 +1 @@ -Subproject commit 80d452484c5409444b0ec19383faa84bb7a4d351 +Subproject commit 4f72ef846fe8453596230ac285eeaa0ce3278bb4 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index df3dd5637..302c9f2cc 100755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,20 +1,22 @@ -pybind11_add_module(_sls_detector +# find_package (Python COMPONENTS Interpreter Development) + +pybind11_add_module(_slsdet src/main.cpp src/enums.cpp src/detector.cpp src/network.cpp ) -target_link_libraries(_sls_detector PUBLIC +target_link_libraries(_slsdet PUBLIC slsDetectorShared slsReceiverShared slsSupportLib - zmq ) + ) -set_target_properties(_sls_detector PROPERTIES +set_target_properties(_slsdet PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) @@ -38,8 +40,8 @@ set( PYTHON_FILES ) foreach(FILE ${PYTHON_FILES}) - configure_file( sls_detector/${FILE} - ${CMAKE_BINARY_DIR}/bin/sls_detector/${FILE} ) + configure_file( slsdet/${FILE} + ${CMAKE_BINARY_DIR}/bin/slsdet/${FILE} ) endforeach(FILE ${PYTHON_FILES}) diff --git a/python/setup.py b/python/setup.py index e09b4b59f..bdf459762 100755 --- a/python/setup.py +++ b/python/setup.py @@ -8,7 +8,7 @@ import sys import setuptools import os -__version__ = 'refactor' +__version__ = 'udp' def get_conda_path(): @@ -19,31 +19,32 @@ def get_conda_path(): return os.environ['CONDA_PREFIX'] -class get_pybind_include(object): - """Helper class to determine the pybind11 include path - The purpose of this class is to postpone importing pybind11 - until it is actually installed, so that the ``get_include()`` - method can be invoked. """ +# class get_pybind_include(object): +# """Helper class to determine the pybind11 include path +# The purpose of this class is to postpone importing pybind11 +# until it is actually installed, so that the ``get_include()`` +# method can be invoked. """ - def __init__(self, user=False): - self.user = user +# def __init__(self, user=False): +# self.user = user - def __str__(self): - import pybind11 - return pybind11.get_include(self.user) +# def __str__(self): +# import pybind11 +# return pybind11.get_include(self.user) ext_modules = [ Extension( - '_sls_detector', + '_slsdet', ['src/main.cpp', 'src/enums.cpp', 'src/detector.cpp', 'src/network.cpp'], include_dirs=[ # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), + # get_pybind_include(), + # get_pybind_include(user=True), + os.path.join('../libs/pybind11/include'), os.path.join(get_conda_path(), 'include/slsDetectorPackage'), ], @@ -109,20 +110,28 @@ class BuildExt(build_ext): opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version()) for ext in self.extensions: ext.extra_compile_args = opts - build_ext.build_extensions(self) + print('**************************************************') + print(ct) + print(opts) + print('**************************************************') + build_ext.build_extensions(self) + + + +def get_shared_lib(): + return [f for f in os.listdir('.') if '_slsdet' in f] setup( - name='sls_detector', + name='slsdet', version=__version__, author='Erik Frojdh', author_email='erik.frojdh@psi.ch', - url='https://github.com/slsdetectorgroup/sls_detector', + url='https://github.com/slsdetectorgroup/slsDetectorPackage', description='Detector API for SLS Detector Group detectors', long_description='', packages=find_packages(exclude=['contrib', 'docs', 'tests']), ext_modules=ext_modules, - install_requires=['pybind11>=2.2'], cmdclass={'build_ext': BuildExt}, zip_safe=False, ) diff --git a/python/sls_detector/__init__.py b/python/sls_detector/__init__.py deleted file mode 100755 index 12e86677b..000000000 --- a/python/sls_detector/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# from .detector import Detector, DetectorError, free_shared_memory -from .eiger import Eiger -from .ctb import Ctb -from .dacs import DetectorDacs, Dac -from .detector import Detector -from .jungfrau import Jungfrau -from .mythen3 import Mythen3 -# from .jungfrau_ctb import JungfrauCTB -# from _sls_detector import DetectorApi - -import _sls_detector - -defs = _sls_detector.slsDetectorDefs -runStatus = _sls_detector.slsDetectorDefs.runStatus -speedLevel = _sls_detector.slsDetectorDefs.speedLevel -timingMode = _sls_detector.slsDetectorDefs.timingMode -dacIndex = _sls_detector.slsDetectorDefs.dacIndex -detectorType = _sls_detector.slsDetectorDefs.detectorType -detectorSettings = _sls_detector.slsDetectorDefs.detectorSettings -readoutMode = _sls_detector.slsDetectorDefs.readoutMode - -IpAddr = _sls_detector.IpAddr -MacAddr = _sls_detector.MacAddr diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py new file mode 100755 index 000000000..3c5216028 --- /dev/null +++ b/python/slsdet/__init__.py @@ -0,0 +1,23 @@ +# from .detector import Detector, DetectorError, free_shared_memory +from .eiger import Eiger +from .ctb import Ctb +from .dacs import DetectorDacs, Dac +from .detector import Detector +from .jungfrau import Jungfrau +from .mythen3 import Mythen3 +# from .jungfrau_ctb import JungfrauCTB +# from _slsdet import DetectorApi + +import _slsdet + +defs = _slsdet.slsDetectorDefs +runStatus = _slsdet.slsDetectorDefs.runStatus +speedLevel = _slsdet.slsDetectorDefs.speedLevel +timingMode = _slsdet.slsDetectorDefs.timingMode +dacIndex = _slsdet.slsDetectorDefs.dacIndex +detectorType = _slsdet.slsDetectorDefs.detectorType +detectorSettings = _slsdet.slsDetectorDefs.detectorSettings +readoutMode = _slsdet.slsDetectorDefs.readoutMode + +IpAddr = _slsdet.IpAddr +MacAddr = _slsdet.MacAddr diff --git a/python/sls_detector/adcs.py b/python/slsdet/adcs.py similarity index 100% rename from python/sls_detector/adcs.py rename to python/slsdet/adcs.py diff --git a/python/sls_detector/ctb.py b/python/slsdet/ctb.py similarity index 95% rename from python/sls_detector/ctb.py rename to python/slsdet/ctb.py index 1c6e695e2..73a2328e7 100644 --- a/python/sls_detector/ctb.py +++ b/python/slsdet/ctb.py @@ -1,8 +1,8 @@ from .detector import Detector from .utils import element_if_equal from .dacs import DetectorDacs -import _sls_detector -dacIndex = _sls_detector.slsDetectorDefs.dacIndex +import _slsdet +dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty class CtbDacs(DetectorDacs): diff --git a/python/sls_detector/dacs.py b/python/slsdet/dacs.py similarity index 97% rename from python/sls_detector/dacs.py rename to python/slsdet/dacs.py index 2291f9c7b..a6d6142ae 100755 --- a/python/sls_detector/dacs.py +++ b/python/slsdet/dacs.py @@ -1,9 +1,9 @@ from .detector_property import DetectorProperty from functools import partial import numpy as np -import _sls_detector +import _slsdet from .detector import freeze -dacIndex = _sls_detector.slsDetectorDefs.dacIndex +dacIndex = _slsdet.slsDetectorDefs.dacIndex class Dac(DetectorProperty): """ This class represents a dac on the detector. One instance handles all diff --git a/python/sls_detector/decorators.py b/python/slsdet/decorators.py similarity index 100% rename from python/sls_detector/decorators.py rename to python/slsdet/decorators.py diff --git a/python/sls_detector/detector.py b/python/slsdet/detector.py similarity index 99% rename from python/sls_detector/detector.py rename to python/slsdet/detector.py index 23f0c94dd..0c49df11e 100755 --- a/python/sls_detector/detector.py +++ b/python/slsdet/detector.py @@ -1,5 +1,5 @@ -from _sls_detector import CppDetectorApi -from _sls_detector import slsDetectorDefs +from _slsdet import CppDetectorApi +from _slsdet import slsDetectorDefs runStatus = slsDetectorDefs.runStatus speedLevel = slsDetectorDefs.speedLevel diff --git a/python/sls_detector/detector_property.py b/python/slsdet/detector_property.py similarity index 100% rename from python/sls_detector/detector_property.py rename to python/slsdet/detector_property.py diff --git a/python/sls_detector/eiger.py b/python/slsdet/eiger.py similarity index 99% rename from python/sls_detector/eiger.py rename to python/slsdet/eiger.py index d2c0f0a12..a451cea66 100755 --- a/python/sls_detector/eiger.py +++ b/python/slsdet/eiger.py @@ -11,8 +11,8 @@ from .detector import Detector # from .adcs import Adc, DetectorAdcs from .dacs import DetectorDacs -import _sls_detector -dacIndex = _sls_detector.slsDetectorDefs.dacIndex +import _slsdet +dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty # from .utils import element_if_equal # from sls_detector.errors import DetectorValueError, DetectorError diff --git a/python/sls_detector/errors.py b/python/slsdet/errors.py similarity index 100% rename from python/sls_detector/errors.py rename to python/slsdet/errors.py diff --git a/python/sls_detector/jungfrau.py b/python/slsdet/jungfrau.py similarity index 95% rename from python/sls_detector/jungfrau.py rename to python/slsdet/jungfrau.py index e05ee7b2a..bd92ac757 100644 --- a/python/sls_detector/jungfrau.py +++ b/python/slsdet/jungfrau.py @@ -9,8 +9,8 @@ from .detector import Detector, freeze # from .adcs import Adc, DetectorAdcs from .dacs import DetectorDacs -import _sls_detector -dacIndex = _sls_detector.slsDetectorDefs.dacIndex +import _slsdet +dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty # @freeze diff --git a/python/sls_detector/lookup.py b/python/slsdet/lookup.py similarity index 100% rename from python/sls_detector/lookup.py rename to python/slsdet/lookup.py diff --git a/python/sls_detector/mythen3.py b/python/slsdet/mythen3.py similarity index 96% rename from python/sls_detector/mythen3.py rename to python/slsdet/mythen3.py index c5205ba1d..0a6e9f173 100644 --- a/python/sls_detector/mythen3.py +++ b/python/slsdet/mythen3.py @@ -9,8 +9,8 @@ from .detector import Detector, freeze # from .adcs import Adc, DetectorAdcs from .dacs import DetectorDacs -import _sls_detector -dacIndex = _sls_detector.slsDetectorDefs.dacIndex +import _slsdet +dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty # vcassh 1200, diff --git a/python/sls_detector/registers.py b/python/slsdet/registers.py similarity index 100% rename from python/sls_detector/registers.py rename to python/slsdet/registers.py diff --git a/python/sls_detector/utils.py b/python/slsdet/utils.py similarity index 95% rename from python/sls_detector/utils.py rename to python/slsdet/utils.py index f59e67c89..4c9fa6c87 100755 --- a/python/sls_detector/utils.py +++ b/python/slsdet/utils.py @@ -5,7 +5,7 @@ but not directly used in controlling the detector from collections import namedtuple -import _sls_detector #C++ lib +import _slsdet #C++ lib import functools @@ -29,7 +29,7 @@ def list_to_bitmask(values): return mask def to_geo(value): - if isinstance(value, _sls_detector.xy): + if isinstance(value, _slsdet.xy): return Geometry(x = value.x, y = value.y) else: raise ValueError("Can only convert sls_detector.xy") diff --git a/python/sphinx/cpp_api.rst b/python/sphinx/cpp_api.rst index 839dbac3f..4d0949a29 100755 --- a/python/sphinx/cpp_api.rst +++ b/python/sphinx/cpp_api.rst @@ -2,7 +2,7 @@ C++ API ===================================================== -.. py:currentmodule:: _sls_detector +.. py:currentmodule:: _slsdet .. autoclass:: DetectorApi :members: diff --git a/python/sphinx/index.rst b/python/sphinx/index.rst index ae114adac..b6422bbb8 100755 --- a/python/sphinx/index.rst +++ b/python/sphinx/index.rst @@ -2,7 +2,7 @@ sls_detector - Python interface for the slsDetectorsPackage ============================================================== sls_detector provide Python bindings to the slsDetectorsPackage using mainly the -multiSlsDetector API. This module contains two parts, a compiled C module to +DetectorImpl API. This module contains two parts, a compiled C module to expose the API and a Python class to offer a more Pythonic interface. diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 4165c9e6d..ddd3e991f 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -610,6 +610,8 @@ void init_det(py::module &m) { py::arg() = Positions{}) .def("writeAdcRegister", &Detector::writeAdcRegister, py::arg(), py::arg(), py::arg() = Positions{}) + .def("getInitialChecks", &Detector::getInitialChecks) + .def("setInitialChecks", &Detector::setInitialChecks, py::arg()) .def("getControlPort", &Detector::getControlPort, py::arg() = Positions{}) .def("setControlPort", &Detector::setControlPort, py::arg(), diff --git a/python/src/main.cpp b/python/src/main.cpp index 2d3c300d6..48bd1bb06 100755 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -19,7 +19,7 @@ void init_enums(py::module &); void init_experimental(py::module &); void init_det(py::module &); void init_network(py::module &); -PYBIND11_MODULE(_sls_detector, m) { +PYBIND11_MODULE(_slsdet, m) { m.doc() = R"pbdoc( C/C++ API ----------------------- diff --git a/python/unit-tests/detector_eiger.py b/python/unit-tests/detector_eiger.py index e17127636..be5d56c61 100755 --- a/python/unit-tests/detector_eiger.py +++ b/python/unit-tests/detector_eiger.py @@ -16,12 +16,12 @@ def d(): def test_acq_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.acq') + m = mocker.patch('_slsdet.DetectorApi.acq') d.acq() m.assert_called_once_with() def test_busy_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getAcquiringFlag') + m = mocker.patch('_slsdet.DetectorApi.getAcquiringFlag') m.return_value = False assert d.busy == False @@ -31,103 +31,103 @@ def test_assign_to_detector_type(d): d.detector_type = 'Eiger' def test_det_type(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDetectorType') + m = mocker.patch('_slsdet.DetectorApi.getDetectorType') m.return_value = 'Eiger' assert d.detector_type == 'Eiger' def test_set_dynamic_range_4(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setDynamicRange') + m = mocker.patch('_slsdet.DetectorApi.setDynamicRange') d.dynamic_range = 4 m.assert_called_with(4) def test_set_dynamic_range_8(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setDynamicRange') + m = mocker.patch('_slsdet.DetectorApi.setDynamicRange') d.dynamic_range = 8 m.assert_called_with(8) def test_set_dynamic_range_16(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setDynamicRange') + m = mocker.patch('_slsdet.DetectorApi.setDynamicRange') d.dynamic_range = 16 m.assert_called_with(16) def test_set_dynamic_range_32(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setDynamicRange') + m = mocker.patch('_slsdet.DetectorApi.setDynamicRange') d.dynamic_range = 32 m.assert_called_with(32) def test_set_dynamic_range_raises_exception(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setDynamicRange') + mocker.patch('_slsdet.DetectorApi.setDynamicRange') with pytest.raises(ValueError): d.dynamic_range = 17 def test_get_dynamic_range_32(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDynamicRange') + m = mocker.patch('_slsdet.DetectorApi.getDynamicRange') m.return_value = 32 dr = d.dynamic_range assert dr == 32 def test_eiger_matrix_reset(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getCounterBit') + m = mocker.patch('_slsdet.DetectorApi.getCounterBit') m.return_value = True assert d.eiger_matrix_reset == True def test_set_eiger_matrix_reset(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setCounterBit') + m = mocker.patch('_slsdet.DetectorApi.setCounterBit') d.eiger_matrix_reset = True m.assert_called_once_with(True) def test_get_exposure_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getExposureTime') + m = mocker.patch('_slsdet.DetectorApi.getExposureTime') m.return_value = 100000000 assert d.exposure_time == 0.1 def test_set_exposure_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setExposureTime') + m = mocker.patch('_slsdet.DetectorApi.setExposureTime') d.exposure_time = 1.5 m.assert_called_once_with(1500000000) def test_set_exposure_time_less_than_zero(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setExposureTime') + mocker.patch('_slsdet.DetectorApi.setExposureTime') with pytest.raises(ValueError): d.exposure_time = -7 def test_get_file_index(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getFileIndex') + m = mocker.patch('_slsdet.DetectorApi.getFileIndex') m.return_value = 8 assert d.file_index == 8 def test_set_file_index(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setFileIndex') + m = mocker.patch('_slsdet.DetectorApi.setFileIndex') d.file_index = 9 m.assert_called_with(9) def test_set_file_index_raises_on_neg(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setFileIndex') + mocker.patch('_slsdet.DetectorApi.setFileIndex') with pytest.raises(ValueError): d.file_index = -9 def test_get_file_name(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getFileName') + m = mocker.patch('_slsdet.DetectorApi.getFileName') d.file_name m.assert_called_once_with() def test_set_file_name(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setFileName') + m = mocker.patch('_slsdet.DetectorApi.setFileName') d.file_name = 'hej' m.assert_called_once_with('hej') def test_get_file_path(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getFilePath') + m = mocker.patch('_slsdet.DetectorApi.getFilePath') d.file_path m.assert_called_once_with() def test_set_file_path_when_path_exists(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setFilePath') + m = mocker.patch('_slsdet.DetectorApi.setFilePath') #To avoid raising an exception because path is not there mock_os = mocker.patch('os.path.exists') mock_os.return_value = True @@ -135,25 +135,25 @@ def test_set_file_path_when_path_exists(d, mocker): m.assert_called_once_with('/path/to/something/') def test_set_file_path_raises_when_not_exists(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setFilePath') + mocker.patch('_slsdet.DetectorApi.setFilePath') mock_os = mocker.patch('os.path.exists') mock_os.return_value = False with pytest.raises(FileNotFoundError): d.file_path = '/path/to/something/' def test_get_file_write(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getFileWrite') + m = mocker.patch('_slsdet.DetectorApi.getFileWrite') m.return_value = False assert d.file_write == False def test_set_file_write(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setFileWrite') + m = mocker.patch('_slsdet.DetectorApi.setFileWrite') d.file_write = True m.assert_called_once_with(True) def test_get_firmware_version(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getFirmwareVersion') + m = mocker.patch('_slsdet.DetectorApi.getFirmwareVersion') m.return_value = 20 assert d.firmware_version == 20 @@ -162,38 +162,38 @@ def test_cannot_set_fw_version(d): d.firmware_version = 20 def test_get_high_voltage_call_signature(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDac') + m = mocker.patch('_slsdet.DetectorApi.getDac') d.high_voltage m.assert_called_once_with('vhighvoltage', -1) def test_get_high_voltage(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDac') + m = mocker.patch('_slsdet.DetectorApi.getDac') m.return_value = 80 assert d.high_voltage == 80 #self._api.setDac('vhighvoltage', -1, voltage) def test_set_high_voltage(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setDac') + m = mocker.patch('_slsdet.DetectorApi.setDac') d.high_voltage = 80 m.assert_called_once_with('vhighvoltage', -1, 80) def test_decode_hostname_two_names(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getHostname') + m = mocker.patch('_slsdet.DetectorApi.getHostname') m.return_value = 'beb059+beb048+' assert d.hostname == ['beb059', 'beb048'] def test_decode_hostname_four_names(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getHostname') + m = mocker.patch('_slsdet.DetectorApi.getHostname') m.return_value = 'beb059+beb048+beb120+beb153+' assert d.hostname == ['beb059', 'beb048', 'beb120', 'beb153'] def test_decode_hostname_blank(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getHostname') + m = mocker.patch('_slsdet.DetectorApi.getHostname') m.return_value = '' assert d.hostname == [] def test_get_image_size_gives_correct_size(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getImageSize') + m = mocker.patch('_slsdet.DetectorApi.getImageSize') m.return_value = (512,1024) im_size = d.image_size assert im_size.rows == 512 @@ -202,7 +202,7 @@ def test_get_image_size_gives_correct_size(d, mocker): def test_load_config(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.readConfigurationFile') + m = mocker.patch('_slsdet.DetectorApi.readConfigurationFile') #To avoid raising an exception because path is not there mock_os = mocker.patch('os.path.isfile') mock_os.return_value = True @@ -210,14 +210,14 @@ def test_load_config(d, mocker): m.assert_called_once_with('/path/to/my/file.config') def test_load_config_raises_when_file_is_not_found(d, mocker): - mocker.patch('_sls_detector.DetectorApi.readConfigurationFile') + mocker.patch('_slsdet.DetectorApi.readConfigurationFile') mock_os = mocker.patch('os.path.isfile') mock_os.return_value = False with pytest.raises(FileNotFoundError): d.load_config('/path/to/my/file.config') def test_load_parameters(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.readParametersFile') + m = mocker.patch('_slsdet.DetectorApi.readParametersFile') #To avoid raising an exception because path is not there mock_os = mocker.patch('os.path.isfile') mock_os.return_value = True @@ -225,7 +225,7 @@ def test_load_parameters(d, mocker): m.assert_called_once_with('/path/to/my/file.par') def test_load_parameters_raises_when_file_is_not_found(d, mocker): - mocker.patch('_sls_detector.DetectorApi.readParametersFile') + mocker.patch('_slsdet.DetectorApi.readParametersFile') mock_os = mocker.patch('os.path.isfile') mock_os.return_value = False with pytest.raises(FileNotFoundError): @@ -233,14 +233,14 @@ def test_load_parameters_raises_when_file_is_not_found(d, mocker): #getDetectorGeometry def test_get_module_geometry_gives_correct_size(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDetectorGeometry') + m = mocker.patch('_slsdet.DetectorApi.getDetectorGeometry') m.return_value = (13,7) g = d.module_geometry assert g.vertical == 7 assert g.horizontal == 13 def test_get_module_geometry_access(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDetectorGeometry') + m = mocker.patch('_slsdet.DetectorApi.getDetectorGeometry') m.return_value = (12,3) assert d.module_geometry[0] == 12 assert d.module_geometry[1] == 3 @@ -248,237 +248,237 @@ def test_get_module_geometry_access(d, mocker): assert d.module_geometry.horizontal == 12 def test_get_n_frames(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getNumberOfFrames') + m = mocker.patch('_slsdet.DetectorApi.getNumberOfFrames') m.return_value = 3 assert d.n_frames == 3 def test_set_n_frames(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setNumberOfFrames') + m = mocker.patch('_slsdet.DetectorApi.setNumberOfFrames') d.n_frames = 9 m.assert_called_once_with(9) def test_set_n_frames_raises_on_neg(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setNumberOfFrames') + mocker.patch('_slsdet.DetectorApi.setNumberOfFrames') with pytest.raises(ValueError): d.n_frames = -1 def test_set_n_frames_raises_on_zero(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setNumberOfFrames') + mocker.patch('_slsdet.DetectorApi.setNumberOfFrames') with pytest.raises(ValueError): d.n_frames = 0 def test_get_n_modules(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getNumberOfDetectors') + m = mocker.patch('_slsdet.DetectorApi.getNumberOfDetectors') m.return_value = 12 assert d.n_modules == 12 def test_get_period_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getPeriod') + m = mocker.patch('_slsdet.DetectorApi.getPeriod') m.return_value = 130000000 assert d.period == 0.13 def test_set_period_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setPeriod') + m = mocker.patch('_slsdet.DetectorApi.setPeriod') d.period = 1.953 m.assert_called_once_with(1953000000) def test_set_period_time_less_than_zero(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setPeriod') + mocker.patch('_slsdet.DetectorApi.setPeriod') with pytest.raises(ValueError): d.period = -7 def test_pulse_chip_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.pulseChip') + m = mocker.patch('_slsdet.DetectorApi.pulseChip') d.pulse_chip(15) m.assert_called_once_with(15) def test_pulse_chip_call_minus_one(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.pulseChip') + m = mocker.patch('_slsdet.DetectorApi.pulseChip') d.pulse_chip(-1) m.assert_called_once_with(-1) def test_pulse_chip_asserts_on_smaller_than_minus_one(d, mocker): - mocker.patch('_sls_detector.DetectorApi.pulseChip') + mocker.patch('_slsdet.DetectorApi.pulseChip') with pytest.raises(ValueError): d.pulse_chip(-3) #--------------------------------------------------------------------subexptime def test_get_sub_exposure_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getSubExposureTime') + m = mocker.patch('_slsdet.DetectorApi.getSubExposureTime') m.return_value = 2370000 assert d.sub_exposure_time == 0.00237 def test_set_sub_exposure_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setSubExposureTime') + m = mocker.patch('_slsdet.DetectorApi.setSubExposureTime') d.sub_exposure_time = 0.002 m.assert_called_once_with(2000000) def test_set_sub_exposure_time_raises_on_zero(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setSubExposureTime') + mocker.patch('_slsdet.DetectorApi.setSubExposureTime') with pytest.raises(ValueError): d.sub_exposure_time = 0 #-------------------------------------------------------------Rate correction def test_get_rate_correction(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getRateCorrection') + m = mocker.patch('_slsdet.DetectorApi.getRateCorrection') m.return_value = [132,129] assert d.rate_correction == [132,129] def test_set_rate_correction(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setRateCorrection') - mock_n = mocker.patch('_sls_detector.DetectorApi.getNumberOfDetectors') + m = mocker.patch('_slsdet.DetectorApi.setRateCorrection') + mock_n = mocker.patch('_slsdet.DetectorApi.getNumberOfDetectors') mock_n.return_value = 3 d.rate_correction = [123,90,50] m.assert_called_once_with([123,90,50]) def test_set_rate_correction_raises_on_wrong_number_of_values(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setRateCorrection') - mock_n = mocker.patch('_sls_detector.DetectorApi.getNumberOfDetectors') + mocker.patch('_slsdet.DetectorApi.setRateCorrection') + mock_n = mocker.patch('_slsdet.DetectorApi.getNumberOfDetectors') mock_n.return_value = 4 with pytest.raises(ValueError): d.rate_correction = [123,90,50] #----------------------------------------------------------------Readout clock def test_get_readout_clock_0(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') m.return_value = 0 assert d.readout_clock == 'Full Speed' def test_get_readout_clock_1(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') m.return_value = 1 assert d.readout_clock == 'Half Speed' def test_get_readout_clock_2(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') m.return_value = 2 assert d.readout_clock == 'Quarter Speed' def test_get_readout_clock_3(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') m.return_value = 3 assert d.readout_clock == 'Super Slow Speed' def test_set_readout_clock_0(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') d.readout_clock = 'Full Speed' m.assert_called_once_with(0) def test_set_readout_clock_1(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') d.readout_clock = 'Half Speed' m.assert_called_once_with(1) def test_set_readout_clock_2(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') d.readout_clock = 'Quarter Speed' m.assert_called_once_with(2) def test_set_readout_clock_3(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') + m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') d.readout_clock = 'Super Slow Speed' m.assert_called_once_with(3) #----------------------------------------------------------------rx_datastream def test_get_rx_datastream(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getRxDataStreamStatus') + m = mocker.patch('_slsdet.DetectorApi.getRxDataStreamStatus') m.return_value = False assert d.rx_datastream == False def test_set_rx_datastream(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setRxDataStreamStatus') + m = mocker.patch('_slsdet.DetectorApi.setRxDataStreamStatus') d.rx_datastream = True m.assert_called_once_with(True) def test_get_rx_zmqip(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') + m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') d.rx_zmqip m.assert_called_once_with('rx_zmqip') def test_get_rx_zmqport_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') + m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') d.rx_zmqport m.assert_called_once_with('rx_zmqport') def test_get_rx_zmqport_decode(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') + m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') m.return_value = '30001+30003+' assert d.rx_zmqport == [30001, 30002, 30003, 30004] def test_get_rx_zmqport_empty(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') + m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') m.return_value = '' assert d.rx_zmqport == [] #--------------------------------------------------------------------status def test_status_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getRunStatus') + m = mocker.patch('_slsdet.DetectorApi.getRunStatus') d.status m.assert_called_once_with() def test_start_acq_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.startAcquisition') + m = mocker.patch('_slsdet.DetectorApi.startAcquisition') d.start_acq() m.assert_called_once_with() def test_stop_acq_call(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.stopAcquisition') + m = mocker.patch('_slsdet.DetectorApi.stopAcquisition') d.stop_acq() m.assert_called_once_with() #--------------------------------------------------------------------subexptime def test_get_sub_exposure_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getSubExposureTime') + m = mocker.patch('_slsdet.DetectorApi.getSubExposureTime') m.return_value = 2370000 assert d.sub_exposure_time == 0.00237 def test_set_sub_exposure_time(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setSubExposureTime') + m = mocker.patch('_slsdet.DetectorApi.setSubExposureTime') d.sub_exposure_time = 0.002 m.assert_called_once_with(2000000) def test_set_sub_exposure_time_raises_on_zero(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setSubExposureTime') + mocker.patch('_slsdet.DetectorApi.setSubExposureTime') with pytest.raises(ValueError): d.sub_exposure_time = 0 #------------------------------------------------------------------timing mode def test_get_timing_mode(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getTimingMode') + m = mocker.patch('_slsdet.DetectorApi.getTimingMode') d.timing_mode m.assert_called_once_with() def test_set_timing_mode(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setTimingMode') + m = mocker.patch('_slsdet.DetectorApi.setTimingMode') d.timing_mode = 'auto' m.assert_called_once_with('auto') #----------------------------------------------------------------vthreshold def test_get_vthreshold(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getDac') + m = mocker.patch('_slsdet.DetectorApi.getDac') d.vthreshold m.assert_called_once_with('vthreshold', -1) def test_set_vthreshold(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setDac') + m = mocker.patch('_slsdet.DetectorApi.setDac') d.vthreshold = 1675 m.assert_called_once_with('vthreshold', -1, 1675) #----------------------------------------------------------------trimbits def test_get_trimbits(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.getAllTrimbits') + m = mocker.patch('_slsdet.DetectorApi.getAllTrimbits') d.trimbits m.assert_called_once_with() def test_set_trimbits(d, mocker): - m = mocker.patch('_sls_detector.DetectorApi.setAllTrimbits') + m = mocker.patch('_slsdet.DetectorApi.setAllTrimbits') d.trimbits = 15 m.assert_called_once_with(15) def test_set_trimbits_raises_outside_range(d, mocker): - mocker.patch('_sls_detector.DetectorApi.setAllTrimbits') + mocker.patch('_slsdet.DetectorApi.setAllTrimbits') with pytest.raises(ValueError): d.trimbits = 69 diff --git a/python/unit-tests/detector_test.py b/python/unit-tests/detector_test.py index 6206204f0..c20bd6f65 100755 --- a/python/unit-tests/detector_test.py +++ b/python/unit-tests/detector_test.py @@ -15,7 +15,7 @@ from pytest_mock import mocker import sys sys.path.append('/home/l_frojdh/slsdetectorgrup/sls_detector') -import _sls_detector +import _slsdet from sls_detector.errors import DetectorValueError, DetectorError from sls_detector.utils import all_equal, element_if_equal @@ -47,7 +47,7 @@ def test_set_counters_single(d, mocker): # def test_busy_call(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getAcquiringFlag') +# m = mocker.patch('_slsdet.DetectorApi.getAcquiringFlag') # m.return_value = False # assert d.busy == False @@ -73,34 +73,34 @@ def test_set_counters_single(d, mocker): # d.detector_type = 'Eiger' # def test_det_type(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getDetectorType') +# m = mocker.patch('_slsdet.DetectorApi.getDetectorType') # m.return_value = 'Eiger' # assert d.detector_type == 'Eiger' # def test_get_exposure_time(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getExposureTime') +# m = mocker.patch('_slsdet.DetectorApi.getExposureTime') # m.return_value = 100000000 # assert d.exposure_time == 0.1 # def test_set_exposure_time(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setExposureTime') +# m = mocker.patch('_slsdet.DetectorApi.setExposureTime') # d.exposure_time = 1.5 # m.assert_called_once_with(1500000000) # def test_set_exposure_time_less_than_zero(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setExposureTime') +# mocker.patch('_slsdet.DetectorApi.setExposureTime') # with pytest.raises(DetectorValueError): # d.exposure_time = -7 # def test_get_file_index(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getFileIndex') +# m = mocker.patch('_slsdet.DetectorApi.getFileIndex') # m.return_value = 8 # assert d.file_index == 8 # def test_set_file_index(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setFileIndex') +# m = mocker.patch('_slsdet.DetectorApi.setFileIndex') # d.file_index = 9 # m.assert_called_with(9) @@ -112,28 +112,28 @@ def test_set_counters_single(d, mocker): # assert d.dynamic_range == -100 # def test_set_file_index_raises_on_neg(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setFileIndex') +# mocker.patch('_slsdet.DetectorApi.setFileIndex') # with pytest.raises(ValueError): # d.file_index = -9 # def test_get_file_name(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getFileName') +# m = mocker.patch('_slsdet.DetectorApi.getFileName') # d.file_name # m.assert_called_once_with() # def test_set_file_name(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setFileName') +# m = mocker.patch('_slsdet.DetectorApi.setFileName') # d.file_name = 'hej' # m.assert_called_once_with('hej') # def test_get_file_path(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getFilePath') +# m = mocker.patch('_slsdet.DetectorApi.getFilePath') # d.file_path # m.assert_called_once_with() # def test_set_file_path_when_path_exists(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setFilePath') +# m = mocker.patch('_slsdet.DetectorApi.setFilePath') # #To avoid raising an exception because path is not there # mock_os = mocker.patch('os.path.exists') # mock_os.return_value = True @@ -141,25 +141,25 @@ def test_set_counters_single(d, mocker): # m.assert_called_once_with('/path/to/something/') # def test_set_file_path_raises_when_not_exists(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setFilePath') +# mocker.patch('_slsdet.DetectorApi.setFilePath') # mock_os = mocker.patch('os.path.exists') # mock_os.return_value = False # with pytest.raises(FileNotFoundError): # d.file_path = '/path/to/something/' # def test_get_file_write(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getFileWrite') +# m = mocker.patch('_slsdet.DetectorApi.getFileWrite') # m.return_value = False # assert d.file_write == False # def test_set_file_write(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setFileWrite') +# m = mocker.patch('_slsdet.DetectorApi.setFileWrite') # d.file_write = True # m.assert_called_once_with(True) # def test_get_firmware_version(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getFirmwareVersion') +# m = mocker.patch('_slsdet.DetectorApi.getFirmwareVersion') # m.return_value = 20 # assert d.firmware_version == 20 @@ -168,38 +168,38 @@ def test_set_counters_single(d, mocker): # d.firmware_version = 20 # def test_get_high_voltage_call_signature(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getDac') +# m = mocker.patch('_slsdet.DetectorApi.getDac') # d.high_voltage # m.assert_called_once_with('vhighvoltage', -1) # def test_get_high_voltage(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getDac') +# m = mocker.patch('_slsdet.DetectorApi.getDac') # m.return_value = 80 # assert d.high_voltage == 80 # #self._api.setDac('vhighvoltage', -1, voltage) # def test_set_high_voltage(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setDac') +# m = mocker.patch('_slsdet.DetectorApi.setDac') # d.high_voltage = 80 # m.assert_called_once_with('vhighvoltage', -1, 80) # def test_decode_hostname_two_names(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getHostname') +# m = mocker.patch('_slsdet.DetectorApi.getHostname') # m.return_value = 'beb059+beb048+' # assert d.hostname == ['beb059', 'beb048'] # def test_decode_hostname_four_names(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getHostname') +# m = mocker.patch('_slsdet.DetectorApi.getHostname') # m.return_value = 'beb059+beb048+beb120+beb153+' # assert d.hostname == ['beb059', 'beb048', 'beb120', 'beb153'] # def test_decode_hostname_blank(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getHostname') +# m = mocker.patch('_slsdet.DetectorApi.getHostname') # m.return_value = '' # assert d.hostname == [] # def test_get_image_size_gives_correct_size(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getImageSize') +# m = mocker.patch('_slsdet.DetectorApi.getImageSize') # m.return_value = (512,1024) # im_size = d.image_size # assert im_size.rows == 512 @@ -208,7 +208,7 @@ def test_set_counters_single(d, mocker): # def test_load_config(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.readConfigurationFile') +# m = mocker.patch('_slsdet.DetectorApi.readConfigurationFile') # #To avoid raising an exception because path is not there # mock_os = mocker.patch('os.path.isfile') # mock_os.return_value = True @@ -216,14 +216,14 @@ def test_set_counters_single(d, mocker): # m.assert_called_once_with('/path/to/my/file.config') # def test_load_config_raises_when_file_is_not_found(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.readConfigurationFile') +# mocker.patch('_slsdet.DetectorApi.readConfigurationFile') # mock_os = mocker.patch('os.path.isfile') # mock_os.return_value = False # with pytest.raises(FileNotFoundError): # d.load_config('/path/to/my/file.config') # def test_load_parameters(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.readParametersFile') +# m = mocker.patch('_slsdet.DetectorApi.readParametersFile') # #To avoid raising an exception because path is not there # mock_os = mocker.patch('os.path.isfile') # mock_os.return_value = True @@ -231,7 +231,7 @@ def test_set_counters_single(d, mocker): # m.assert_called_once_with('/path/to/my/file.par') # def test_load_parameters_raises_when_file_is_not_found(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.readParametersFile') +# mocker.patch('_slsdet.DetectorApi.readParametersFile') # mock_os = mocker.patch('os.path.isfile') # mock_os.return_value = False # with pytest.raises(FileNotFoundError): @@ -239,14 +239,14 @@ def test_set_counters_single(d, mocker): # #getDetectorGeometry # def test_get_module_geometry_gives_correct_size(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getDetectorGeometry') +# m = mocker.patch('_slsdet.DetectorApi.getDetectorGeometry') # m.return_value = (13,7) # g = d.module_geometry # assert g.vertical == 7 # assert g.horizontal == 13 # def test_get_module_geometry_access(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getDetectorGeometry') +# m = mocker.patch('_slsdet.DetectorApi.getDetectorGeometry') # m.return_value = (12,3) # assert d.module_geometry[0] == 12 # assert d.module_geometry[1] == 3 @@ -259,12 +259,12 @@ def test_set_counters_single(d, mocker): # assert t.vertical == 0 # def test_get_n_frames(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getNumberOfFrames') +# m = mocker.patch('_slsdet.DetectorApi.getNumberOfFrames') # m.return_value = 3 # assert d.n_frames == 3 # def test_set_n_frames(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setNumberOfFrames') +# m = mocker.patch('_slsdet.DetectorApi.setNumberOfFrames') # d.n_frames = 9 # m.assert_called_once_with(9) @@ -272,12 +272,12 @@ def test_set_counters_single(d, mocker): # assert d.n_frames == -100 # def test_set_n_frames_raises_on_neg(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setNumberOfFrames') +# mocker.patch('_slsdet.DetectorApi.setNumberOfFrames') # with pytest.raises(DetectorValueError): # d.n_frames = -1 # def test_set_n_frames_raises_on_zero(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setNumberOfFrames') +# mocker.patch('_slsdet.DetectorApi.setNumberOfFrames') # with pytest.raises(DetectorValueError): # d.n_frames = 0 @@ -285,12 +285,12 @@ def test_set_counters_single(d, mocker): # assert d.n_cycles == -100 # def test_set_n_cycles_raises_on_zero(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setCycles') +# mocker.patch('_slsdet.DetectorApi.setCycles') # with pytest.raises(DetectorValueError): # d.n_cycles = 0 # def test_set_n_cycles(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setCycles') +# m = mocker.patch('_slsdet.DetectorApi.setCycles') # d.n_cycles = 56 # m.assert_called_once_with(56) @@ -300,12 +300,12 @@ def test_set_counters_single(d, mocker): # assert d.n_measurements == -100 # def test_set_n_measurements_raises_on_zero(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setNumberOfMeasurements') +# mocker.patch('_slsdet.DetectorApi.setNumberOfMeasurements') # with pytest.raises(DetectorValueError): # d.n_measurements = 0 # def test_set_n_measurements(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setNumberOfMeasurements') +# m = mocker.patch('_slsdet.DetectorApi.setNumberOfMeasurements') # d.n_measurements = 560 # m.assert_called_once_with(560) @@ -313,33 +313,33 @@ def test_set_counters_single(d, mocker): # assert d.n_modules == 0 # def test_get_n_modules(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getNumberOfDetectors') +# m = mocker.patch('_slsdet.DetectorApi.getNumberOfDetectors') # m.return_value = 12 # assert d.n_modules == 12 # def test_get_period_time(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getPeriod') +# m = mocker.patch('_slsdet.DetectorApi.getPeriod') # m.return_value = 130000000 # assert d.period == 0.13 # def test_set_period_time(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setPeriod') +# m = mocker.patch('_slsdet.DetectorApi.setPeriod') # d.period = 1.953 # m.assert_called_once_with(1953000000) # def test_set_period_time_less_than_zero(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setPeriod') +# mocker.patch('_slsdet.DetectorApi.setPeriod') # with pytest.raises(ValueError): # d.period = -7 # def test_get_online(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getOnline') +# m = mocker.patch('_slsdet.DetectorApi.getOnline') # d.online # m.assert_called_once_with() # def test_set_online(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setOnline') +# m = mocker.patch('_slsdet.DetectorApi.setOnline') # d.online = True # m.assert_called_once_with(True) @@ -347,116 +347,116 @@ def test_set_counters_single(d, mocker): # assert d.last_client_ip == '' # def test_last_cliten_ip_call(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getLastClientIP') +# m = mocker.patch('_slsdet.DetectorApi.getLastClientIP') # d.last_client_ip # m.assert_called_once_with() # #-------------------------------------------------------------Rate correction # def test_get_rate_correction(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getRateCorrection') +# m = mocker.patch('_slsdet.DetectorApi.getRateCorrection') # m.return_value = [132,129] # assert d.rate_correction == [132,129] # def test_set_rate_correction(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setRateCorrection') -# mock_n = mocker.patch('_sls_detector.DetectorApi.getNumberOfDetectors') +# m = mocker.patch('_slsdet.DetectorApi.setRateCorrection') +# mock_n = mocker.patch('_slsdet.DetectorApi.getNumberOfDetectors') # mock_n.return_value = 3 # d.rate_correction = [123,90,50] # m.assert_called_once_with([123,90,50]) # def test_set_rate_correction_raises_on_wrong_number_of_values(d, mocker): -# mocker.patch('_sls_detector.DetectorApi.setRateCorrection') -# mock_n = mocker.patch('_sls_detector.DetectorApi.getNumberOfDetectors') +# mocker.patch('_slsdet.DetectorApi.setRateCorrection') +# mock_n = mocker.patch('_slsdet.DetectorApi.getNumberOfDetectors') # mock_n.return_value = 4 # with pytest.raises(ValueError): # d.rate_correction = [123,90,50] # #----------------------------------------------------------------Readout clock # def test_get_readout_clock_0(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') # m.return_value = 0 # assert d.readout_clock == 'Full Speed' # def test_get_readout_clock_1(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') # m.return_value = 1 # assert d.readout_clock == 'Half Speed' # def test_get_readout_clock_2(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') # m.return_value = 2 # assert d.readout_clock == 'Quarter Speed' # def test_get_readout_clock_3(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.getReadoutClockSpeed') # m.return_value = 3 # assert d.readout_clock == 'Super Slow Speed' # def test_set_readout_clock_0(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') # d.readout_clock = 'Full Speed' # m.assert_called_once_with(0) # def test_set_readout_clock_1(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') # d.readout_clock = 'Half Speed' # m.assert_called_once_with(1) # def test_set_readout_clock_2(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') # d.readout_clock = 'Quarter Speed' # m.assert_called_once_with(2) # def test_set_readout_clock_3(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setReadoutClockSpeed') +# m = mocker.patch('_slsdet.DetectorApi.setReadoutClockSpeed') # d.readout_clock = 'Super Slow Speed' # m.assert_called_once_with(3) # #----------------------------------------------------------------rx_datastream # def test_get_rx_datastream(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getRxDataStreamStatus') +# m = mocker.patch('_slsdet.DetectorApi.getRxDataStreamStatus') # m.return_value = False # assert d.rx_datastream == False # def test_set_rx_datastream(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setRxDataStreamStatus') +# m = mocker.patch('_slsdet.DetectorApi.setRxDataStreamStatus') # d.rx_datastream = True # m.assert_called_once_with(True) # def test_get_rx_zmqip(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') +# m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') # d.rx_zmqip # m.assert_called_once_with('rx_zmqip') # def test_get_rx_zmqport_call(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') +# m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') # d.rx_zmqport # m.assert_called_once_with('rx_zmqport') # def test_get_rx_zmqport_decode(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') +# m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') # m.return_value = ['30001', '30003'] # assert d.rx_zmqport == [30001, 30003] # def test_get_rx_zmqport_empty(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getNetworkParameter') +# m = mocker.patch('_slsdet.DetectorApi.getNetworkParameter') # m.return_value = '' # assert d.rx_zmqport == [] # #--------------------------------------------------------------------status # def test_status_call(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getRunStatus') +# m = mocker.patch('_slsdet.DetectorApi.getRunStatus') # d.status # m.assert_called_once_with() # def test_start_detecor(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.startAcquisition') +# m = mocker.patch('_slsdet.DetectorApi.startAcquisition') # d.start_detector() # m.assert_called_once_with() # def test_stop_acq_call(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.stopAcquisition') +# m = mocker.patch('_slsdet.DetectorApi.stopAcquisition') # d.stop_detector() # m.assert_called_once_with() @@ -464,23 +464,23 @@ def test_set_counters_single(d, mocker): # #------------------------------------------------------------------timing mode # def test_get_timing_mode(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getTimingMode') +# m = mocker.patch('_slsdet.DetectorApi.getTimingMode') # d.timing_mode # m.assert_called_once_with() # def test_set_timing_mode(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setTimingMode') +# m = mocker.patch('_slsdet.DetectorApi.setTimingMode') # d.timing_mode = 'auto' # m.assert_called_once_with('auto') # #----------------------------------------------------------------vthreshold # def test_get_vthreshold(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.getDac') +# m = mocker.patch('_slsdet.DetectorApi.getDac') # d.vthreshold # m.assert_called_once_with('vthreshold', -1) # def test_set_vthreshold(d, mocker): -# m = mocker.patch('_sls_detector.DetectorApi.setDac') +# m = mocker.patch('_slsdet.DetectorApi.setDac') # d.vthreshold = 1675 # m.assert_called_once_with('vthreshold', -1, 1675) diff --git a/sample/CMakeLists.txt b/sample/CMakeLists.txt index ff1835f63..a1d2e21c1 100644 --- a/sample/CMakeLists.txt +++ b/sample/CMakeLists.txt @@ -18,4 +18,19 @@ target_link_libraries(result set_target_properties(result PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) \ No newline at end of file +) + +add_executable(udp udp.cpp) +target_link_libraries(udp + slsDetectorShared + slsSupportLib + pthread + rt + fmt +) + +set_target_properties(udp PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + + diff --git a/sample/udp.cpp b/sample/udp.cpp new file mode 100644 index 000000000..dc301ffb9 --- /dev/null +++ b/sample/udp.cpp @@ -0,0 +1,65 @@ +#include "UdpRxSocket.h" +#include "sls_detector_defs.h" +#include +#include +#include +#include +#include "network_utils.h" + +// Assume packages arrive in order + +// Assume frame nr starts from 0 + +using header_t = slsDetectorDefs::sls_detector_header; + +int main() { + fmt::print("Hej!\n"); + + + constexpr ssize_t packet_size = 4144; + constexpr ssize_t payload_size = packet_size - sizeof(header_t); + int port = 50012; + + char * buffer = new char[packet_size]; + + sls::UdpRxSocket s(port, packet_size, "10.1.1.107"); + int n = 0; + while(true){ + // s.ReceiveDataOnly(buffer); + if (s.ReceivePacket()) + std::cout << n++ << std::endl; + } + + // auto header = reinterpret_cast(s.buffer()); + // char *data = s.buffer() + sizeof(header_t); + // fmt::print("buffer start: {}\nheader: {}\ndata: {}\n", fmt::ptr(s.buffer()), + // fmt::ptr(header), fmt::ptr(data)); + + // int n = 0; + + // fmt::print("Buffer size: {}\n", s.buffer_size()); + // std::vector image(n_pixels); + // char *image_data = (char *)image.data(); + // uint64_t frame_nr = 0; + // while (true) { + + // if (s.ReceivePacket()) { + + // // fmt::print("frame: {} pkt: {} dst: {}\n", header->frameNumber, + // // header->packetNumber, header->packetNumber*payload_size); + // if (header->frameNumber != frame_nr) { + // // dispatch frame + // fmt::print("frame {} done! got: {} pkgs\n", frame_nr, n); + // frame_nr = header->frameNumber; + // n = 0; + // std::this_thread::sleep_for(std::chrono::milliseconds(1)); + // } + // ++n; + // memcpy(image_data + header->packetNumber * payload_size, data, + // payload_size); + + // } else { + // std::cout << "timeout\n"; + // } + // } +} \ No newline at end of file diff --git a/slsDetectorCalibration/multiThreadedAnalogDetector.h b/slsDetectorCalibration/multiThreadedAnalogDetector.h index 9a37a62ca..bdfacf455 100644 --- a/slsDetectorCalibration/multiThreadedAnalogDetector.h +++ b/slsDetectorCalibration/multiThreadedAnalogDetector.h @@ -17,7 +17,7 @@ #include #include "analogDetector.h" -#include "circularFifo.h" +#include "CircularFifo.h" #include #include #include diff --git a/slsDetectorGui/CMakeLists.txt b/slsDetectorGui/CMakeLists.txt index 6e52023dc..b0f9e79e4 100755 --- a/slsDetectorGui/CMakeLists.txt +++ b/slsDetectorGui/CMakeLists.txt @@ -1,5 +1,8 @@ set(CMAKE_AUTOMOC ON) +find_package(PNG REQUIRED) +find_package(ZLIB REQUIRED) + set(SOURCES slsDetectorPlotting/src/SlsQt1DPlot.cxx slsDetectorPlotting/src/SlsQt1DZoomer.cxx @@ -89,8 +92,8 @@ target_link_libraries(slsDetectorGui PUBLIC ${QT_QTCORE_LIBRARIES} ${QT_QTGUI_LIBRARIES} ${QWT_LIBRARIES} - png - z + PNG::PNG + ZLIB::ZLIB Qt4::QtOpenGL Qt4::QtSvg ) diff --git a/slsDetectorGui/include/qDrawPlot.h b/slsDetectorGui/include/qDrawPlot.h index c9b95bcc9..b6b8a2b5d 100755 --- a/slsDetectorGui/include/qDrawPlot.h +++ b/slsDetectorGui/include/qDrawPlot.h @@ -160,4 +160,5 @@ class qDrawPlot : public QWidget, private Ui::PlotObject { unsigned int nPixelsY{0}; const static int npixelsx_jctb = 400; int npixelsy_jctb{0}; + uint32_t pixelMask{0}; }; diff --git a/slsDetectorGui/src/qDetectorMain.cpp b/slsDetectorGui/src/qDetectorMain.cpp index 01621fca9..47fda49ec 100755 --- a/slsDetectorGui/src/qDetectorMain.cpp +++ b/slsDetectorGui/src/qDetectorMain.cpp @@ -229,6 +229,7 @@ void qDetectorMain::SetUpDetector(const std::string fName, int multiID) { case slsDetectorDefs::JUNGFRAU: case slsDetectorDefs::MOENCH: case slsDetectorDefs::MYTHEN3: + case slsDetectorDefs::GOTTHARD2: break; default: std::ostringstream os; @@ -446,7 +447,7 @@ void qDetectorMain::ExecuteHelp(QAction *action) { clientVersion + "

" "Common GUI to control the SLS Detectors: " - "Eiger, Gotthard, Jungfrau and Moench.

" + "Eiger, Jungfrau, Mythen3, Gotthard, Gotthard2 and Moench.

" "It can be operated in parallel with the command " "line interface:
" "sls_detector_put,
sls_detector_get,
sls_" diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index 88a56cd64..d7637c3b1 100755 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -52,6 +52,19 @@ qDrawPlot::~qDrawPlot() { void qDrawPlot::SetupWidgetWindow() { detType = det->getDetectorType().squash(); + switch (detType) { + case slsDetectorDefs::JUNGFRAU: + case slsDetectorDefs::MOENCH: + pixelMask = ((1 << 15) - 1); + FILE_LOG(logINFO) << "Pixel Mask: " << std::hex << pixelMask << std::dec; + break; + case slsDetectorDefs::GOTTHARD2: + pixelMask = ((1 << 13) - 1); + FILE_LOG(logINFO) << "Pixel Mask: " << std::hex << pixelMask << std::dec; + break; + default: + break; + } // save try { std::string temp = det->getFilePath().squash("/tmp/"); @@ -317,9 +330,11 @@ void qDrawPlot::SetDataCallBack(bool enable) { FILE_LOG(logINFO) << "Setting data call back to " << std::boolalpha << enable << std::noboolalpha; if (enable) { isPlot = true; + det->setRxZmqDataStream(true); det->registerDataCallback(&(GetDataCallBack), this); } else { isPlot = false; + det->setRxZmqDataStream(false); det->registerDataCallback(nullptr, this); } @@ -879,7 +894,7 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size, int data int halfbyte = 0; char cbyte = '\0'; - // mythen 3 debugging + // mythen3 / gotthard2 debugging int discardBits = numDiscardBits; switch (dr) { @@ -903,14 +918,15 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size, int data case 16: if (detType == slsDetectorDefs::JUNGFRAU || - detType == slsDetectorDefs::MOENCH) { + detType == slsDetectorDefs::MOENCH || + detType == slsDetectorDefs::GOTTHARD2) { // show gain plot if (gaindest != NULL) { for (ichan = 0; ichan < size; ++ichan) { uint16_t temp = (*((u_int16_t *)source)); gaindest[ichan] = ((temp & 0xC000) >> 14); - dest[ichan] = (temp & 0x3FFF); + dest[ichan] = (temp & pixelMask); source += 2; } } @@ -918,7 +934,7 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size, int data // only data plot else { for (ichan = 0; ichan < size; ++ichan) { - dest[ichan] = ((*((u_int16_t *)source)) & 0x3FFF); + dest[ichan] = ((*((u_int16_t *)source)) & pixelMask); source += 2; } } diff --git a/slsDetectorGui/src/qTabAdvanced.cpp b/slsDetectorGui/src/qTabAdvanced.cpp index 61991fe45..e19678940 100755 --- a/slsDetectorGui/src/qTabAdvanced.cpp +++ b/slsDetectorGui/src/qTabAdvanced.cpp @@ -30,6 +30,7 @@ void qTabAdvanced::SetupWidgetWindow() { tab_roi->setEnabled(true); break; case slsDetectorDefs::MYTHEN3: + case slsDetectorDefs::GOTTHARD2: lblDiscardBits->setEnabled(true); spinDiscardBits->setEnabled(true); default: @@ -361,7 +362,7 @@ void qTabAdvanced::SetDetectorUDPIP() { std::string s = dispDetectorUDPIP->text().toAscii().constData(); FILE_LOG(logINFO) << "Setting Detector UDP IP:" << s; try { - det->setSourceUDPIP(s, {comboDetector->currentIndex()}); + det->setSourceUDPIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); } CATCH_HANDLE ("Could not set Detector UDP IP.", "qTabAdvanced::SetDetectorUDPIP", this, &qTabAdvanced::GetDetectorUDPIP) @@ -371,7 +372,7 @@ void qTabAdvanced::SetDetectorUDPMAC() { std::string s = dispDetectorUDPMAC->text().toAscii().constData(); FILE_LOG(logINFO) << "Setting Detector UDP MAC:" << s; try { - det->setSourceUDPMAC(s, {comboDetector->currentIndex()}); + det->setSourceUDPMAC(sls::MacAddr{s}, {comboDetector->currentIndex()}); } CATCH_HANDLE ("Could not set Detector UDP MAC.", "qTabAdvanced::SetDetectorUDPMAC", this, &qTabAdvanced::GetDetectorUDPMAC) @@ -390,7 +391,7 @@ void qTabAdvanced::SetCltZMQIP() { std::string s = dispZMQIP->text().toAscii().constData(); FILE_LOG(logINFO) << "Setting Client ZMQ IP:" << s; try { - det->setClientZmqIp(s, {comboDetector->currentIndex()}); + det->setClientZmqIp(sls::IpAddr{s}, {comboDetector->currentIndex()}); } CATCH_HANDLE ("Could not set Client ZMQ IP.", "qTabAdvanced::SetCltZMQIP", this, &qTabAdvanced::GetCltZMQIP) @@ -431,7 +432,7 @@ void qTabAdvanced::SetRxrUDPIP() { std::string s = dispRxrUDPIP->text().toAscii().constData(); FILE_LOG(logINFO) << "Setting Receiver UDP IP:" << s; try { - det->setDestinationUDPIP(s, {comboDetector->currentIndex()}); + det->setDestinationUDPIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); } CATCH_HANDLE ("Could not set Receiver UDP IP.", "qTabAdvanced::SetRxrUDPIP", this, &qTabAdvanced::GetRxrUDPIP) @@ -441,7 +442,7 @@ void qTabAdvanced::SetRxrUDPMAC() { std::string s = dispRxrUDPMAC->text().toAscii().constData(); FILE_LOG(logINFO) << "Setting Receiver UDP MAC:" << s; try { - det->setDestinationUDPMAC(s, {comboDetector->currentIndex()}); + det->setDestinationUDPMAC(sls::MacAddr{s}, {comboDetector->currentIndex()}); } CATCH_HANDLE ("Could not set Receiver UDP MAC.", "qTabAdvanced::SetRxrUDPMAC", this, &qTabAdvanced::GetRxrUDPMAC) @@ -460,7 +461,7 @@ void qTabAdvanced::SetRxrZMQIP() { std::string s = dispRxrZMQIP->text().toAscii().constData(); FILE_LOG(logINFO) << "Setting Receiver ZMQ IP:" << s; try { - det->setRxZmqIP(s, {comboDetector->currentIndex()}); + det->setRxZmqIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); } CATCH_HANDLE ("Could not set Receiver ZMQ IP.", "qTabAdvanced::SetRxrZMQIP", this, &qTabAdvanced::GetRxrZMQIP) diff --git a/slsDetectorGui/src/qTabDeveloper.cpp b/slsDetectorGui/src/qTabDeveloper.cpp index 6291fb026..1fe5c5332 100755 --- a/slsDetectorGui/src/qTabDeveloper.cpp +++ b/slsDetectorGui/src/qTabDeveloper.cpp @@ -112,7 +112,27 @@ void qTabDeveloper::SetupWidgetWindow() { dacWidgets.push_back(new qDacWidget(this, det, true, "vpl: ", getSLSIndex(detType, tempid++))); dacWidgets.push_back(new qDacWidget(this, det, true, "vtrim: ", getSLSIndex(detType, tempid++))); dacWidgets.push_back(new qDacWidget(this, det, true, "vdcsh: ", getSLSIndex(detType, tempid++))); - break; + break; + + case slsDetectorDefs::GOTTHARD2: + lblSpinHV->show(); + spinHV->show(); + hvmin = 0; + dacWidgets.push_back(new qDacWidget(this, det, true, "vref_h_adc: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vb_comp_fe: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vb_comp_adc: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vcom_cds: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vref_rstore: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vb_opa_1st: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vref_comp_fe: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vcom_adc1: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vref_prech: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vref_l_adc: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vref_cds: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vb_cs: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vb_opa_fd: ", getSLSIndex(detType, tempid++))); + dacWidgets.push_back(new qDacWidget(this, det, true, "vcom_adc2: ", getSLSIndex(detType, tempid++))); + break; default: break; } @@ -367,6 +387,41 @@ slsDetectorDefs::dacIndex qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorTy } break; + case slsDetectorDefs::GOTTHARD2: + switch (index) { + case 0: + return slsDetectorDefs::VREF_H_ADC; + case 1: + return slsDetectorDefs::VB_COMP_FE; + case 2: + return slsDetectorDefs::VB_COMP_ADC; + case 3: + return slsDetectorDefs::VCOM_CDS; + case 4: + return slsDetectorDefs::VREF_RSTORE; + case 5: + return slsDetectorDefs::VB_OPA_1ST; + case 6: + return slsDetectorDefs::VREF_COMP_FE; + case 7: + return slsDetectorDefs::VCOM_ADC1; + case 8: + return slsDetectorDefs::VREF_PRECH; + case 9: + return slsDetectorDefs::VREF_L_ADC; + case 10: + return slsDetectorDefs::VREF_CDS; + case 11: + return slsDetectorDefs::VB_CS; + case 12: + return slsDetectorDefs::VB_OPA_FD; + case 13: + return slsDetectorDefs::VCOM_ADC2; + default: + throw sls::RuntimeError(std::string("Unknown dac/adc index") + std::to_string(index)); + } + break; + default: throw sls::RuntimeError(std::string("Unknown detector type")); } diff --git a/slsDetectorGui/src/qTabPlot.cpp b/slsDetectorGui/src/qTabPlot.cpp index a43d3f5c8..e9322eafa 100755 --- a/slsDetectorGui/src/qTabPlot.cpp +++ b/slsDetectorGui/src/qTabPlot.cpp @@ -60,6 +60,7 @@ void qTabPlot::SetupWidgetWindow() { switch(det->getDetectorType().squash()) { case slsDetectorDefs::GOTTHARD: case slsDetectorDefs::MYTHEN3: + case slsDetectorDefs::GOTTHARD2: is1d = true; break; case slsDetectorDefs::EIGER: diff --git a/slsDetectorGui/src/qTabSettings.cpp b/slsDetectorGui/src/qTabSettings.cpp index ceb0e3fff..10489db8e 100755 --- a/slsDetectorGui/src/qTabSettings.cpp +++ b/slsDetectorGui/src/qTabSettings.cpp @@ -83,6 +83,11 @@ void qTabSettings::SetupDetectorSettings() { item[(int)FORCESWITCHG1]->setEnabled(true); item[(int)FORCESWITCHG2]->setEnabled(true); break; + case slsDetectorDefs::GOTTHARD2: + item[(int)DYNAMICGAIN]->setEnabled(true); + item[(int)FIXGAIN1]->setEnabled(true); + item[(int)FIXGAIN2]->setEnabled(true); + break; default: FILE_LOG(logDEBUG) << "Unknown detector type. Exiting GUI."; qDefs::Message(qDefs::CRITICAL, diff --git a/slsDetectorServers/ctbDetectorServer/CMakeLists.txt b/slsDetectorServers/ctbDetectorServer/CMakeLists.txt index a6a1ca695..5a45b5557 100644 --- a/slsDetectorServers/ctbDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/ctbDetectorServer/CMakeLists.txt @@ -15,7 +15,7 @@ add_executable(ctbDetectorServer_virtual ../slsDetectorServer/src/INA226.c ../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/MAX1932.c - ../slsDetectorServer/src/programfpga.c + ../slsDetectorServer/src/programFpgaBlackfin.c ) include_directories( diff --git a/slsDetectorServers/ctbDetectorServer/Makefile b/slsDetectorServers/ctbDetectorServer/Makefile index 7aa969f84..ead1d5733 100755 --- a/slsDetectorServers/ctbDetectorServer/Makefile +++ b/slsDetectorServers/ctbDetectorServer/Makefile @@ -12,7 +12,7 @@ DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programfpga.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 10e68bd22..6c00c1135 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 1b1cc46ab..368e3f8ab 100755 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -12,9 +12,6 @@ #include "INA226.h" // i2c #include "ALTERA_PLL.h" // pll #include "blackfin.h" -#ifndef VIRTUAL -#include "programfpga.h" -#endif #include #include // usleep diff --git a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt index f9e195018..655d0a602 100644 --- a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(gotthard2DetectorServer_virtual ../slsDetectorServer/src/LTC2620_Driver.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ASIC_Driver.c + ../slsDetectorServer/src/programFpgaNios.c ) include_directories( diff --git a/slsDetectorServers/gotthard2DetectorServer/Makefile b/slsDetectorServers/gotthard2DetectorServer/Makefile index 8179b3436..13135a08e 100755 --- a/slsDetectorServers/gotthard2DetectorServer/Makefile +++ b/slsDetectorServers/gotthard2DetectorServer/Makefile @@ -12,7 +12,7 @@ DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programFpgaNios.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index c07195ac9..8068bc35f 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index c8c12e068..5906b1672 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -47,9 +47,6 @@ int injectedChannelsIncrement = 0; int vetoReference[NCHIP][NCHAN]; uint8_t adcConfiguration[NCHIP][NADC]; int burstMode = BURST_INTERNAL; -int64_t exptime_ns = 0; -int64_t period_ns = 0; -int64_t nframes = 0; int detPos[2] = {}; int isInitCheckDone() { @@ -252,7 +249,7 @@ u_int16_t getHardwareVersionNumber() { #ifdef VIRTUAL return 0; #endif - return ((bus_r(MCB_SERIAL_NO_REG)));// & HARDWARE_VERSION_NUM_MSK) >> HARDWARE_VERSION_NUM_OFST); + return ((bus_r(MCB_SERIAL_NO_REG) & MCB_SERIAL_NO_VRSN_MSK) >> MCB_SERIAL_NO_VRSN_OFST); } u_int32_t getDetectorNumber(){ @@ -314,10 +311,14 @@ u_int32_t getDetectorIP(){ /* initialization */ void initControlServer(){ + CreateNotificationForCriticalTasks(); if (initError == OK) { setupDetector(); } initCheckDone = 1; + if (initError == OK) { + NotifyServerStartSuccess(); + } } void initStopServer() { @@ -349,9 +350,6 @@ void setupDetector() { injectedChannelsOffset = 0; injectedChannelsIncrement = 0; burstMode = BURST_INTERNAL; - exptime_ns = 0; - period_ns = 0; - nframes = 0; { int i, j; for (i = 0; i < NUM_CLOCKS; ++i) { @@ -447,10 +445,15 @@ int readConfigFile() { return initError; } + // require a sleep before and after the rst dac signal + usleep (INITIAL_STARTUP_WAIT); + // inform FPGA that onchip dacs will be configured soon FILE_LOG(logINFO, ("Setting configuration starting bit\n")); bus_w(ASIC_CONFIG_REG, bus_r(ASIC_CONFIG_REG) | ASIC_CONFIG_RST_DAC_MSK); + usleep (INITIAL_STARTUP_WAIT); + FILE* fd = fopen(CONFIG_FILE, "r"); if(fd == NULL) { sprintf(initErrorMessage, "Could not open on-board detector server config file [%s].\n", CONFIG_FILE); @@ -723,12 +726,23 @@ int setDynamicRange(int dr){ void setNumFrames(int64_t val) { if (val > 0) { FILE_LOG(logINFO, ("Setting number of frames %lld [local]\n", (long long int)val)); - nframes = val; + // continuous mode + if (burstMode == BURST_OFF) { + setNumFramesCont(val); + setNumFramesBurst(1); + } else { + setNumFramesBurst(val); + setNumFramesCont(1); + } } } int64_t getNumFrames() { - return nframes; + if (burstMode == BURST_OFF) { + return getNumFramesCont(); + } else { + return getNumFramesBurst(); + } } void setNumTriggers(int64_t val) { @@ -748,12 +762,16 @@ int setExpTime(int64_t val) { return FAIL; } FILE_LOG(logINFO, ("Setting exptime %lld ns [local]\n", (long long int)val)); - exptime_ns = val; - return OK; + // continuous mode + if (burstMode == BURST_OFF) { + return setExptimeCont(val); + } else { + return setExptimeBurst(val); + } } int64_t getExpTime() { - return exptime_ns; + return getExptimeBoth(); } int setPeriod(int64_t val) { @@ -762,12 +780,22 @@ int setPeriod(int64_t val) { return FAIL; } FILE_LOG(logINFO, ("Setting period %lld ns [local]\n", (long long int)val)); - period_ns = val; - return OK; + // continuous mode + if (burstMode == BURST_OFF) { + setPeriodBurst(0); + return setPeriodCont(val); + } else { + setPeriodCont(0); + return setPeriodBurst(val); + } } int64_t getPeriod() { - return period_ns; + if (burstMode == BURST_OFF) { + return getPeriodCont(); + } else { + return getPeriodBurst(); + } } void setNumFramesBurst(int64_t val) { @@ -832,6 +860,7 @@ int setPeriodBurst(int64_t val) { } int64_t getPeriodBurst() { + FILE_LOG(logDEBUG, ("Getting period [Burst mode]\n")); return get64BitReg(ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG)/ (1E-9 * clkFrequency[SYSTEM_C0]); } @@ -850,6 +879,7 @@ int setPeriodCont(int64_t val) { } int64_t getPeriodCont() { + FILE_LOG(logDEBUG, ("Getting period [Continuous mode]\n")); return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/ (1E-9 * FIXED_PLL_FREQUENCY); } @@ -1820,84 +1850,24 @@ enum burstMode getBurstMode() { int runmode = bus_r (addr) & ASIC_CONFIG_RUN_MODE_MSK; switch (runmode) { case ASIC_CONFIG_RUN_MODE_CONT_VAL: - return BURST_OFF; + burstMode = BURST_OFF; + break; case ASIC_CONFIG_RUN_MODE_INT_BURST_VAL: - return BURST_INTERNAL; + burstMode = BURST_INTERNAL; + break; case ASIC_CONFIG_RUN_MODE_EXT_BURST_VAL: - return BURST_EXTERNAL; + burstMode = BURST_EXTERNAL; + break; default: FILE_LOG(logERROR, ("Unknown run mode read from FPGA %d\n", runmode)); return -1; } + return burstMode; } /* aquisition */ -int updateAcquisitionRegisters(char* mess) { - // burst mode - if (burstMode != BURST_OFF) { - // validate #frames in burst mode - if (nframes > MAX_FRAMES_IN_BURST_MODE) { - sprintf(mess, "Could not start acquisition because number of frames %lld must be <= %d in burst mode.\n", (long long unsigned int)nframes, MAX_FRAMES_IN_BURST_MODE); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - setNumFramesBurst(nframes); - // exptime - if (setExptimeBurst(exptime_ns) == FAIL) { - sprintf(mess, "Could not start acquisition because exptime could not be set in burst mode. Set %lld ns, got %lld ns.\n", (long long unsigned int)exptime_ns, getExptimeBoth()); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - // period - if (setPeriodBurst(period_ns) == FAIL) { - sprintf(mess, "Could not start acquisition because period could not be set in burst mode. Set %lld ns, got %lld ns.\n", (long long unsigned int)period_ns, getPeriodBurst()); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - - // set continuous values to default (exptime same register) - FILE_LOG(logINFO, ("Setting continuous mode registers to defaults\n")); - // frames - setNumFramesCont(1); - // period - if (setPeriodCont(0) == FAIL) { - sprintf(mess, "Could not start acquisition because period could not be set in continuous mode. Set 0 ns, got %lld ns.\n", getPeriodCont()); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - } - // continuous - else { - // frames - setNumFramesCont(nframes); - // exptime - if (setExptimeCont(exptime_ns) == FAIL) { - sprintf(mess, "Could not start acquisition because exptime could not be set in continuous mode. Set %lld ns, got %lld ns.\n", (long long unsigned int)exptime_ns, getExptimeBoth()); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - // period - if (setPeriodCont(period_ns) == FAIL) { - sprintf(mess, "Could not start acquisition because period could not be set in continuous mode. Set %lld ns, got %lld ns.\n", (long long unsigned int)period_ns, getPeriodCont()); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - - // set burst values to default (exptime same register) - FILE_LOG(logINFO, ("Setting burst mode registers to defaults\n")); - setNumFramesBurst(1); - // period - if (setPeriodBurst(0) == FAIL) { - sprintf(mess, "Could not start acquisition because period could not be set in burst mode. Set 0 ns, got %lld ns.\n", getPeriodBurst()); - FILE_LOG(logERROR,(mess)); - return FAIL; - } - } - return OK; -} - int startStateMachine(){ #ifdef VIRTUAL // create udp socket diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index 2762f353a..c39ad53de 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -27,13 +27,14 @@ #define TYPE_GOTTHARD2_MODULE_VAL (512) #define TYPE_TOLERANCE (10) #define TYPE_NO_MODULE_STARTING_VAL (800) +#define INITIAL_STARTUP_WAIT (1 * 1000 * 1000) /** Default Parameters */ #define DEFAULT_BURST_MODE (BURST_INTERNAL) #define DEFAULT_NUM_FRAMES (1) #define DEFAULT_NUM_CYCLES (1) -#define DEFAULT_EXPTIME (1 * 1000 * 1000) // 1 ms -#define DEFAULT_PERIOD (1 * 1000 * 1000 * 1000) // 1 s +#define DEFAULT_EXPTIME (0) // 0 ms (220ns in firmware) +#define DEFAULT_PERIOD (0) // 0 ms #define DEFAULT_DELAY_AFTER_TRIGGER (0) #define DEFAULT_HIGH_VOLTAGE (0) #define DEFAULT_TIMING_MODE (AUTO_TIMING) diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index 6d01cce02..6f8e56077 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt b/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt index b67445a6f..2d1b5e493 100644 --- a/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt @@ -10,7 +10,7 @@ add_executable(jungfrauDetectorServer_virtual ../slsDetectorServer/src/ALTERA_PLL.c ../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/MAX1932.c - ../slsDetectorServer/src/programfpga.c + ../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/communication_funcs_UDP.c ) @@ -28,7 +28,7 @@ target_compile_definitions(jungfrauDetectorServer_virtual ) target_link_libraries(jungfrauDetectorServer_virtual - PUBLIC pthread rt + PUBLIC pthread rt slsProjectOptions slsProjectWarnings ) set_target_properties(jungfrauDetectorServer_virtual PROPERTIES diff --git a/slsDetectorServers/jungfrauDetectorServer/Makefile b/slsDetectorServers/jungfrauDetectorServer/Makefile index 8e8291bc5..5bde520d0 100755 --- a/slsDetectorServers/jungfrauDetectorServer/Makefile +++ b/slsDetectorServers/jungfrauDetectorServer/Makefile @@ -12,7 +12,7 @@ DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programfpga.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index cdd146df2..8109b2cde 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 02f81256c..6c628adfb 100755 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -8,9 +8,7 @@ #include "ALTERA_PLL.h" // pll #include "blackfin.h" #include "common.h" -#ifndef VIRTUAL -#include "programfpga.h" -#else +#ifdef VIRTUAL #include "communication_funcs_UDP.h" #endif @@ -67,7 +65,6 @@ void basictests() { } return; #else - defineGPIOpins(); resetFPGA(); if (mapCSP0() == FAIL) { diff --git a/slsDetectorServers/moenchDetectorServer/CMakeLists.txt b/slsDetectorServers/moenchDetectorServer/CMakeLists.txt index 4c42361d8..2952e41ac 100644 --- a/slsDetectorServers/moenchDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/moenchDetectorServer/CMakeLists.txt @@ -12,7 +12,7 @@ add_executable(moenchDetectorServer_virtual ../slsDetectorServer/src/ALTERA_PLL.c ../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/MAX1932.c - ../slsDetectorServer/src/programfpga.c + ../slsDetectorServer/src/programFpgaBlackfin.c ) include_directories( diff --git a/slsDetectorServers/moenchDetectorServer/Makefile b/slsDetectorServers/moenchDetectorServer/Makefile index 9ed4d7908..00d7f828e 100755 --- a/slsDetectorServers/moenchDetectorServer/Makefile +++ b/slsDetectorServers/moenchDetectorServer/Makefile @@ -12,7 +12,7 @@ DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programfpga.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index ca7523934..46613a557 100755 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -10,7 +10,7 @@ #include "ALTERA_PLL.h" // pll #include "blackfin.h" #ifndef VIRTUAL -#include "programfpga.h" +#include "programFpgaBlackfin.h" #endif #include diff --git a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt index 687e9de86..feb438fa0 100644 --- a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable(mythen3DetectorServer_virtual ../slsDetectorServer/src/common.c ../slsDetectorServer/src/LTC2620_Driver.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c + ../slsDetectorServer/src/programFpgaNios.c ) include_directories( diff --git a/slsDetectorServers/mythen3DetectorServer/Makefile b/slsDetectorServers/mythen3DetectorServer/Makefile index 4141a0afd..de03fb554 100755 --- a/slsDetectorServers/mythen3DetectorServer/Makefile +++ b/slsDetectorServers/mythen3DetectorServer/Makefile @@ -12,7 +12,7 @@ DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 08bb18c8c..94af96265 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index a2882b1dd..e4c3342d3 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -249,7 +249,7 @@ u_int32_t getDetectorNumber(){ #ifdef VIRTUAL return 0; #endif - return bus_r(MCB_SERIAL_NO_REG); + return ((bus_r(MCB_SERIAL_NO_REG) & MCB_SERIAL_NO_VRSN_MSK) >> MCB_SERIAL_NO_VRSN_OFST); } @@ -303,10 +303,14 @@ u_int32_t getDetectorIP(){ /* initialization */ void initControlServer(){ + CreateNotificationForCriticalTasks(); if (initError == OK) { setupDetector(); } initCheckDone = 1; + if (initError == OK) { + NotifyServerStartSuccess(); + } } void initStopServer() { diff --git a/slsDetectorServers/slsDetectorServer/include/programfpga.h b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h similarity index 91% rename from slsDetectorServers/slsDetectorServer/include/programfpga.h rename to slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h index 090ebca2b..b4dd76fb5 100755 --- a/slsDetectorServers/slsDetectorServer/include/programfpga.h +++ b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h @@ -1,6 +1,7 @@ #pragma once #include +#include /** * Define GPIO pins if not defined @@ -49,4 +50,4 @@ void stopWritingFPGAprogram(FILE* filefp); * @param filefp pointer to flash * @return 0 for success, 1 for fail (cannot write) */ -int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); +int writeFPGAProgram(char* fpgasrc, uint64_t fsize, FILE* filefp); diff --git a/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h b/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h new file mode 100755 index 000000000..bf5ce2b84 --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +#define NIOS_MAX_APP_IMAGE_SIZE (0x00580000) + +/** Notify microcontroller of successful server start up */ +void NotifyServerStartSuccess(); + +/** create notification file to notify watchdog of critical tasks (to not shutdown) */ +void CreateNotificationForCriticalTasks(); + +/** write 1 to notification file to postpone shut down process if requested*/ +void NotifyCriticalTask(); + +/** write 0 to notification file to allow shut down process if requested */ +void NotifyCriticalTaskDone(); + +/** reset fpga and controller(only implemented for >= v1.1 boards) */ +void rebootControllerAndFPGA(); + +/** finds the right mtd drive + * @param mess error message + * @returns ok or fail +*/ +int findFlash(char* mess); + +/** erase flash */ +void eraseFlash(); + +/** erase and write flash + * @param mess error message + * @param fpgasrc program source + * @param fsize file size + * @returns ok or fail + */ +int eraseAndWriteToFlash(char* mess, char* fpgasrc, uint64_t fsize); + +/** + * Write FPGA Program to flash + * @param mess error message + * @param fpgasrc source program + * @param fsize size of program + * @param filefp pointer to flash + * @return ok or fail + */ +int writeFPGAProgram(char* mess, char* fpgasrc, uint64_t fsize, FILE* filefp); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 332cd1bce..44e5cb609 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -366,10 +366,10 @@ int getFrequency(enum CLKINDEX ind); void configureSyncFrequency(enum CLKINDEX ind); void setPipeline(enum CLKINDEX ind, int val); int getPipeline(enum CLKINDEX ind); -extern void eraseFlash(); // programfpga.h -extern int startWritingFPGAprogram(FILE** filefp); // programfpga.h -extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h -extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h +extern void eraseFlash(); // programFpgaBlackfin.h +extern int startWritingFPGAprogram(FILE** filefp); // programFpgaBlackfin.h +extern void stopWritingFPGAprogram(FILE* filefp); // programFpgaBlackfin.h +extern int writeFPGAProgram(char* fpgasrc, uint64_t fsize, FILE* filefp); // programFpgaBlackfin.h // patterns uint64_t writePatternIOControl(uint64_t word); uint64_t writePatternClkControl(uint64_t word); @@ -401,10 +401,10 @@ int validatePhaseinDegrees(enum CLKINDEX ind, int val, int retval); int setThresholdTemperature(int val); int setTemperatureControl(int val); int setTemperatureEvent(int val); -extern void eraseFlash(); // programfpga.h -extern int startWritingFPGAprogram(FILE** filefp); // programfpga.h -extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h -extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h +extern void eraseFlash(); // programFpgaBlackfin.h +extern int startWritingFPGAprogram(FILE** filefp); // programFpgaBlackfin.h +extern void stopWritingFPGAprogram(FILE* filefp); // programFpgaBlackfin.h +extern int writeFPGAProgram(char* fpgasrc, uint64_t fsize, FILE* filefp); // programFpgaBlackfin.h void alignDeserializer(); // eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter @@ -480,7 +480,15 @@ enum burstMode getBurstMode(); #endif - +#if defined(MYTHEN3D) || defined(GOTTHARD2D) +extern void NotifyServerStartSuccess(); +extern void CreateNotificationForCriticalTasks(); +extern void rebootControllerAndFPGA(); // programFpgaNios.h +extern int findFlash(char* mess); // programFpgaNios.h +extern void eraseFlash(); // programFpgaNios.h +extern int eraseAndWriteToFlash(char* mess, char* fpgasrc, uint64_t fsize); // programFpgaNios.h +extern int writeFPGAProgram(char* mess, char* fpgasrc, uint64_t fsize, FILE* filefp); // programFpgaNios.h +#endif #if defined(JUNGFRAUD) || defined(EIGERD) @@ -500,9 +508,6 @@ int setTransmissionDelayRight(int value); // aquisition -#ifdef GOTTHARD2D -int updateAcquisitionRegisters(char* mess); -#endif #ifdef EIGERD int prepareAcquisition(); #endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index f831a9769..4210db940 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -19,7 +19,9 @@ void validate(int arg, int retval, char* modename, enum numberMode nummode); void validate64(int64_t arg, int64_t retval, char* modename, enum numberMode nummode); int executeCommand(char* command, char* result, enum TLogLevel level); int M_nofunc(int); -int M_nofuncMode(int); +#if defined(MYTHEN3D) || defined(GOTTHARD2D) +extern void rebootControllerAndFPGA(); +#endif // functions called by client int exec_command(int); diff --git a/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c b/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c index 91df2f2f1..d716fa2ea 100755 --- a/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c +++ b/slsDetectorServers/slsDetectorServer/src/ASIC_Driver.c @@ -28,14 +28,14 @@ void ASIC_Driver_SetDefines(char* driverfname) { int ASIC_Driver_Set (int index, int length, char* buffer) { char fname[MAX_STR_LENGTH]; sprintf(fname, "%s%d", ASIC_Driver_DriverFileName, index + 1); - FILE_LOG(logDEBUG1, ("\t[chip index: %d, length: %d, fname: %s]\n", index, length, fname)); + FILE_LOG(logDEBUG2, ("\t[chip index: %d, length: %d, fname: %s]\n", index, length, fname)); { - FILE_LOG(logDEBUG1, ("\t[values: \n")); + FILE_LOG(logDEBUG2, ("\t[values: \n")); int i; for (i = 0; i < length; ++i) { - FILE_LOG(logDEBUG1, ("\t%d: 0x%02hhx\n", i, buffer[i])); + FILE_LOG(logDEBUG2, ("\t%d: 0x%02hhx\n", i, buffer[i])); } - FILE_LOG(logDEBUG1, ("\t]\n")); + FILE_LOG(logDEBUG2, ("\t]\n")); } #ifdef VIRTUAL diff --git a/slsDetectorServers/slsDetectorServer/src/communication_funcs.c b/slsDetectorServers/slsDetectorServer/src/communication_funcs.c index a49cb0765..f6f572ea3 100755 --- a/slsDetectorServers/slsDetectorServer/src/communication_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/communication_funcs.c @@ -252,8 +252,9 @@ void closeConnection(int file_des) { } void exitServer(int socketDescriptor) { - if (socketDescriptor >= 0) + if (socketDescriptor >= 0) { close(socketDescriptor); + } FILE_LOG(logINFO, ("Closing %s server\n", (isControlServer ? "control":"stop"))); FD_CLR(socketDescriptor, &readset); isock--; diff --git a/slsDetectorServers/slsDetectorServer/src/programfpga.c b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c similarity index 86% rename from slsDetectorServers/slsDetectorServer/src/programfpga.c rename to slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c index 65a266ce3..98383c923 100755 --- a/slsDetectorServers/slsDetectorServer/src/programfpga.c +++ b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c @@ -1,4 +1,4 @@ -#include "programfpga.h" +#include "programFpgaBlackfin.h" #include "ansi.h" #include "clogger.h" #include "slsDetectorServer_defs.h" @@ -57,6 +57,12 @@ int startWritingFPGAprogram(FILE** filefp){ FILE_LOG(logDEBUG1, ("Start Writing of FPGA program\n")); //getting the drive + //root:/> cat /proc/mtd + //dev: size erasesize name + //mtd0: 00040000 00020000 "bootloader(nor)" + //mtd1: 00100000 00020000 "linux kernel(nor)" + //mtd2: 002c0000 00020000 "file system(nor)" + //mtd3: 01000000 00010000 "bitfile(spi)" char output[255]; memset(output, 0, 255); FILE* fp = popen("awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r"); @@ -120,14 +126,14 @@ void stopWritingFPGAprogram(FILE* filefp){ FILE_LOG(logINFO, ("FPGA has picked up the program from flash\n")); } -int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp){ +int writeFPGAProgram(char* fpgasrc, uint64_t fsize, FILE* filefp){ FILE_LOG(logDEBUG1, ("Writing of FPGA Program\n" "\taddress of fpgasrc:%p\n" - "\tfsize:%lu\n\tpointer:%p\n", - (void *)fpgasrc, fsize, (void*)filefp)); + "\tfsize:%llu\n\tpointer:%p\n", + (void *)fpgasrc, (long long unsigned int)fsize, (void*)filefp)); if(fwrite((void*)fpgasrc , sizeof(char) , fsize , filefp )!= fsize){ - FILE_LOG(logERROR, ("Could not write FPGA source to flash (size:%lu)\n", fsize)); + FILE_LOG(logERROR, ("Could not write FPGA source to flash (size:%llu)\n", (long long unsigned int)fsize)); return 1; } FILE_LOG(logDEBUG1, ("program written to flash\n")); diff --git a/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c b/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c new file mode 100755 index 000000000..cd09f70c3 --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c @@ -0,0 +1,152 @@ +#include "programFpgaNios.h" +#include "ansi.h" +#include "clogger.h" +#include "slsDetectorServer_defs.h" + +#include // usleep +#include + + +/* global variables */ +#define MTDSIZE 10 +char mtdvalue[MTDSIZE] = {0}; +#define NOTIFICATION_FILE "/tmp/block_shutdown" +#define MICROCONTROLLER_FILE "/dev/ttyAL0" + +void NotifyServerStartSuccess() { + FILE_LOG(logINFOBLUE, ("Server started successfully\n")); + char command[255]; + memset(command, 0, 255); + sprintf(command,"echo r > %s",MICROCONTROLLER_FILE); + system(command); +} + +void CreateNotificationForCriticalTasks() { + FILE* fd = fopen(NOTIFICATION_FILE, "r"); + if (fd == NULL) { + fd = fopen(NOTIFICATION_FILE, "w"); + if (fd == NULL) { + FILE_LOG(logERROR, ("Could not create notication file: %s\n", NOTIFICATION_FILE)); + return; + } + FILE_LOG(logINFOBLUE, ("Created notification file: %s\n", NOTIFICATION_FILE)); + } + fclose(fd); + NotifyCriticalTaskDone(); +} + +void NotifyCriticalTask() { + FILE_LOG(logINFO, ("\tNotifying Critical Task Ongoing\n")); + char command[255]; + memset(command, 0, 255); + sprintf(command,"echo 1 > %s",NOTIFICATION_FILE); + system(command); +} + +void NotifyCriticalTaskDone() { + FILE_LOG(logINFO, ("\tNotifying Critical Task Done\n")); + char command[255]; + memset(command, 0, 255); + sprintf(command,"echo 0 > %s",NOTIFICATION_FILE); + system(command); +} + +void rebootControllerAndFPGA() { + FILE_LOG(logDEBUG1, ("Reseting FPGA...\n")); + char command[255]; + memset(command, 0, 255); + sprintf(command,"echo z > %s",MICROCONTROLLER_FILE); + system(command); +} + +int findFlash(char* mess) { + FILE_LOG(logDEBUG1, ("Finding flash drive...\n")); + //getting the drive + // # cat /proc/mtd + // dev: size erasesize name + // mtd0: 00580000 00010000 "qspi BootInfo + Factory Image" + // mtd1: 00580000 00010000 "qspi Application Image" + // mtd2: 00800000 00010000 "qspi Linux Kernel with initramfs" + // mtd3: 00800000 00010000 "qspi Linux Kernel with initramfs Backup" + // mtd4: 02500000 00010000 "qspi ubi filesystem" + // mtd5: 04000000 00010000 "qspi Complete Flash" + char output[255]; + memset(output, 0, 255); + FILE* fp = popen("awk \'$5== \"Application\" {print $1}\' /proc/mtd", "r"); + if (fp == NULL) { + strcpy(mess, "popen returned NULL. Need that to get mtd drive.\n"); + FILE_LOG(logERROR, (mess)); + return RO_TRIGGER_IN_FALLING_EDGE; + } + if (fgets(output, sizeof(output), fp) == NULL) { + strcpy(mess, "fgets returned NULL. Need that to get mtd drive.\n"); + FILE_LOG(logERROR, (mess)); + return FAIL; + } + pclose(fp); + memset(mtdvalue, 0, MTDSIZE); + strcpy(mtdvalue, "/dev/"); + char* pch = strtok(output, ":"); + if (pch == NULL){ + strcpy (mess, "Could not get mtd value\n"); + FILE_LOG(logERROR, (mess)); + return FAIL; + } + strcat(mtdvalue, pch); + FILE_LOG(logINFO, ("\tFlash drive found: %s\n", mtdvalue)); + return OK; +} + +void eraseFlash() { + FILE_LOG(logDEBUG1, ("Erasing Flash...\n")); + char command[255]; + memset(command, 0, 255); + sprintf(command,"flash_erase %s 0 0",mtdvalue); + system(command); + FILE_LOG(logINFO, ("\tFlash erased\n")); +} + +int eraseAndWriteToFlash(char* mess, char* fpgasrc, uint64_t fsize) { + if (findFlash(mess) == FAIL) { + return FAIL; + } + NotifyCriticalTask(); + eraseFlash(); + + // open file pointer to flash + FILE *filefp = fopen(mtdvalue, "w"); + if(filefp == NULL){ + NotifyCriticalTaskDone(); + sprintf (mess, "Unable to open %s in write mode\n", mtdvalue); + FILE_LOG(logERROR, (mess)); + return FAIL; + } + FILE_LOG(logINFO, ("\tFlash ready for writing\n")); + + // write to flash + if (writeFPGAProgram(mess, fpgasrc, fsize, filefp) == FAIL) { + NotifyCriticalTaskDone(); + fclose(filefp); + return FAIL; + } + + fclose(filefp); + NotifyCriticalTaskDone(); + return OK; +} + +int writeFPGAProgram(char* mess, char* fpgasrc, uint64_t fsize, FILE* filefp) { + FILE_LOG(logDEBUG1, ("Writing to flash...\n" + "\taddress of fpgasrc:%p\n" + "\tfsize:%lu\n\tpointer:%p\n", + (void *)fpgasrc, fsize, (void*)filefp)); + + uint64_t retval = fwrite((void*)fpgasrc , sizeof(char) , fsize , filefp); + if (retval != fsize) { + sprintf (mess, "Could not write FPGA source to flash (size:%llu), write %llu\n", (long long unsigned int) fsize, (long long unsigned int)retval); + FILE_LOG(logERROR, (mess)); + return FAIL; + } + FILE_LOG(logINFO, ("\tProgram written to flash\n")); + return OK; +} diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c index b84d7256d..31ff1382c 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c @@ -10,7 +10,7 @@ #include #include - +#include // Global variables from communication_funcs extern int isControlServer; @@ -149,9 +149,13 @@ int main(int argc, char *argv[]){ exitServer(sockfd); if (retval == REBOOT) { - FILE_LOG(logINFOBLUE,("Rebooting!\n")); + FILE_LOG(logINFORED,("Rebooting!\n")); fflush(stdout); +#if defined(MYTHEN3D) || defined(GOTTHARD2D) + rebootControllerAndFPGA(); +#else system("reboot"); +#endif } FILE_LOG(logINFO,("Goodbye!\n")); return 0; diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index bb4af0441..dbb16d36c 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -2,6 +2,13 @@ #include "slsDetectorFunctionList.h" #include "communication_funcs.h" #include "clogger.h" +#ifndef VIRTUAL +#if defined(MYTHEN3D) || defined(GOTTHARD2D) +#include "programFpgaNios.h" +#elif defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) || defined(MOENCHD) +#include "programFpgaBlackfin.h" +#endif +#endif #include #include @@ -594,27 +601,6 @@ int M_nofunc(int file_des) { } -// Jungfrau program mode -int M_nofuncMode(int file_des) { - ret = FAIL; - memset(mess, 0, sizeof(mess)); - - // to receive any arguments - int n = 1; - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - - sprintf(mess,"This Function %s cannot be executed as the " - "On-board detector server in update mode.\n" - "Restart detector server in normal mode (without any arguments) to continue.\n", - getFunctionName((enum detFuncs)fnum)); - FILE_LOG(logERROR, (mess)); - return Server_SendResult(file_des, OTHER, NO_UPDATE, NULL, 0); -} - - - - int exec_command(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -1783,12 +1769,6 @@ int start_acquisition(int file_des) { FILE_LOG(logERROR,(mess)); } else -#endif -#ifdef GOTTHARD2D - if (updateAcquisitionRegisters(mess) == FAIL) { - ret = FAIL; - } - else #endif if (configured == FAIL) { ret = FAIL; @@ -1919,12 +1899,6 @@ int start_and_read_all(int file_des) { FILE_LOG(logERROR,(mess)); } else -#endif -#ifdef GOTTHARD2D - if (updateAcquisitionRegisters(mess) == FAIL) { - ret = FAIL; - } - else #endif if (configured == FAIL) { ret = FAIL; @@ -1991,10 +1965,20 @@ int set_num_frames(int file_des) { // only set if (Server_VerifyLock() == OK) { - setNumFrames(arg); - int64_t retval = getNumFrames(); - FILE_LOG(logDEBUG1, ("retval num frames %lld\n", (long long int)retval)); - validate64(arg, retval, "set number of frames", DEC); +#ifdef GOTTHARD2D + // validate #frames in burst mode + if (getBurstMode() != BURST_OFF && arg > MAX_FRAMES_IN_BURST_MODE) { + ret = FAIL; + sprintf(mess, "Could not set number of frames %lld. Must be <= %d in burst mode.\n", (long long unsigned int)arg, MAX_FRAMES_IN_BURST_MODE); + FILE_LOG(logERROR,(mess)); + } +#endif + if (ret == OK) { + setNumFrames(arg); + int64_t retval = getNumFrames(); + FILE_LOG(logDEBUG1, ("retval num frames %lld\n", (long long int)retval)); + validate64(arg, retval, "set number of frames", DEC); + } } return Server_SendResult(file_des, INT64, UPDATE, NULL, 0); } @@ -2587,7 +2571,7 @@ int set_dynamic_range(int file_des) { #elif EIGERD case 4: case 8: case 16: case 32: #endif -#if defined(GOTTHARD) || defined(JUNGFRAU) || defined(CHIPTESTBOARD) || defined(MOENCH) || defined(GOTTHARD2) +#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(GOTTHARD2D) case 16: #endif retval = setDynamicRange(dr); @@ -3710,7 +3694,7 @@ int program_fpga(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); -#if defined(EIGERD) || defined(GOTTHARDD) || defined(MYTHEN3D) || defined(GOTTHARD2D) +#if defined(EIGERD) || defined(GOTTHARDD) //to receive any arguments int n = 1; while (n > 0) @@ -3723,9 +3707,38 @@ int program_fpga(int file_des) { FILE_LOG(logINFOBLUE, ("Programming FPGA...\n")); - size_t filesize = 0; - size_t totalsize = 0; - size_t unitprogramsize = 0; +#if defined(MYTHEN3D) || defined(GOTTHARD2D) + uint64_t filesize = 0; + // filesize + if (receiveData(file_des,&filesize,sizeof(filesize),INT64) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG1, ("Total program size is: %llx\n", (long long unsigned int)filesize)); + if (filesize > NIOS_MAX_APP_IMAGE_SIZE) { + ret = FAIL; + sprintf(mess,"Could not start programming FPGA. File size 0x%llx exceeds max size 0x%llx. Forgot Compression?\n", (long long unsigned int) filesize, (long long unsigned int)NIOS_MAX_APP_IMAGE_SIZE); + FILE_LOG(logERROR,(mess)); + } + Server_SendResult(file_des, INT32, NO_UPDATE, NULL, 0); + + // receive program + if (ret == OK) { + char* fpgasrc = (char*)malloc(filesize); + if (receiveData(file_des, fpgasrc, filesize, OTHER) < 0) + return printSocketReadError(); + + ret = eraseAndWriteToFlash(mess, fpgasrc, filesize); + Server_SendResult(file_des, INT32, NO_UPDATE, NULL, 0); + + //free resources + if (fpgasrc != NULL) + free(fpgasrc); + } + + +#else // jungfrau, ctb, moench + uint64_t filesize = 0; + uint64_t totalsize = 0; + uint64_t unitprogramsize = 0; char* fpgasrc = NULL; FILE* fp = NULL; @@ -3733,7 +3746,7 @@ int program_fpga(int file_des) { if (receiveData(file_des,&filesize,sizeof(filesize),INT32) < 0) return printSocketReadError(); totalsize = filesize; - FILE_LOG(logDEBUG1, ("Total program size is: %d\n", totalsize)); + FILE_LOG(logDEBUG1, ("Total program size is: %lld\n", (long long unsigned int)totalsize)); // opening file pointer to flash and telling FPGA to not touch flash @@ -3758,7 +3771,7 @@ int program_fpga(int file_des) { unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb if (unitprogramsize > filesize) //less than 2mb unitprogramsize = filesize; - FILE_LOG(logDEBUG1, ("unit size to receive is:%d\nfilesize:%d\n", unitprogramsize, filesize)); + FILE_LOG(logDEBUG1, ("unit size to receive is:%lld\nfilesize:%lld\n", (long long unsigned int)unitprogramsize, (long long unsigned int)filesize)); //receive part of program if (receiveData(file_des,fpgasrc,unitprogramsize,OTHER) < 0) @@ -3783,7 +3796,6 @@ int program_fpga(int file_des) { fflush(stdout); } } - printf("\n"); if (ret == OK) { FILE_LOG(logINFO, ("Done copying program\n")); } @@ -3797,8 +3809,13 @@ int program_fpga(int file_des) { if (fp != NULL) fclose(fp); - FILE_LOG(logINFO, ("Completed program fpga command with %s\n", (ret == OK ? "success" : "fail"))); - } +#endif // end of Blackfin programming + if (ret == FAIL) { + FILE_LOG(logERROR, ("Program FPGA FAIL!\n")); + } else { + FILE_LOG(logINFOGREEN, ("Programming FPGA completed successfully\n")); + } + } #endif #endif return ret; @@ -4301,13 +4318,22 @@ int copy_detector_server(int file_des) { int reboot_controller(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); -#ifdef EIGERD +#if defined(MYTHEN3D) || defined(GOTTHARD2D) + if (getHardwareVersionNumber() == 0) { + ret = FAIL; + strcpy(mess, "Old board version, reboot by yourself please!\n"); + FILE_LOG(logINFORED, (mess)); + Server_SendResult(file_des, INT32, NO_UPDATE, NULL, 0); + return GOODBYE; + } + ret = REBOOT; +#elif EIGERD functionNotImplemented(); - return ret; #else - FILE_LOG(logINFORED, ("Rebooting controller\n")); - return REBOOT; + ret = REBOOT; #endif + Server_SendResult(file_des, INT32, NO_UPDATE, NULL, 0); + return ret; } diff --git a/slsDetectorSoftware/CMakeLists.txt b/slsDetectorSoftware/CMakeLists.txt index b903c71cb..a5183ef79 100755 --- a/slsDetectorSoftware/CMakeLists.txt +++ b/slsDetectorSoftware/CMakeLists.txt @@ -1,5 +1,5 @@ set(SOURCES - src/multiSlsDetector.cpp + src/DetectorImpl.cpp src/slsDetectorUsers.cpp src/slsDetector.cpp src/Detector.cpp @@ -32,7 +32,9 @@ target_link_libraries(slsDetectorShared PUBLIC slsProjectOptions slsProjectWarnings slsSupportLib - ${ZeroMQ_LIBRARIES} + ${ZeroMQ_LIBRARIES} + pthread + rt ) set(PUBLICHEADERS diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index 44bec7420..2f02a31a7 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -5,7 +5,7 @@ #include #include -class multiSlsDetector; +class DetectorImpl; class detectorData; namespace sls { @@ -23,7 +23,7 @@ void freeSharedMemory(int multiId, int detPos = -1); * \class Detector */ class Detector { - std::unique_ptr pimpl; + std::unique_ptr pimpl; public: /** @@ -1216,7 +1216,9 @@ class Detector { * * * ************************************************/ - /** [Jungfrau][CTB] */ + /** [Jungfrau][CTB] fname is a pof file + * [Mythen3][Gotthard2] fname is an rbf file + */ void programFPGA(const std::string &fname, Positions pos = {}); /** [Jungfrau][CTB] */ @@ -1229,7 +1231,7 @@ class Detector { void copyDetectorServer(const std::string &fname, const std::string &hostname, Positions pos = {}); - /** [Jungfrau][Gotthard][CTB] */ + /** [Jungfrau][Gotthard][CTB][Mythen3][Gotthard2] */ void rebootController(Positions pos = {}); /** @@ -1263,6 +1265,12 @@ class Detector { /** [Gotthard][Jungfrau][CTB] not possible to read back*/ void writeAdcRegister(uint32_t addr, uint32_t value, Positions pos = {}); + bool getInitialChecks() const; + + /** initial compaibility and other server start up checks + * default enabled */ + void setInitialChecks(const bool value); + /************************************************** * * * Insignificant * diff --git a/slsDetectorSoftware/src/CmdParser.cpp b/slsDetectorSoftware/src/CmdParser.cpp index c9f47bd9b..66bce155d 100755 --- a/slsDetectorSoftware/src/CmdParser.cpp +++ b/slsDetectorSoftware/src/CmdParser.cpp @@ -45,9 +45,7 @@ void CmdParser::Parse(const std::string &s) { auto old_size = arguments_.size(); arguments_.erase(std::remove_if(begin(arguments_), end(arguments_), [](const std::string &item) { - if (item == "-h" || item == "--help") - return true; - return false; + return (item == "-h" || item == "--help"); }), end(arguments_)); if (old_size - arguments_.size() > 0) diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index c5e1898a5..1a16de091 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1288,7 +1288,7 @@ std::string CmdProxy::Counters(int action) { std::vector result; for (size_t i = 0; i < 32; ++i) { if (mask & (1 << i)) { - result.push_back((int)i); + result.push_back(static_cast(i)); } } os << sls::ToString(result) << '\n'; @@ -1807,7 +1807,8 @@ std::string CmdProxy::ProgramFpga(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[fname.pof]\n\t[Jungfrau][Ctb] Programs FPGA from pof file." + os << "[fname.pof | fname.rbf]\n\t[Jungfrau][Ctb] Programs FPGA from pof file." + << "\n\t[Mythen3][Gotthard2] Programs FPGA from rbf file." << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get"); @@ -1815,9 +1816,6 @@ std::string CmdProxy::ProgramFpga(int action) { if (args.size() != 1) { WrongNumberOfParameters(1); } - if (args[0].find(".pof") == std::string::npos) { - throw sls::RuntimeError("Programming file must be a pof file."); - } det->programFPGA(args[0], {det_id}); os << "successful\n"; } else { @@ -1980,6 +1978,39 @@ std::string CmdProxy::BitOperations(int action) { return os.str(); } +std::string CmdProxy::InitialChecks(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[0, 1]\n\tEnable 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'; + } else if (action == defs::GET_ACTION) { + if (det_id != -1) { + throw sls::RuntimeError( + "Cannot enable/disable initial checks at module level"); + } + if (!args.empty()) { + WrongNumberOfParameters(0); + } + auto t = det->getInitialChecks(); + os << t << '\n'; + } else if (action == defs::PUT_ACTION) { + if (det_id != -1) { + throw sls::RuntimeError( + "Cannot get initial checks enable at module level"); + } + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + det->setInitialChecks(std::stoi(args[0])); + os << args.front() << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + + /* Insignificant */ std::string CmdProxy::ExecuteCommand(int action) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 588c6ef5c..56e96984e 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -876,6 +876,7 @@ class CmdProxy { {"getbit", &CmdProxy::BitOperations}, {"firmwaretest", &CmdProxy::firmwaretest}, {"bustest", &CmdProxy::bustest}, + {"initialchecks", &CmdProxy::InitialChecks}, /* Insignificant */ {"port", &CmdProxy::port}, @@ -973,6 +974,7 @@ class CmdProxy { std::string Register(int action); std::string AdcRegister(int action); std::string BitOperations(int action); + std::string InitialChecks(int action); /* Insignificant */ std::string ExecuteCommand(int action); std::string UserDetails(int action); @@ -1009,7 +1011,7 @@ class CmdProxy { INTEGER_COMMAND_NOID(frames, getNumberOfFrames, setNumberOfFrames, std::stol, "[n_frames]\n\tNumber of frames per aquire. In trigger mode, number of frames per trigger." - "\n\t[Gotthard2] Burst mode has a maximum of 2720 frames. Frames number for both modes are uploaded to detector just before acquisition starts"); + "\n\t[Gotthard2] Burst mode has a maximum of 2720 frames."); INTEGER_COMMAND_NOID(triggers, getNumberOfTriggers, setNumberOfTriggers, std::stol, @@ -1696,7 +1698,7 @@ class CmdProxy { "\n\t[Jungfrau][Ctb] Reset FPGA."); EXECUTE_SET_COMMAND(rebootcontroller, rebootController, - "\n\t[Jungfrau][Ctb] Reboot controler (blackfin) of detector."); + "\n\t[Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2] Reboot controler (blackfin) of detector."); EXECUTE_SET_COMMAND(firmwaretest, executeFirmwareTest, "\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb] Firmware test, ie. reads a read fixed pattern from a register."); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 8f2fff64d..c9b23ca1e 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -4,7 +4,7 @@ #include "container_utils.h" #include "detectorData.h" #include "logger.h" -#include "multiSlsDetector.h" +#include "DetectorImpl.h" #include "slsDetector.h" #include "sls_detector_defs.h" @@ -41,7 +41,7 @@ void freeSharedMemory(int multiId, int detPos) { using defs = slsDetectorDefs; Detector::Detector(int shm_id) - : pimpl(sls::make_unique(shm_id)) {} + : pimpl(sls::make_unique(shm_id)) {} Detector::~Detector() = default; @@ -51,7 +51,7 @@ void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); } void Detector::loadConfig(const std::string &fname) { int shm_id = getShmId(); freeSharedMemory(); - pimpl = sls::make_unique(shm_id); + pimpl = sls::make_unique(shm_id); FILE_LOG(logINFO) << "Loading configuration file: " << fname; loadParameters(fname); } @@ -148,7 +148,7 @@ Result Detector::getSettings(Positions pos) const { return pimpl->Parallel(&slsDetector::getSettings, pos); } -void Detector::setSettings(defs::detectorSettings value, Positions pos) { +void Detector::setSettings(const defs::detectorSettings value, Positions pos) { pimpl->Parallel(&slsDetector::setSettings, pos, value); } @@ -1652,9 +1652,7 @@ void Detector::setDetectorMode(defs::detectorModeType value, Positions pos) { // Advanced void Detector::programFPGA(const std::string &fname, Positions pos) { - FILE_LOG(logINFO) - << "Updating Firmware. This can take awhile. Please be patient..."; - std::vector buffer = pimpl->readPofFile(fname); + std::vector buffer = pimpl->readProgrammingFile(fname); pimpl->Parallel(&slsDetector::programFPGA, pos, buffer); } @@ -1709,6 +1707,14 @@ void Detector::writeAdcRegister(uint32_t addr, uint32_t value, Positions pos) { pimpl->Parallel(&slsDetector::writeAdcRegister, pos, addr, value); } +bool Detector::getInitialChecks() const { + return pimpl->getInitialChecks(); +} + +void Detector::setInitialChecks(const bool value) { + pimpl->setInitialChecks(value); +} + // Insignificant Result Detector::getControlPort(Positions pos) const { diff --git a/slsDetectorSoftware/src/multiSlsDetector.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp similarity index 78% rename from slsDetectorSoftware/src/multiSlsDetector.cpp rename to slsDetectorSoftware/src/DetectorImpl.cpp index 83bd716c6..75ebed13b 100755 --- a/slsDetectorSoftware/src/multiSlsDetector.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1,4 +1,4 @@ -#include "multiSlsDetector.h" +#include "DetectorImpl.h" #include "SharedMemory.h" #include "ZmqSocket.h" #include "detectorData.h" @@ -28,14 +28,14 @@ using namespace sls; -multiSlsDetector::multiSlsDetector(int multi_id, bool verify, bool update) +DetectorImpl::DetectorImpl(int multi_id, bool verify, bool update) : multiId(multi_id), multi_shm(multi_id, -1) { setupMultiDetector(verify, update); } -multiSlsDetector::~multiSlsDetector() = default; +DetectorImpl::~DetectorImpl() = default; -void multiSlsDetector::setupMultiDetector(bool verify, bool update) { +void DetectorImpl::setupMultiDetector(bool verify, bool update) { initSharedMemory(verify); initializeMembers(verify); if (update) { @@ -43,104 +43,17 @@ void multiSlsDetector::setupMultiDetector(bool verify, bool update) { } } -template -std::vector -multiSlsDetector::serialCall(RT (slsDetector::*somefunc)(CT...), - typename NonDeduced::type... Args) { - std::vector result; - result.reserve(detectors.size()); - for (auto &d : detectors) { - result.push_back((d.get()->*somefunc)(Args...)); - } - return result; -} - -template -std::vector -multiSlsDetector::serialCall(RT (slsDetector::*somefunc)(CT...) const, - typename NonDeduced::type... Args) const { - std::vector result; - result.reserve(detectors.size()); - for (auto &d : detectors) { - result.push_back((d.get()->*somefunc)(Args...)); - } - return result; -} - -template -std::vector -multiSlsDetector::parallelCall(RT (slsDetector::*somefunc)(CT...), - typename NonDeduced::type... Args) { - std::vector> futures; - for (auto &d : detectors) { - futures.push_back( - std::async(std::launch::async, somefunc, d.get(), Args...)); - } - std::vector result; - result.reserve(detectors.size()); - for (auto &i : futures) { - result.push_back(i.get()); - } - return result; -} - -template -std::vector -multiSlsDetector::parallelCall(RT (slsDetector::*somefunc)(CT...) const, - typename NonDeduced::type... Args) const { - std::vector> futures; - for (auto &d : detectors) { - futures.push_back( - std::async(std::launch::async, somefunc, d.get(), Args...)); - } - std::vector result; - result.reserve(detectors.size()); - for (auto &i : futures) { - result.push_back(i.get()); - } - return result; -} - -template -void multiSlsDetector::parallelCall(void (slsDetector::*somefunc)(CT...), - typename NonDeduced::type... Args) { - std::vector> futures; - for (auto &d : detectors) { - futures.push_back( - std::async(std::launch::async, somefunc, d.get(), Args...)); - } - for (auto &i : futures) { - i.get(); - } - return; -} - -template -void multiSlsDetector::parallelCall( - void (slsDetector::*somefunc)(CT...) const, - typename NonDeduced::type... Args) const { - std::vector> futures; - for (auto &d : detectors) { - futures.push_back( - std::async(std::launch::async, somefunc, d.get(), Args...)); - } - for (auto &i : futures) { - i.get(); - } - return; -} - -void multiSlsDetector::setAcquiringFlag(bool flag) { +void DetectorImpl::setAcquiringFlag(bool flag) { multi_shm()->acquiringFlag = flag; } -int multiSlsDetector::getMultiId() const { return multiId; } +int DetectorImpl::getMultiId() const { return multiId; } -std::string multiSlsDetector::getPackageVersion() const { return GITBRANCH; } +std::string DetectorImpl::getPackageVersion() const { return GITBRANCH; } -int64_t multiSlsDetector::getClientSoftwareVersion() const { return APILIB; } +int64_t DetectorImpl::getClientSoftwareVersion() const { return APILIB; } -void multiSlsDetector::freeSharedMemory(int multiId, int detPos) { +void DetectorImpl::freeSharedMemory(int multiId, int detPos) { // single if (detPos >= 0) { SharedMemory temp_shm(multiId, detPos); @@ -166,7 +79,7 @@ void multiSlsDetector::freeSharedMemory(int multiId, int detPos) { } } -void multiSlsDetector::freeSharedMemory() { +void DetectorImpl::freeSharedMemory() { zmqSocket.clear(); for (auto &d : detectors) { d->freeSharedMemory(); @@ -178,7 +91,7 @@ void multiSlsDetector::freeSharedMemory() { client_downstream = false; } -std::string multiSlsDetector::getUserDetails() { +std::string DetectorImpl::getUserDetails() { if (detectors.empty()) { return std::string("none"); } @@ -212,7 +125,15 @@ std::string multiSlsDetector::getUserDetails() { return sstream.str(); } -void multiSlsDetector::initSharedMemory(bool verify) { +bool DetectorImpl::getInitialChecks() const { + return multi_shm()->initialChecks; +} + +void DetectorImpl::setInitialChecks(const bool value) { + multi_shm()->initialChecks = value; +} + +void DetectorImpl::initSharedMemory(bool verify) { if (!multi_shm.IsExisting()) { multi_shm.CreateSharedMemory(); initializeDetectorStructure(); @@ -230,7 +151,7 @@ void multiSlsDetector::initSharedMemory(bool verify) { } } -void multiSlsDetector::initializeDetectorStructure() { +void DetectorImpl::initializeDetectorStructure() { multi_shm()->shmversion = MULTI_SHMVERSION; multi_shm()->numberOfDetectors = 0; multi_shm()->multiDetectorType = GENERIC; @@ -240,10 +161,11 @@ void multiSlsDetector::initializeDetectorStructure() { multi_shm()->numberOfChannels.y = 0; multi_shm()->acquiringFlag = false; multi_shm()->receiver_upstream = false; + multi_shm()->initialChecks = true; } -void multiSlsDetector::initializeMembers(bool verify) { - // multiSlsDetector +void DetectorImpl::initializeMembers(bool verify) { + // DetectorImpl zmqSocket.clear(); // get objects from single det shared memory (open) @@ -258,10 +180,10 @@ void multiSlsDetector::initializeMembers(bool verify) { } } -void multiSlsDetector::updateUserdetails() { +void DetectorImpl::updateUserdetails() { multi_shm()->lastPID = getpid(); - memset(multi_shm()->lastUser, 0, SHORT_STRING_LENGTH); - memset(multi_shm()->lastDate, 0, SHORT_STRING_LENGTH); + memset(multi_shm()->lastUser, 0, sizeof(multi_shm()->lastUser)); + memset(multi_shm()->lastDate, 0, sizeof(multi_shm()->lastDate)); try { sls::strcpy_safe(multi_shm()->lastUser, exec("whoami").c_str()); sls::strcpy_safe(multi_shm()->lastDate, exec("date").c_str()); @@ -271,7 +193,7 @@ void multiSlsDetector::updateUserdetails() { } } -bool multiSlsDetector::isAcquireReady() { +bool DetectorImpl::isAcquireReady() { if (multi_shm()->acquiringFlag) { FILE_LOG(logWARNING) << "Acquire has already started. " @@ -283,31 +205,26 @@ bool multiSlsDetector::isAcquireReady() { return true; } -std::string multiSlsDetector::exec(const char *cmd) { - int bufsize = 128; - char buffer[bufsize]; - std::string result = ""; +std::string DetectorImpl::exec(const char *cmd) { + char buffer[128]; + std::string result; FILE *pipe = popen(cmd, "r"); if (pipe == nullptr) { throw RuntimeError("Could not open pipe"); } - try { - while (feof(pipe) == 0) { - if (fgets(buffer, bufsize, pipe) != nullptr) { - result += buffer; - } + + while (feof(pipe) == 0) { + if (fgets(buffer, sizeof(buffer), pipe) != nullptr) { + result += buffer; } - } catch (...) { - pclose(pipe); - throw; } + pclose(pipe); result.erase(result.find_last_not_of(" \t\n\r") + 1); return result; } -void multiSlsDetector::setVirtualDetectorServers(const int numdet, - const int port) { +void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) { std::vector hostnames; for (int i = 0; i < numdet; ++i) { // * 2 is for control and stop port @@ -317,14 +234,16 @@ void multiSlsDetector::setVirtualDetectorServers(const int numdet, setHostname(hostnames); } -void multiSlsDetector::setHostname(const std::vector &name) { +void DetectorImpl::setHostname(const std::vector &name) { // this check is there only to allow the previous detsizechan command if (multi_shm()->numberOfDetectors != 0) { FILE_LOG(logWARNING) << "There are already detector(s) in shared memory." "Freeing Shared memory now."; + bool initialChecks = multi_shm()->initialChecks; freeSharedMemory(); setupMultiDetector(); + multi_shm()->initialChecks = initialChecks; } for (const auto &hostname : name) { addSlsDetector(hostname); @@ -332,7 +251,7 @@ void multiSlsDetector::setHostname(const std::vector &name) { updateDetectorSize(); } -void multiSlsDetector::addSlsDetector(const std::string &hostname) { +void DetectorImpl::addSlsDetector(const std::string &hostname) { FILE_LOG(logINFO) << "Adding detector " << hostname; int port = DEFAULT_PORTNO; @@ -357,18 +276,20 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) { // get type by connecting detectorType type = slsDetector::getTypeFromDetector(host, port); - int pos = (int)detectors.size(); - detectors.push_back( + auto pos = detectors.size(); + detectors.emplace_back( sls::make_unique(type, multiId, pos, false)); multi_shm()->numberOfDetectors = detectors.size(); detectors[pos]->setControlPort(port); detectors[pos]->setStopPort(port + 1); - detectors[pos]->setHostname(host); + detectors[pos]->setHostname(host, multi_shm()->initialChecks); // detector type updated by now - multi_shm()->multiDetectorType = Parallel(&slsDetector::getDetectorType, {}).tsquash("Inconsistent detector types."); + multi_shm()->multiDetectorType = + Parallel(&slsDetector::getDetectorType, {}) + .tsquash("Inconsistent detector types."); } -void multiSlsDetector::updateDetectorSize() { +void DetectorImpl::updateDetectorSize() { FILE_LOG(logDEBUG) << "Updating Multi-Detector Size: " << size(); const slsDetectorDefs::xy det_size = detectors[0]->getNumberOfChannels(); @@ -403,17 +324,17 @@ void multiSlsDetector::updateDetectorSize() { } } -int multiSlsDetector::size() const { return detectors.size(); } +int DetectorImpl::size() const { return detectors.size(); } -slsDetectorDefs::xy multiSlsDetector::getNumberOfDetectors() const { +slsDetectorDefs::xy DetectorImpl::getNumberOfDetectors() const { return multi_shm()->numberOfDetector; } -slsDetectorDefs::xy multiSlsDetector::getNumberOfChannels() const { +slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const { return multi_shm()->numberOfChannels; } -void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy c) { +void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) { if (size() > 1) { throw RuntimeError( "Set the number of channels before setting hostname."); @@ -421,7 +342,7 @@ void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy c) { multi_shm()->numberOfChannels = c; } -void multiSlsDetector::setGapPixelsinReceiver(bool enable) { +void DetectorImpl::setGapPixelsinReceiver(bool enable) { Parallel(&slsDetector::enableGapPixels, {}, static_cast(enable)); // update number of channels Result res = @@ -434,7 +355,7 @@ void multiSlsDetector::setGapPixelsinReceiver(bool enable) { } } -int multiSlsDetector::createReceivingDataSockets(const bool destroy) { +int DetectorImpl::createReceivingDataSockets(const bool destroy) { if (destroy) { FILE_LOG(logINFO) << "Going to destroy data sockets"; // close socket @@ -452,7 +373,8 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) { if (multi_shm()->multiDetectorType == EIGER) { numSocketsPerDetector = 2; } - if (Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash() == 2) { + if (Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash() == + 2) { numSocketsPerDetector = 2; } numSockets *= numSocketsPerDetector; @@ -464,7 +386,8 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) { try { zmqSocket.push_back(sls::make_unique( detectors[iSocket / numSocketsPerDetector] - ->getClientStreamingIP().str() + ->getClientStreamingIP() + .str() .c_str(), portnum)); FILE_LOG(logINFO) << "Zmq Client[" << iSocket << "] at " @@ -482,7 +405,7 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) { return OK; } -void multiSlsDetector::readFrameFromReceiver() { +void DetectorImpl::readFrameFromReceiver() { int nX = 0; int nY = 0; @@ -491,7 +414,9 @@ void multiSlsDetector::readFrameFromReceiver() { bool gappixelsenable = false; bool quadEnable = false; bool eiger = false; - bool numInterfaces = Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash(); // cannot pick up from zmq + bool numInterfaces = + Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}) + .squash(); // cannot pick up from zmq bool runningList[zmqSocket.size()], connectList[zmqSocket.size()]; int numRunning = 0; @@ -518,7 +443,7 @@ void multiSlsDetector::readFrameFromReceiver() { uint32_t size = 0, nPixelsX = 0, nPixelsY = 0, dynamicRange = 0; float bytesPerPixel = 0; // header info every header - std::string currentFileName = ""; + std::string currentFileName; uint64_t currentAcquisitionIndex = -1, currentFrameIndex = -1, currentFileIndex = -1; uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1, @@ -651,19 +576,19 @@ void multiSlsDetector::readFrameFromReceiver() { if (eiger && (flippedDataX != 0U)) { for (uint32_t i = 0; i < nPixelsY; ++i) { - memcpy(((char *)multiframe) + + memcpy((multiframe) + ((yoffset + (nPixelsY - 1 - i)) * rowoffset) + xoffset, - (char *)image + (i * singledetrowoffset), + image + (i * singledetrowoffset), singledetrowoffset); } } else { for (uint32_t i = 0; i < nPixelsY; ++i) { - std::cout << i << " " << std::endl; - memcpy(((char *)multiframe) + - ((yoffset + i) * rowoffset) + xoffset, - (char *)image + (i * singledetrowoffset), + + memcpy((multiframe) + ((yoffset + i) * rowoffset) + + xoffset, + image + (i * singledetrowoffset), singledetrowoffset); } } @@ -695,21 +620,22 @@ void multiSlsDetector::readFrameFromReceiver() { << "\n\t nDetPixelsX: " << nDetPixelsX << "\n\t nDetPixelsY: " << nDetPixelsY << "\n\t databytes: " << n; - thisData = new detectorData( - getCurrentProgress(), currentFileName.c_str(), nDetPixelsX, - nDetPixelsY, multigappixels, n, dynamicRange, - currentFileIndex); + thisData = + new detectorData(getCurrentProgress(), currentFileName, + nDetPixelsX, nDetPixelsY, multigappixels, + n, dynamicRange, currentFileIndex); } // normal pixels else { - thisData = new detectorData( - getCurrentProgress(), currentFileName.c_str(), nDetPixelsX, - nDetPixelsY, multiframe, multisize, dynamicRange, - currentFileIndex); + thisData = + new detectorData(getCurrentProgress(), currentFileName, + nDetPixelsX, nDetPixelsY, multiframe, + multisize, dynamicRange, currentFileIndex); } - dataReady(thisData, currentFrameIndex, - ((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1), - pCallbackArg); + dataReady( + thisData, currentFrameIndex, + ((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1), + pCallbackArg); delete thisData; } @@ -750,8 +676,8 @@ void multiSlsDetector::readFrameFromReceiver() { delete[] multigappixels; } -int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage, - bool quadEnable) { +int DetectorImpl::processImageWithGapPixels(char *image, char *&gpImage, + bool quadEnable) { // eiger 4 bit mode int nxb = multi_shm()->numberOfDetector.x * (512 + 3); //(divided by 2 already) @@ -885,7 +811,7 @@ int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage, return gapdatabytes; } -bool multiSlsDetector::enableDataStreamingToClient(int enable) { +bool DetectorImpl::enableDataStreamingToClient(int enable) { if (enable >= 0) { // destroy data threads if (enable == 0) { @@ -900,8 +826,7 @@ bool multiSlsDetector::enableDataStreamingToClient(int enable) { return client_downstream; } - -void multiSlsDetector::savePattern(const std::string &fname) { +void DetectorImpl::savePattern(const std::string &fname) { // std::ofstream outfile; // outfile.open(fname.c_str(), std::ios_base::out); // if (!outfile.is_open()) { @@ -919,7 +844,7 @@ void multiSlsDetector::savePattern(const std::string &fname) { // } // // rest of pattern file // const std::vector commands{ - // "patioctrl", + // "patioctrl", // "patclkctrl", // "patlimits", // "patloop0", @@ -941,43 +866,36 @@ void multiSlsDetector::savePattern(const std::string &fname) { // multiSlsDetectorClient(cmd, GET_ACTION, this, outfile); } - - -void multiSlsDetector::registerAcquisitionFinishedCallback( - void (*func)(double, int, void *), void *pArg) { +void DetectorImpl::registerAcquisitionFinishedCallback(void (*func)(double, int, + void *), + void *pArg) { acquisition_finished = func; acqFinished_p = pArg; } -void multiSlsDetector::registerDataCallback( - void (*userCallback)(detectorData *, uint64_t, uint32_t, void *), - void *pArg) { +void DetectorImpl::registerDataCallback(void (*userCallback)(detectorData *, + uint64_t, uint32_t, + void *), + void *pArg) { dataReady = userCallback; pCallbackArg = pArg; - if (Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) { - if (dataReady == nullptr) { - enableDataStreamingToClient(0); - Parallel(&slsDetector::enableDataStreamingFromReceiver, {}, 0); - } else { - enableDataStreamingToClient(1); - Parallel(&slsDetector::enableDataStreamingFromReceiver, {}, 1); - } - } + enableDataStreamingToClient(dataReady == nullptr ? 0 : 1); } -double multiSlsDetector::setTotalProgress() { +double DetectorImpl::setTotalProgress() { int64_t nf = Parallel(&slsDetector::getNumberOfFramesFromShm, {}) - .tsquash("Inconsistent number of frames"); + .tsquash("Inconsistent number of frames"); int64_t nc = Parallel(&slsDetector::getNumberOfTriggersFromShm, {}) - .tsquash("Inconsistent number of triggers"); + .tsquash("Inconsistent number of triggers"); if (nf == 0 || nc == 0) { throw RuntimeError("Number of frames or triggers is 0"); } int ns = 1; if (multi_shm()->multiDetectorType == JUNGFRAU) { - ns = Parallel(&slsDetector::getNumberOfAdditionalStorageCellsFromShm, {}) - .tsquash("Inconsistent number of additional storage cells"); + ns = + Parallel(&slsDetector::getNumberOfAdditionalStorageCellsFromShm, {}) + .tsquash("Inconsistent number of additional storage cells"); ++ns; } @@ -987,30 +905,28 @@ double multiSlsDetector::setTotalProgress() { return totalProgress; } -double multiSlsDetector::getCurrentProgress() { +double DetectorImpl::getCurrentProgress() { std::lock_guard lock(mp); return 100. * progressIndex / totalProgress; } -void multiSlsDetector::incrementProgress() { +void DetectorImpl::incrementProgress() { std::lock_guard lock(mp); progressIndex += 1; std::cout << std::fixed << std::setprecision(2) << std::setw(6) - << 100. * progressIndex / totalProgress - << " \%"; + << 100. * progressIndex / totalProgress << " \%"; std::cout << '\r' << std::flush; } -void multiSlsDetector::setCurrentProgress(int64_t i) { +void DetectorImpl::setCurrentProgress(int64_t i) { std::lock_guard lock(mp); progressIndex = (double)i; std::cout << std::fixed << std::setprecision(2) << std::setw(6) - << 100. * progressIndex / totalProgress - << " \%"; + << 100. * progressIndex / totalProgress << " \%"; std::cout << '\r' << std::flush; } -int multiSlsDetector::acquire() { +int DetectorImpl::acquire() { // ensure acquire isnt started multiple times by same client if (!isAcquireReady()) { return FAIL; @@ -1020,21 +936,23 @@ int multiSlsDetector::acquire() { struct timespec begin, end; clock_gettime(CLOCK_REALTIME, &begin); - // in the real time acquisition loop, processing thread will wait for a post - // each time + // in the real time acquisition loop, processing thread will wait for a + // post each time sem_init(&sem_newRTAcquisition, 1, 0); - // in the real time acquistion loop, main thread will wait for processing - // thread to be done each time (which in turn waits for receiver/ext - // process) + // in the real time acquistion loop, main thread will wait for + // processing thread to be done each time (which in turn waits for + // receiver/ext process) sem_init(&sem_endRTAcquisition, 1, 0); - bool receiver = Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false); + bool receiver = + Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false); progressIndex = 0; setJoinThreadFlag(false); // verify receiver is idle if (receiver) { - if (Parallel(&slsDetector::getReceiverStatus, {}).squash(ERROR) != IDLE) { + if (Parallel(&slsDetector::getReceiverStatus, {}).squash(ERROR) != + IDLE) { Parallel(&slsDetector::stopReceiver, {}); } } @@ -1083,8 +1001,7 @@ int multiSlsDetector::acquire() { auto t = Parallel(&slsDetector::getRunStatus, {}); if (t.equal()) status = t.front(); - acquisition_finished(getCurrentProgress(), status, - acqFinished_p); + acquisition_finished(getCurrentProgress(), status, acqFinished_p); } sem_destroy(&sem_newRTAcquisition); @@ -1103,12 +1020,12 @@ int multiSlsDetector::acquire() { return OK; } -void multiSlsDetector::startProcessingThread() { +void DetectorImpl::startProcessingThread() { setTotalProgress(); - dataProcessingThread = std::thread(&multiSlsDetector::processData, this); + dataProcessingThread = std::thread(&DetectorImpl::processData, this); } -void multiSlsDetector::processData() { +void DetectorImpl::processData() { if (Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) { if (dataReady != nullptr) { readFrameFromReceiver(); @@ -1126,7 +1043,8 @@ void multiSlsDetector::processData() { } } // get progress - caught = Parallel(&slsDetector::getFramesCaughtByReceiver, {0}).squash(); + caught = Parallel(&slsDetector::getFramesCaughtByReceiver, {0}) + .squash(); // updating progress if (caught != -1) { @@ -1143,17 +1061,17 @@ void multiSlsDetector::processData() { } } -bool multiSlsDetector::getJoinThreadFlag() const { +bool DetectorImpl::getJoinThreadFlag() const { std::lock_guard lock(mp); return jointhread; } -void multiSlsDetector::setJoinThreadFlag(bool value) { +void DetectorImpl::setJoinThreadFlag(bool value) { std::lock_guard lock(mp); jointhread = value; } -int multiSlsDetector::kbhit() { +int DetectorImpl::kbhit() { struct timeval tv; fd_set fds; tv.tv_sec = 0; @@ -1164,11 +1082,33 @@ int multiSlsDetector::kbhit() { return FD_ISSET(STDIN_FILENO, &fds); } -std::vector multiSlsDetector::readPofFile(const std::string &fname) { +std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { + // validate type of file + bool isPof = false; + switch (multi_shm()->multiDetectorType) { + case JUNGFRAU: + case CHIPTESTBOARD: + if (fname.find(".pof") == std::string::npos) { + throw RuntimeError("Programming file must be a pof file."); + } + isPof = true; + break; + case MYTHEN3: + case GOTTHARD2: + if (fname.find(".rbf") == std::string::npos) { + throw RuntimeError("Programming file must be an rbf file."); + } + break; + default: + throw RuntimeError("Not implemented for this detector"); + } + + FILE_LOG(logINFO) + << "Updating Firmware. This can take awhile. Please be patient..."; FILE_LOG(logDEBUG1) << "Programming FPGA with file name:" << fname; + size_t filesize = 0; // check if it exists - struct stat st; if (stat(fname.c_str(), &st) != 0) { throw RuntimeError("Program FPGA: Programming file does not exist"); @@ -1196,32 +1136,43 @@ std::vector multiSlsDetector::readPofFile(const std::string &fname) { // convert src to dst rawbin FILE_LOG(logDEBUG1) << "Converting " << fname << " to " << destfname; { - int filepos, x, y, i; - // Remove header (0...11C) - for (filepos = 0; filepos < 0x11C; ++filepos) { - fgetc(src); - } - // Write 0x80 times 0xFF (0...7F) - { - char c = 0xFF; - for (filepos = 0; filepos < 0x80; ++filepos) { - write(dst, &c, 1); + constexpr int pofNumHeaderBytes = 0x11C; + constexpr int pofFooterOfst = 0x1000000; + int dstFilePos = 0; + if (isPof) { + // Read header and discard + for (int i = 0; i < pofNumHeaderBytes; ++i) { + fgetc(src); + } + // Write 0xFF to destination 0x80 times (padding) + constexpr int pofNumPadding{0x80}; + constexpr uint8_t c{0xFF}; + while (dstFilePos < pofNumPadding) { + write(dst, &c, sizeof(c)); + ++dstFilePos; } } - // Swap bits and write to file - for (filepos = 0x80; filepos < 0x1000000; ++filepos) { - x = fgetc(src); - if (x < 0) { + // Swap bits from source and write to dest + while (!feof(src)) { + // pof: exit early to discard footer + if (isPof && dstFilePos >= pofFooterOfst) { break; } - y = 0; - for (i = 0; i < 8; ++i) { - y = y | - (((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits + // read source + int s = fgetc(src); + if (s < 0) { + break; } - write(dst, &y, 1); + // swap bits + int d = 0; + for (int i = 0; i < 8; ++i) { + d = d | (((s & (1 << i)) >> i) << (7 - i)); + } + write(dst, &d, 1); + ++dstFilePos; } - if (filepos < 0x1000000) { + // validate pof: read less than footer offset + if (isPof && dstFilePos < pofFooterOfst) { throw RuntimeError( "Could not convert programming file. EOF before end of flash"); } diff --git a/slsDetectorSoftware/src/multiSlsDetector.h b/slsDetectorSoftware/src/DetectorImpl.h similarity index 88% rename from slsDetectorSoftware/src/multiSlsDetector.h rename to slsDetectorSoftware/src/DetectorImpl.h index a90d05e21..f2bc44270 100755 --- a/slsDetectorSoftware/src/multiSlsDetector.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -17,9 +17,8 @@ class detectorData; #include #define MULTI_SHMAPIVERSION 0x190809 -#define MULTI_SHMVERSION 0x190819 +#define MULTI_SHMVERSION 0x200131 #define SHORT_STRING_LENGTH 50 -#define DATE_LENGTH 30 #include #include @@ -64,9 +63,12 @@ struct sharedMultiSlsDetector { /** data streaming (up stream) enable in receiver */ bool receiver_upstream; + + /** initial checks */ + bool initialChecks; }; -class multiSlsDetector : public virtual slsDetectorDefs { +class DetectorImpl : public virtual slsDetectorDefs { public: /** * Constructor @@ -75,13 +77,13 @@ class multiSlsDetector : public virtual slsDetectorDefs { * one * @param update true to update last user pid, date etc */ - explicit multiSlsDetector(int multi_id = 0, bool verify = true, + explicit DetectorImpl(int multi_id = 0, bool verify = true, bool update = true); /** * Destructor */ - virtual ~multiSlsDetector(); + virtual ~DetectorImpl(); template struct NonDeduced { using type = CT; }; template @@ -190,44 +192,6 @@ class multiSlsDetector : public virtual slsDetectorDefs { } } - /** - * Loop through the detectors serially and return the result as a vector - */ - - template - std::vector serialCall(RT (slsDetector::*somefunc)(CT...), - typename NonDeduced::type... Args); - - /** - * Loop through the detectors serially and return the result as a vector - * Const qualified version - */ - template - std::vector serialCall(RT (slsDetector::*somefunc)(CT...) const, - typename NonDeduced::type... Args) const; - - /** - * Loop through the detectors in parallel and return the result as a vector - */ - template - std::vector parallelCall(RT (slsDetector::*somefunc)(CT...), - typename NonDeduced::type... Args); - - /** - * Loop through the detectors in parallel and return the result as a vector - * Const qualified version - */ - template - std::vector parallelCall(RT (slsDetector::*somefunc)(CT...) const, - typename NonDeduced::type... Args) const; - - template - void parallelCall(void (slsDetector::*somefunc)(CT...), - typename NonDeduced::type... Args); - - template - void parallelCall(void (slsDetector::*somefunc)(CT...) const, - typename NonDeduced::type... Args) const; /** set acquiring flag in shared memory */ void setAcquiringFlag(bool flag); @@ -248,6 +212,12 @@ class multiSlsDetector : public virtual slsDetectorDefs { /** Get user details of shared memory */ std::string getUserDetails(); + bool getInitialChecks() const; + + /** initial compaibility and other server start up checks + * default enabled */ + void setInitialChecks(const bool value); + /** * Connect to Virtual Detector Servers at local host * @param ndet number of detectors @@ -323,11 +293,13 @@ class multiSlsDetector : public virtual slsDetectorDefs { /** * Convert raw file - * @param fname name of pof file - * @param fpgasrc pointer in memory to read pof to + * [Jungfrau][Ctb] from pof file + * [Mythen3][Gotthard2] from rbf file + * @param fname name of pof/rbf file + * @param fpgasrc pointer in memory to read programming file to * @returns file size */ - std::vector readPofFile(const std::string &fname); + std::vector readProgrammingFile(const std::string &fname); private: /** diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index 2f064eba7..6df2d7f85 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -279,13 +279,21 @@ void slsDetector::freeSharedMemory() { } } -void slsDetector::setHostname(const std::string &hostname) { +void slsDetector::setHostname(const std::string &hostname, const bool initialChecks) { sls::strcpy_safe(shm()->hostname, hostname.c_str()); auto client = DetectorSocket(shm()->hostname, shm()->controlPort); client.close(); FILE_LOG(logINFO) << "Checking Detector Version Compatibility"; - checkDetectorVersionCompatibility(); + if (!initialChecks) { + try { + checkDetectorVersionCompatibility(); + } catch (const DetectorError& e) { + FILE_LOG(logWARNING) << "Bypassing Initial Checks at your own risk!"; + } + } else { + checkDetectorVersionCompatibility(); + } FILE_LOG(logINFO) << "Detector connecting - updating!"; updateCachedDetectorVariables(); @@ -1156,7 +1164,7 @@ void slsDetector::stopAcquisition() { void slsDetector::sendSoftwareTrigger() { FILE_LOG(logDEBUG1) << "Sending software trigger"; - sendToDetector(F_SOFTWARE_TRIGGER); + sendToDetectorStop(F_SOFTWARE_TRIGGER); FILE_LOG(logDEBUG1) << "Sending software trigger successful"; } @@ -1518,8 +1526,8 @@ int slsDetector::setDynamicRange(int n) { // update speed for usability if (dr == 32) { FILE_LOG(logINFO) << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32"; setClockDivider(RUN_CLOCK, 2); - } else if (dr == 16) { - FILE_LOG(logINFO) << "Setting Clock to Half Speed to cope with Dynamic Range of 16"; setClockDivider(RUN_CLOCK, 1); + } else { + FILE_LOG(logINFO) << "Setting Clock to Full Speed to cope with Dynamic Range of " << dr; setClockDivider(RUN_CLOCK, 0); } } @@ -2888,23 +2896,28 @@ int slsDetector::setStoragecellStart(int pos) { } void slsDetector::programFPGA(std::vector buffer) { - // validate type switch (shm()->myDetectorType) { case JUNGFRAU: case CHIPTESTBOARD: - case MOENCH: + programFPGAviaBlackfin(buffer); + break; + case MYTHEN3: + case GOTTHARD2: + programFPGAviaNios(buffer); break; default: throw RuntimeError("Program FPGA is not implemented for this detector"); } +} - size_t filesize = buffer.size(); +void slsDetector::programFPGAviaBlackfin(std::vector buffer) { + uint64_t filesize = buffer.size(); // send program from memory to detector int fnum = F_PROGRAM_FPGA; int ret = FAIL; char mess[MAX_STR_LENGTH] = {0}; - FILE_LOG(logINFO) << "Sending programming binary to detector " << detId + FILE_LOG(logINFO) << "Sending programming binary (from pof) to detector " << detId << " (" << shm()->hostname << ")"; auto client = DetectorSocket(shm()->hostname, shm()->controlPort); @@ -2921,35 +2934,34 @@ void slsDetector::programFPGA(std::vector buffer) { } // erasing flash - if (ret != FAIL) { - FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); - std::cout << std::flush; - // erasing takes 65 seconds, printing here (otherwise need threads - // in server-unnecessary) - const int ERASE_TIME = 65; - int count = ERASE_TIME + 1; - while (count > 0) { - usleep(1 * 1000 * 1000); - --count; - printf("%d%%\r", - static_cast( - (static_cast(ERASE_TIME - count) / ERASE_TIME) * - 100)); - std::cout << std::flush; - } - printf("\n"); - FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); + FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " (" + << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + // erasing takes 65 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 65; + int count = ERASE_TIME + 1; + while (count > 0) { + usleep(1 * 1000 * 1000); + --count; + printf("%d%%\r", + static_cast( + (static_cast(ERASE_TIME - count) / ERASE_TIME) * + 100)); std::cout << std::flush; } + printf("\n"); + FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " (" + << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; - // sending program in parts of 2mb each - size_t unitprogramsize = 0; + + // sending program in parts of 2mb each + uint64_t unitprogramsize = 0; int currentPointer = 0; - size_t totalsize = filesize; + uint64_t totalsize = filesize; while (filesize > 0) { unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb if (unitprogramsize > filesize) { // less than 2mb @@ -2967,19 +2979,53 @@ void slsDetector::programFPGA(std::vector buffer) { os << "Detector " << detId << " (" << shm()->hostname << ")" << " returned error: " << mess; throw RuntimeError(os.str()); - } else { - filesize -= unitprogramsize; - currentPointer += unitprogramsize; - - // print progress - printf("%d%%\r", - static_cast( - (static_cast(totalsize - filesize) / totalsize) * - 100)); - std::cout << std::flush; } + filesize -= unitprogramsize; + currentPointer += unitprogramsize; + + // print progress + printf("%d%%\r", + static_cast( + (static_cast(totalsize - filesize) / totalsize) * + 100)); + std::cout << std::flush; } printf("\n"); + FILE_LOG(logINFO) << "FPGA programmed successfully"; + rebootController(); +} + +void slsDetector::programFPGAviaNios(std::vector buffer) { + uint64_t filesize = buffer.size(); + int fnum = F_PROGRAM_FPGA; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = {0}; + FILE_LOG(logINFO) << "Sending programming binary (from rbf) to detector " << detId + << " (" << shm()->hostname << ")"; + + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + // filesize + client.Send(&filesize, sizeof(filesize)); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + client.Receive(mess, sizeof(mess)); + std::ostringstream os; + os << "Detector " << detId << " (" << shm()->hostname << ")" + << " returned error: " << mess; + throw RuntimeError(os.str()); + } + // program + client.Send(&buffer[0], filesize); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + client.Receive(mess, sizeof(mess)); + std::ostringstream os; + os << "Detector " << detId << " (" << shm()->hostname << ")" + << " returned error: " << mess; + throw RuntimeError(os.str()); + } + FILE_LOG(logINFO) << "FPGA programmed successfully"; rebootController(); } @@ -2999,15 +3045,9 @@ void slsDetector::copyDetectorServer(const std::string &fname, } void slsDetector::rebootController() { - if (shm()->myDetectorType == EIGER) { - throw RuntimeError( - "Reboot controller not implemented for this detector"); - } - int fnum = F_REBOOT_CONTROLLER; - FILE_LOG(logINFO) << "Sending reboot controller to detector " << detId - << " (" << shm()->hostname << ")"; - auto client = DetectorSocket(shm()->hostname, shm()->controlPort); - client.Send(&fnum, sizeof(fnum)); + FILE_LOG(logDEBUG1) << "Rebooting Controller"; + sendToDetector(F_REBOOT_CONTROLLER, nullptr, nullptr); + FILE_LOG(logINFO) << "Controller rebooted successfully!"; } int slsDetector::powerChip(int ival) { diff --git a/slsDetectorSoftware/src/slsDetector.h b/slsDetectorSoftware/src/slsDetector.h index 84b5c1f09..03d825aa3 100755 --- a/slsDetectorSoftware/src/slsDetector.h +++ b/slsDetectorSoftware/src/slsDetector.h @@ -252,8 +252,11 @@ class slsDetector : public virtual slsDetectorDefs { /** * Sets the hostname, if online flag is set connects to update the detector * @param name hostname + * @param initialChecks enable or disable initial compatibility checks + * and other server start up checks. Enabled by default. Disable only + * for advanced users! */ - void setHostname(const std::string &hostname); + void setHostname(const std::string &hostname, const bool initialChecks); /** * Gets the hostname of detector @@ -1382,11 +1385,17 @@ class slsDetector : public virtual slsDetectorDefs { int setStoragecellStart(int pos = -1); /** - * Programs FPGA with pof file (Jungfrau, CTB, Moench) + * [Jungfau][Ctb] Programs FPGA with raw file from pof file + * [Mythen3][Gotthard2] Programs FPGA with raw file from rbf file * @param buffer programming file in memory */ void programFPGA(std::vector buffer); + + /** [Jungfau][Ctb] */ + void programFPGAviaBlackfin(std::vector buffer); + /** [Mythen3][Gotthard2] */ + void programFPGAviaNios(std::vector buffer); /** * Resets FPGA (Jungfrau) */ @@ -1401,6 +1410,7 @@ class slsDetector : public virtual slsDetectorDefs { const std::string &hostname); /** + * [Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2] * Reboot detector controller (blackfin/ powerpc) */ void rebootController(); diff --git a/slsDetectorSoftware/tests/CMakeLists.txt b/slsDetectorSoftware/tests/CMakeLists.txt index 82ae54b8d..1622c48d9 100755 --- a/slsDetectorSoftware/tests/CMakeLists.txt +++ b/slsDetectorSoftware/tests/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-eiger.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-jungfrau.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-mythen3.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-gotthard2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-global.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp diff --git a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp index 0a3d39f7e..8385f3fce 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp @@ -333,6 +333,7 @@ TEST_CASE("Setting and reading back EIGER dacs", "[.cmd]") { det.setDAC(defs::VCP, vcp[i], false, {i}); } } + // gotthard REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); @@ -341,6 +342,7 @@ TEST_CASE("Setting and reading back EIGER dacs", "[.cmd]") { REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); + // mythen3 REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); @@ -357,6 +359,7 @@ TEST_CASE("Setting and reading back EIGER dacs", "[.cmd]") { REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET)); + // gotthard2 REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET)); @@ -370,6 +373,7 @@ TEST_CASE("Setting and reading back EIGER dacs", "[.cmd]") { REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET)); + // jungfrau REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET)); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp new file mode 100644 index 000000000..58f610c47 --- /dev/null +++ b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp @@ -0,0 +1,226 @@ +#include "CmdProxy.h" +#include "Detector.h" +#include "catch.hpp" +#include "sls_detector_defs.h" +#include + +#include "Result.h" +#include "ToString.h" +#include "test-CmdProxy-global.h" +#include "tests/globals.h" +#include "versionAPI.h" + +using sls::CmdProxy; +using sls::Detector; +using test::GET; +using test::PUT; + +TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") { + // vref_h_adc, vb_comp_fe, vb_comp_adc, vcom_cds, + // vref_restore, vb_opa_1st, vref_comp_fe, vcom_adc1, + // vref_prech, vref_l_adc, vref_cds, vb_cs, + // vb_opa_fd, vcom_adc2 + + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + SECTION("vref_h_adc") { test_dac(defs::VREF_H_ADC, "vref_h_adc", 2099); } + SECTION("vb_comp_fe") { test_dac(defs::VB_COMP_FE, "vb_comp_fe", 0); } + SECTION("vb_comp_adc") { test_dac(defs::VB_COMP_ADC, "vb_comp_adc", 0); } + SECTION("vcom_cds") { test_dac(defs::VCOM_CDS, "vcom_cds", 1400); } + SECTION("vref_rstore") { test_dac(defs::VREF_RSTORE, "vref_rstore", 640); } + SECTION("vb_opa_1st") { test_dac(defs::VB_OPA_1ST, "vb_opa_1st", 0); } + SECTION("vref_comp_fe") { test_dac(defs::VREF_COMP_FE, "vref_comp_fe", 0); } + SECTION("vcom_adc1") { test_dac(defs::VCOM_ADC1, "vcom_adc1", 1400); } + SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1720); } + SECTION("vref_l_adc") { test_dac(defs::VREF_L_ADC, "vref_l_adc", 700); } + SECTION("vref_cds") { test_dac(defs::VREF_CDS, "vref_cds", 1200); } + SECTION("vb_cs") { test_dac(defs::VB_CS, "vb_cs", 2799); } + SECTION("vb_opa_fd") { test_dac(defs::VB_OPA_FD, "vb_opa_fd", 0); } + SECTION("vcom_adc2") { test_dac(defs::VCOM_ADC2, "vcom_adc2", 1400); } + // eiger + REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET)); + // gotthard + REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); + // jungfrau + REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET)); + // mythen3 + REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET)); + } +} + +TEST_CASE("vchip", "[.cmd][.onchipdacs]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + std::vector on_chip_dac_names = {"vchip_comp_fe", "vchip_opa_1st", "vchip_opa_fd", "vchip_comp_adc", "vchip_ref_comp_fe", "vchip_cs"}; + std::vector on_chip_dac_indices = {defs::VB_COMP_FE, defs::VB_OPA_1ST, defs::VB_OPA_FD, defs::VB_COMP_ADC, defs::VREF_COMP_FE, defs::VB_CS}; + std::vector values = {0x137, 0x000, 0x134, 0x3FF, 0x100, 0x0D0}; + + for (size_t i = 0; i < on_chip_dac_names.size(); ++i) { + REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {}, -1, GET)); + REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"10", "0x0"}, -1, GET)); // chip index (-1 to 9) + REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"-1", "0x400"}, -1, GET)); // max val is 0x3ff + + auto previous = det.getOnChipDAC(on_chip_dac_indices[i], -1); + auto dacstr = sls::ToStringHex(values[i]); + int chip_index = -1; + auto chip_index_str = std::to_string(chip_index); + + std::ostringstream oss_set, oss_get; + proxy.Call(on_chip_dac_names[i], {chip_index_str, dacstr}, -1, PUT, oss_set); + REQUIRE(oss_set.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n"); + proxy.Call(on_chip_dac_names[i], {chip_index_str}, -1, GET, oss_get); + REQUIRE(oss_get.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n"); + // Reset all dacs to previous value + for (int i = 0; i != det.size(); ++i) { + det.setOnChipDAC(on_chip_dac_indices[i], chip_index, previous[i], {i}); + } + } + } else { + REQUIRE_THROWS(proxy.Call("vchip_comp_fe", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET)); + } +} + + +TEST_CASE("burstmode", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + + if (det_type == defs::GOTTHARD2) { + auto burst = det.getBurstMode(); + auto burststr = sls::ToString(burst); + { + std::ostringstream oss; + proxy.Call("burstmode", {"internal"}, -1, PUT, oss); + REQUIRE(oss.str() == "burstmode internal\n"); + } + { + std::ostringstream oss; + proxy.Call("burstmode", {"off"}, -1, PUT, oss); + REQUIRE(oss.str() == "burstmode off\n"); + } + { + std::ostringstream oss; + proxy.Call("burstmode", {}, -1, GET, oss); + REQUIRE(oss.str() == "burstmode off\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setBurstMode(burst[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("burstmode", {}, -1, GET)); + } +} + + +TEST_CASE("vetoref", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + + if (det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("vetoref", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vetoref", {"3", "0x3ff"}, -1, PUT)); // invalid chip index + REQUIRE_NOTHROW(proxy.Call("vetoref", {"1", "0x010"}, -1, PUT)); + } else { + REQUIRE_THROWS(proxy.Call("vetoref", {"3", "0x0"}, -1, PUT)); + } +} + + +TEST_CASE("vetophoton", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + + if (det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("vetophoton", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("vetophoton", {"-1"}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vetophoton", {"12", "1", "39950"}, -1, PUT));// invalid chip index + REQUIRE_THROWS(proxy.Call("vetophoton", {"-1", "0"}, -1, PUT)); // invalid photon number + REQUIRE_THROWS(proxy.Call("vetophoton", {"-1", "1", "39950"}, -1, PUT)); // invald file + } else { + REQUIRE_THROWS(proxy.Call("vetophoton", {"-1"}, -1, GET)); + } +} + + + +TEST_CASE("inj_ch", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + + if (det_type == defs::GOTTHARD2) { + auto inj = det.getInjectChannel(); + REQUIRE_THROWS(proxy.Call("inj_ch", {"-1", "1"}, -1, PUT));// invalid offset + REQUIRE_THROWS(proxy.Call("inj_ch", {"0", "0"}, -1, PUT));// invalid increment + { + std::ostringstream oss; + proxy.Call("inj_ch", {"0", "1"}, -1, PUT, oss); + REQUIRE(oss.str() == "inj_ch [0, 1]\n"); + } + { + std::ostringstream oss; + proxy.Call("inj_ch", {}, -1, GET, oss); + REQUIRE(oss.str() == "inj_ch [0, 1]\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setInjectChannel(inj[i][0], inj[i][1], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("inj_ch", {}, -1, GET)); + } +} diff --git a/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp b/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp index 88bb61277..553186b05 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp @@ -479,58 +479,3 @@ TEST_CASE("rx_zmqip", "[.cmd]") { } } -// TEST_CASE("burstmode", "[.cmd][.gotthard2]") { -// if (test::type == slsDetectorDefs::GOTTHARD2) { -// REQUIRE_NOTHROW(multiSlsDetectorClient("burstmode 0", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("burstmode 1", PUT)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("burstmode", GET)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("burstmod", GET)); -// } -// } - -// TEST_CASE("vetoref", "[.cmd][.gotthard2]") { -// if (test::type == slsDetectorDefs::GOTTHARD2) { -// REQUIRE_THROWS(multiSlsDetectorClient("vetoref 3 0x3ff", PUT)); // -// invalid chip index REQUIRE_THROWS(multiSlsDetectorClient("vetoref 0 -// 0xFFFF", PUT)); // invalid value -// REQUIRE_NOTHROW(multiSlsDetectorClient("vetoref 1 0x010", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vetoref", GET)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("vetoref 3 0x0", PUT)); -// } -// } - -// TEST_CASE("vetophoton", "[.cmd][.gotthard2]") { -// if (test::type == slsDetectorDefs::GOTTHARD2) { -// REQUIRE_THROWS(multiSlsDetectorClient("vetophoton 12 1 39950 -// examples/gotthard2_veto_photon.txt", PUT)); // invalid chip index -// REQUIRE_THROWS(multiSlsDetectorClient("vetophoton -1 0 39950 -// examples/gotthard2_veto_photon.txt", PUT)); // invalid photon number -// REQUIRE_NOTHROW(multiSlsDetectorClient("vetophoton -1 1 39950 -// examples/gotthard2_veto_photon.txt", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vetophoton", GET)); -// REQUIRE_NOTHROW(multiSlsDetectorClient("vetophoton -1", GET)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("vetophoton -1", GET)); -// } -// } - -// TEST_CASE("inj_ch", "[.cmd][.gotthard2]") { -// if (test::type == slsDetectorDefs::GOTTHARD2) { -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("inj_ch 0 1", PUT, -// nullptr, oss)); REQUIRE(oss.str() == "inj_ch [0, 1]\n"); -// } -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("inj_ch", GET, nullptr, -// oss)); REQUIRE(oss.str() == "inj_ch [0, 1]\n"); -// } -// REQUIRE_THROWS(multiSlsDetectorClient("inj_ch -1 1", PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("inj_ch 0 0", PUT)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("inj_ch", GET)); -// } -// } diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index 15cded029..6e1718503 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -34,120 +34,35 @@ TEST_CASE("type", "[.cmd]"){ } -// TEST_CASE("vchip", "[.cmd]") { -// int prev_val = 0; -// if (test::type == slsDetectorDefs::GOTTHARD2) { -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_comp_fe", GET)); // -// needs a chip index -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_comp_fe -1 0x400", -// GET)); // max val is 0x3ff -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_fe -1", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vchip_comp_fe -1 ")); prev_val = stoul(s, 0, 16); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_fe -1 0x137", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_fe -1", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vchip_comp_fe -1 0x137\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_fe -1 " + -// sls::ToStringHex(prev_val), PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_opa_1st", GET)); // -// needs a chip index -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_1st -1", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vchip_opa_1st -1 ")); prev_val = stoul(s, 0, 16); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_1st -1 0x137", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_1st -1", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vchip_opa_1st -1 0x137\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_1st -1 " + -// sls::ToStringHex(prev_val), PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_opa_fd", GET)); // needs -// a chip index -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_fd -1", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vchip_opa_fd -1 ")); prev_val = stoul(s, 0, 16); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_fd -1 0x137", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_fd -1", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vchip_opa_fd -1 0x137\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_opa_fd -1 " + -// sls::ToStringHex(prev_val), PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_comp_adc", GET)); // -// needs a chip index -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_adc -1", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vchip_comp_adc -1 ")); prev_val = stoul(s, 0, 16); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_adc -1 0x137", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_adc -1", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vchip_comp_adc -1 -// 0x137\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_comp_adc -1 " + -// sls::ToStringHex(prev_val), PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_ref_comp_fe", GET)); // -// needs a chip index -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_ref_comp_fe -1", -// GET, nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vchip_ref_comp_fe -1 ")); prev_val = stoul(s, 0, 16); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_ref_comp_fe -1 -// 0x137", PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_ref_comp_fe -1", -// GET, nullptr, oss)); REQUIRE(oss.str() == "vchip_ref_comp_fe -1 -// 0x137\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_ref_comp_fe -1 " + -// sls::ToStringHex(prev_val), PUT)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_cs", GET)); // needs a -// chip index -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_cs -1", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vchip_cs -1 ")); prev_val = stoul(s, 0, 16); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_cs -1 0x137", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_cs -1", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vchip_cs -1 0x137\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vchip_cs -1 " + -// sls::ToStringHex(prev_val), PUT)); -// } else { -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_comp_fe", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_opa_1st", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_opa_fd", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_comp_adc", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_ref_comp_fe", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vchip_cs", GET)); -// } - -// } +TEST_CASE("initialchecks", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto check = det.getInitialChecks(); + auto dtstr = sls::ToString(check); + auto hostname = det.getHostname(); + std::string hostnamestr; + for (auto &it : hostname) { + hostnamestr += (it + "+"); + } + { + std::ostringstream oss; + proxy.Call("initialchecks", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "initialchecks 0\n"); + } + { + std::ostringstream oss; + proxy.Call("initialchecks", {}, -1, GET, oss); + REQUIRE(oss.str() == "initialchecks 0\n"); + } + { + det.setHostname(hostname); + std::ostringstream oss; + proxy.Call("initialchecks", {}, -1, GET, oss); + REQUIRE(oss.str() == "initialchecks 0\n"); + } + det.setInitialChecks(check); +} // TEST_CASE("dacs", "[.cmd]") { // REQUIRE_NOTHROW(multiSlsDetectorClient("daclist", GET)); @@ -574,238 +489,6 @@ TEST_CASE("type", "[.cmd]"){ // REQUIRE_THROWS(multiSlsDetectorClient("vdd_prot", GET)); // } - -// else if (test::type == slsDetectorDefs::GOTTHARD2) { -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_h_adc", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vref_h_adc ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_h_adc 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_h_adc", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vref_h_adc 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_h_adc " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_fe", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vb_comp_fe ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_fe 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_fe", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vb_comp_fe 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_fe " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_adc", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vb_comp_adc ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_adc 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_adc", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vb_comp_adc 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_comp_adc " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_cds", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("vcom_cds -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_cds 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_cds", GET, nullptr, -// oss)); REQUIRE(oss.str() == "vcom_cds 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_cds " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_rstore", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vref_rstore ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_rstore 1000", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_rstore", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vref_rstore 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_rstore " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_1st", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vb_opa_1st ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_1st 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_1st", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vb_opa_1st 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_1st " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_comp_fe", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vref_comp_fe ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_comp_fe 1000", -// PUT)); std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_comp_fe", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vref_comp_fe 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_comp_fe " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc1", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("vcom_adc1 -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc1 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc1", GET, nullptr, -// oss)); REQUIRE(oss.str() == "vcom_adc1 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc1 " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_prech", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vref_prech ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_prech 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_prech", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vref_prech 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_prech " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_l_adc", GET, -// nullptr, oss)); std::string s = (oss.str()).erase (0, -// strlen("vref_l_adc ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_l_adc 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_l_adc", GET, -// nullptr, oss)); REQUIRE(oss.str() == "vref_l_adc 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_l_adc " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_cds", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("vref_cds -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_cds 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_cds", GET, nullptr, -// oss)); REQUIRE(oss.str() == "vref_cds 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vref_cds " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_cs", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("vb_cs ")); -// prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_cs 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_cs", GET, nullptr, -// oss)); REQUIRE(oss.str() == "vb_cs 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_cs " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_fd", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("vb_opa_fd -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_fd 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_fd", GET, nullptr, -// oss)); REQUIRE(oss.str() == "vb_opa_fd 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vb_opa_fd " + -// std::to_string(prev_val), PUT)); -// { -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc2", GET, nullptr, -// oss)); std::string s = (oss.str()).erase (0, strlen("vcom_adc2 -// ")); prev_val = std::stoi(s); -// } -// { -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc2 1000", PUT)); -// std::ostringstream oss; -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc2", GET, nullptr, -// oss)); REQUIRE(oss.str() == "vcom_adc2 1000\n"); -// } -// REQUIRE_NOTHROW(multiSlsDetectorClient("vcom_adc2 " + -// std::to_string(prev_val), PUT)); - -// REQUIRE_THROWS(multiSlsDetectorClient("vthreshold", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vsvp", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vsvn", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vtr", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vrf", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vrs", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vtgstv", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcmp_ll", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcmp_lr", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcal", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcmp_rl", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcmp_rr", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("rxb_rb", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("rxb_lb", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcp", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcn", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vis", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("iodelay", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vref_ds", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcascn_pb", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcascp_pb", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vout_cm", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vcasc_out", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vin_cm", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vref_comp", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("ib_test_c", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vb_ds", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vb_comp", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vb_pixbuf", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vin_com", GET)); -// REQUIRE_THROWS(multiSlsDetectorClient("vdd_prot", GET)); -// } - // } TEST_CASE("user", "[.cmd]") { @@ -2340,7 +2023,7 @@ TEST_CASE("stopport", "[.cmd]") { // REQUIRE_NOTHROW(multiSlsDetectorClient("0:flippeddatax", GET, // nullptr, oss)); REQUIRE(oss.str() == "flippeddatax 0\n"); // } -// multiSlsDetector d; +// DetectorImpl d; // if (d.size() > 1) { // std::ostringstream oss; // REQUIRE_NOTHROW(multiSlsDetectorClient("1:flippeddatax", GET, @@ -2618,7 +2301,7 @@ TEST_CASE("fformat", "[.cmd]") { // oss)); REQUIRE(oss.str() == "udp_dstport 6200\n"); // } // { -// multiSlsDetector d; +// DetectorImpl d; // int socketsperdetector = 1; // if (test::type == slsDetectorDefs::EIGER) { // socketsperdetector *= 2; diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index 983aed82a..9e285f1fe 100755 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -70,7 +70,7 @@ set_target_properties(slsReceiverShared PROPERTIES ) add_executable(slsReceiver - src/main.cpp) + src/ReceiverApp.cpp) set_target_properties(slsReceiver PROPERTIES @@ -88,7 +88,7 @@ target_link_libraries(slsReceiver PUBLIC ) add_executable(slsMultiReceiver - src/multiReceiver.cpp) + src/MultiReceiverApp.cpp) set_target_properties(slsMultiReceiver PROPERTIES diff --git a/slsReceiverSoftware/include/CircularFifo.h b/slsReceiverSoftware/include/CircularFifo.h new file mode 100755 index 000000000..2fba93459 --- /dev/null +++ b/slsReceiverSoftware/include/CircularFifo.h @@ -0,0 +1,129 @@ +#pragma once +/* CircularFifo.h + * Code & platform dependent issues with it was originally + * published at http://www.kjellkod.cc/threadsafecircularqueue + * 2009-11-02 + * @author Kjell Hedstr�m, hedstrom@kjellkod.cc + * modified by the sls detector group + * */ + +#include +#include +#include + +/** Circular Fifo (a.k.a. Circular Buffer) + * Thread safe for one reader, and one writer */ +template class CircularFifo { + private: + size_t tail{0}; + size_t head{0}; + size_t capacity; + std::vector data; + mutable sem_t data_mutex; + mutable sem_t free_mutex; + size_t increment(size_t i) const; + + public: + explicit CircularFifo(size_t size) : capacity(size + 1), data(capacity) { + sem_init(&data_mutex, 0, 0); + sem_init(&free_mutex, 0, size); + } + + CircularFifo(const CircularFifo &) = delete; + CircularFifo(CircularFifo&&) = delete; + + virtual ~CircularFifo() { + sem_destroy(&data_mutex); + sem_destroy(&free_mutex); + } + + bool push(Element *&item, bool no_block = false); + bool pop(Element *&item, bool no_block = false); + + bool isEmpty() const; + bool isFull() const; + + int getDataValue() const; + int getFreeValue() const; +}; + +template int CircularFifo::getDataValue() const { + int value; + sem_getvalue(&data_mutex, &value); + return value; +} + +template int CircularFifo::getFreeValue() const { + int value; + sem_getvalue(&free_mutex, &value); + return value; +} + +/** Producer only: Adds item to the circular queue. + * If queue is full at 'push' operation no update/overwrite + * will happen, it is up to the caller to handle this case + * + * \param item_ copy by reference the input item + * \param no_block if true, return immediately if fifo is full + * \return whether operation was successful or not */ +template +bool CircularFifo::push(Element *&item, bool no_block) { + // check for fifo full + if (no_block && isFull()) + return false; + + sem_wait(&free_mutex); + data[tail] = item; + tail = increment(tail); + sem_post(&data_mutex); + return true; +} + +/** Consumer only: Removes and returns item from the queue + * If queue is empty at 'pop' operation no retrieve will happen + * It is up to the caller to handle this case + * + * \param item_ return by reference the wanted item + * \param no_block if true, return immediately if fifo is full + * \return whether operation was successful or not */ +template +bool CircularFifo::pop(Element *&item, bool no_block) { + // check for fifo empty + if (no_block && isEmpty()) + return false; + + sem_wait(&data_mutex); + item = data[head]; + head = increment(head); + sem_post(&free_mutex); + return true; +} + +/** Useful for testing and Consumer check of status + * Remember that the 'empty' status can change quickly + * as the Producer adds more items. + * + * \return true if circular buffer is empty */ +template bool CircularFifo::isEmpty() const { + return (getDataValue() == 0); +} + +/** Useful for testing and Producer check of status + * Remember that the 'full' status can change quickly + * as the Consumer catches up. + * + * \return true if circular buffer is full. */ +template bool CircularFifo::isFull() const { + return (getFreeValue() == 0); +} + +/** Increment helper function for index of the circular queue + * index is incremented or wrapped + * + * \param idx_ the index to the incremented/wrapped + * \return new value for the index */ +template +size_t CircularFifo::increment(size_t i) const { + i = (i + 1) % capacity; + return i; +} diff --git a/slsReceiverSoftware/include/ClientInterface.h b/slsReceiverSoftware/include/ClientInterface.h deleted file mode 100755 index 96e117e13..000000000 --- a/slsReceiverSoftware/include/ClientInterface.h +++ /dev/null @@ -1,160 +0,0 @@ -#pragma once -#include "receiver_defs.h" -#include "sls_detector_defs.h" -#include "Implementation.h" -#include "ServerSocket.h" -class MySocketTCP; -class ServerInterface; - -#include -#include - -class ClientInterface : private virtual slsDetectorDefs { - private: - enum numberMode { DEC, HEX }; - - public: - virtual ~ClientInterface(); - ClientInterface(int portNumber = -1); - int64_t getReceiverVersion(); - - //***callback functions*** - /** params: filepath, filename, fileindex, datasize */ - void registerCallBackStartAcquisition(int (*func)(std::string, std::string, uint64_t, - uint32_t, void *), - void *arg); - - /** params: total frames caught */ - void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *), - void *arg); - - /** params: sls_receiver_header frame metadata, dataPointer, dataSize */ - void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t, - void *), - void *arg); - - /** params: sls_receiver_header frame metadata, dataPointer, modified size */ - void registerCallBackRawDataModifyReady(void (*func)(char *, char *, - uint32_t &, void *), - void *arg); - - private: - void startTCPServer(); - int functionTable(); - int decodeFunction(sls::ServerInterface2 &socket); - void functionNotImplemented(); - void modeNotImplemented(const std::string& modename, int mode); - template - void validate(T arg, T retval, std::string modename, numberMode hex); - void verifyLock(); - void verifyIdle(sls::ServerInterface2 &socket); - - - int exec_command(sls::ServerInterface2 &socket); - int exit_server(sls::ServerInterface2 &socket); - int lock_receiver(sls::ServerInterface2 &socket); - int get_last_client_ip(sls::ServerInterface2 &socket); - int set_port(sls::ServerInterface2 &socket); - int update_client(sls::ServerInterface2 &socket); - int send_update(sls::ServerInterface2 &socket); - int get_version(sls::ServerInterface2 &socket); - int set_detector_type(sls::ServerInterface2 &socket); - int set_detector_hostname(sls::ServerInterface2 &socket); - int set_roi(sls::ServerInterface2 &socket); - int set_num_frames(sls::ServerInterface2 &socket); - int set_num_analog_samples(sls::ServerInterface2 &socket); - int set_num_digital_samples(sls::ServerInterface2 &socket); - int set_exptime(sls::ServerInterface2 &socket); - int set_period(sls::ServerInterface2 &socket); - int set_subexptime(sls::ServerInterface2 &socket); - int set_subdeadtime(sls::ServerInterface2 &socket); - int set_dynamic_range(sls::ServerInterface2 &socket); - int set_streaming_frequency(sls::ServerInterface2 &socket); - int get_status(sls::ServerInterface2 &socket); - int start_receiver(sls::ServerInterface2 &socket); - int stop_receiver(sls::ServerInterface2 &socket); - int set_file_dir(sls::ServerInterface2 &socket); - int set_file_name(sls::ServerInterface2 &socket); - int set_file_index(sls::ServerInterface2 &socket); - int get_frame_index(sls::ServerInterface2 &socket); - int get_missing_packets(sls::ServerInterface2 &socket); - int get_frames_caught(sls::ServerInterface2 &socket); - int enable_file_write(sls::ServerInterface2 &socket); - int enable_master_file_write(sls::ServerInterface2 &socket); - int enable_compression(sls::ServerInterface2 &socket); - int enable_overwrite(sls::ServerInterface2 &socket); - int enable_tengiga(sls::ServerInterface2 &socket); - int set_fifo_depth(sls::ServerInterface2 &socket); - int set_activate(sls::ServerInterface2 &socket); - int set_data_stream_enable(sls::ServerInterface2 &socket); - int set_streaming_timer(sls::ServerInterface2 &socket); - int set_flipped_data(sls::ServerInterface2 &socket); - int set_file_format(sls::ServerInterface2 &socket); - int set_detector_posid(sls::ServerInterface2 &socket); - int set_multi_detector_size(sls::ServerInterface2 &socket); - int set_streaming_port(sls::ServerInterface2 &socket); - int set_streaming_source_ip(sls::ServerInterface2 &socket); - int set_silent_mode(sls::ServerInterface2 &socket); - int enable_gap_pixels(sls::ServerInterface2 &socket); - int restream_stop(sls::ServerInterface2 &socket); - int set_additional_json_header(sls::ServerInterface2 &socket); - int get_additional_json_header(sls::ServerInterface2 &socket); - int set_udp_socket_buffer_size(sls::ServerInterface2 &socket); - int get_real_udp_socket_buffer_size(sls::ServerInterface2 &socket); - int set_frames_per_file(sls::ServerInterface2 &socket); - int check_version_compatibility(sls::ServerInterface2 &socket); - int set_discard_policy(sls::ServerInterface2 &socket); - int set_padding_enable(sls::ServerInterface2 &socket); - int set_deactivated_padding_enable(sls::ServerInterface2 &socket); - int set_readout_mode(sls::ServerInterface2 &socket); - int set_adc_mask(sls::ServerInterface2 &socket); - int set_dbit_list(sls::ServerInterface2 &socket); - int get_dbit_list(sls::ServerInterface2 &socket); - int set_dbit_offset(sls::ServerInterface2 &socket); - int set_quad_type(sls::ServerInterface2 &socket); - int set_read_n_lines(sls::ServerInterface2 &socket); - int set_udp_ip(sls::ServerInterface2 &socket); - int set_udp_ip2(sls::ServerInterface2 &socket); - int set_udp_port(sls::ServerInterface2 &socket); - int set_udp_port2(sls::ServerInterface2 &socket); - int set_num_interfaces(sls::ServerInterface2 &socket); - int set_adc_mask_10g(sls::ServerInterface2 &socket); - int set_num_counters(sls::ServerInterface2 &socket); - - Implementation *impl() { - if (receiver != nullptr) { - return receiver.get(); - } else { - throw sls::SocketError( - "Receiver not set up. Please use rx_hostname first.\n"); - } - } - - detectorType myDetectorType; - std::unique_ptr receiver{nullptr}; - int (ClientInterface::*flist[NUM_REC_FUNCTIONS])( - sls::ServerInterface2 &socket); - int ret{OK}; - int fnum{-1}; - int lockedByClient{0}; - int portNumber{0}; - std::atomic killTcpThread{false}; - std::unique_ptr tcpThread; - - - - //***callback parameters*** - - int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t, - void *) = nullptr; - void *pStartAcquisition{nullptr}; - void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr; - void *pAcquisitionFinished{nullptr}; - void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr; - void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &, - void *) = nullptr; - void *pRawDataReady{nullptr}; - - protected: - std::unique_ptr server{nullptr}; -}; diff --git a/slsReceiverSoftware/include/Receiver.h b/slsReceiverSoftware/include/Receiver.h index dc0bc5e35..7a26b66a9 100755 --- a/slsReceiverSoftware/include/Receiver.h +++ b/slsReceiverSoftware/include/Receiver.h @@ -1,9 +1,9 @@ #pragma once -#include "ClientInterface.h" #include "sls_detector_defs.h" - #include +class ClientInterface; + class Receiver : private virtual slsDetectorDefs { public: @@ -26,6 +26,8 @@ class Receiver : private virtual slsDetectorDefs { */ Receiver(int tcpip_port_no = 1954); + ~Receiver(); + /** * get get Receiver Version \returns id diff --git a/slsReceiverSoftware/include/circularFifo.h b/slsReceiverSoftware/include/circularFifo.h deleted file mode 100755 index d85c0fac7..000000000 --- a/slsReceiverSoftware/include/circularFifo.h +++ /dev/null @@ -1,149 +0,0 @@ -#pragma once -/* CircularFifo.h -* Code & platform dependent issues with it was originally -* published at http://www.kjellkod.cc/threadsafecircularqueue -* 2009-11-02 -* @author Kjell Hedstr�m, hedstrom@kjellkod.cc -* modified by the sls detetor group -* */ - -#include -#include -#include - -/** Circular Fifo (a.k.a. Circular Buffer) -* Thread safe for one reader, and one writer */ -template -class CircularFifo { -public: - - CircularFifo(unsigned int Size) : tail(0), head(0){ - Capacity = Size + 1; - array.resize(Capacity); - sem_init(&data_mutex,0,0); - sem_init(&free_mutex,0,Size); - } - virtual ~CircularFifo() { - sem_destroy(&data_mutex); - sem_destroy(&free_mutex); - } - - bool push(Element*& item_, bool no_block=false); - bool pop(Element*& item_, bool no_block=false); - - bool isEmpty() const; - bool isFull() const; - - int getDataValue() const; - int getFreeValue() const; - -private: - std::vector array; - unsigned int tail; // input index - unsigned int head; // output index - unsigned int Capacity; - mutable sem_t data_mutex; - mutable sem_t free_mutex; - unsigned int increment(unsigned int idx_) const; -}; - -template -int CircularFifo::getDataValue() const -{ - int value; - sem_getvalue(&data_mutex, &value); - return value; -} - -template -int CircularFifo::getFreeValue() const -{ - int value; - sem_getvalue(&free_mutex, &value); - return value; -} - - -/** Producer only: Adds item to the circular queue. -* If queue is full at 'push' operation no update/overwrite -* will happen, it is up to the caller to handle this case -* -* \param item_ copy by reference the input item -* \param no_block if true, return immediately if fifo is full -* \return whether operation was successful or not */ -template -bool CircularFifo::push(Element*& item_, bool no_block) -{ - // check for fifo full - if (no_block && isFull()) - return false; - - sem_wait(&free_mutex); - array[tail] = item_; - tail = increment(tail); - sem_post(&data_mutex); - return true; -} - -/** Consumer only: Removes and returns item from the queue -* If queue is empty at 'pop' operation no retrieve will happen -* It is up to the caller to handle this case -* -* \param item_ return by reference the wanted item -* \param no_block if true, return immediately if fifo is full -* \return whether operation was successful or not */ -template -bool CircularFifo::pop(Element*& item_, bool no_block) -{ - // check for fifo empty - if (no_block && isEmpty()) - return false; - - sem_wait(&data_mutex); - item_ = array[head]; - head = increment(head); - sem_post(&free_mutex); - return true; -} - -/** Useful for testinng and Consumer check of status - * Remember that the 'empty' status can change quickly - * as the Procuder adds more items. - * - * \return true if circular buffer is empty */ -template -bool CircularFifo::isEmpty() const -{ - return (getDataValue() == 0); -} - -/** Useful for testing and Producer check of status - * Remember that the 'full' status can change quickly - * as the Consumer catches up. - * - * \return true if circular buffer is full. */ -template -bool CircularFifo::isFull() const -{ - return (getFreeValue() == 0); -} - -/** Increment helper function for index of the circular queue -* index is inremented or wrapped -* -* \param idx_ the index to the incremented/wrapped -* \return new value for the index */ -template -unsigned int CircularFifo::increment(unsigned int idx_) const -{ - // increment or wrap - // ================= - // index++; - // if(index == array.lenght) -> index = 0; - // - //or as written below: - // index = (index+1) % array.length - idx_ = (idx_+1) % Capacity; - return idx_; -} - diff --git a/slsReceiverSoftware/src/BinaryFile.cpp b/slsReceiverSoftware/src/BinaryFile.cpp index bad78e8f2..a5119dec1 100755 --- a/slsReceiverSoftware/src/BinaryFile.cpp +++ b/slsReceiverSoftware/src/BinaryFile.cpp @@ -49,7 +49,7 @@ void BinaryFile::CreateFile() { currentFileName = BinaryFileStatic::CreateFileName(*filePath, *fileNamePrefix, *fileIndex, subFileIndex, *detIndex, *numUnitsPerDetector, index); - BinaryFileStatic::CreateDataFile(filefd, *overWriteEnable, currentFileName, FILE_BUFFER_SIZE); + BinaryFileStatic::CreateDataFile(filefd, *overWriteEnable, currentFileName); if(!(*silentMode)) { FILE_LOG(logINFO) << "[" << *udpPortNumber << "]: Binary File created: " << currentFileName; diff --git a/slsReceiverSoftware/include/BinaryFile.h b/slsReceiverSoftware/src/BinaryFile.h similarity index 100% rename from slsReceiverSoftware/include/BinaryFile.h rename to slsReceiverSoftware/src/BinaryFile.h diff --git a/slsReceiverSoftware/include/BinaryFileStatic.h b/slsReceiverSoftware/src/BinaryFileStatic.h similarity index 97% rename from slsReceiverSoftware/include/BinaryFileStatic.h rename to slsReceiverSoftware/src/BinaryFileStatic.h index 032aeed30..b1e60fd00 100755 --- a/slsReceiverSoftware/include/BinaryFileStatic.h +++ b/slsReceiverSoftware/src/BinaryFileStatic.h @@ -196,10 +196,9 @@ class BinaryFileStatic { * @param fd file pointer * @param owenable overwrite enable * @param fname complete file name - * @param filebuffersize file buffer size * @returns 0 for success and 1 for fail */ - static void CreateDataFile(FILE*& fd, bool owenable, std::string fname, size_t filebuffersize) + static void CreateDataFile(FILE*& fd, bool owenable, std::string fname) { if(!owenable){ if (NULL == (fd = fopen((const char *) fname.c_str(), "wx"))){ @@ -210,8 +209,8 @@ class BinaryFileStatic { fd = 0; throw sls::RuntimeError("Could not create file " + fname); } - //setting file buffer size to 16mb - setvbuf(fd,NULL,_IOFBF,filebuffersize); + //setting to no file buffering + setvbuf(fd, NULL, _IONBF, 0); } }; diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index fa8833f98..2bd2be3c6 100755 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -18,7 +18,7 @@ using sls::RuntimeError; using sls::SocketError; -using Interface = sls::ServerInterface2; +using Interface = sls::ServerInterface; ClientInterface::~ClientInterface() { killTcpThread = true; @@ -217,7 +217,7 @@ void ClientInterface::modeNotImplemented(const std::string &modename, } template -void ClientInterface::validate(T arg, T retval, std::string modename, +void ClientInterface::validate(T arg, T retval, const std::string& modename, numberMode hex) { if (ret == OK && arg != -1 && retval != arg) { auto format = (hex == HEX) ? std::hex : std::dec; @@ -557,7 +557,9 @@ int ClientInterface::set_period(Interface &socket) { int ClientInterface::set_subexptime(Interface &socket) { auto value = socket.Receive(); FILE_LOG(logDEBUG1) << "Setting period to " << value << "ns"; + uint64_t subdeadtime = impl()->getSubPeriod() - impl()->getSubExpTime(); impl()->setSubExpTime(value); + impl()->setSubPeriod(impl()->getSubExpTime() + subdeadtime); return socket.Send(OK); } diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h new file mode 100755 index 000000000..ef6d9e317 --- /dev/null +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -0,0 +1,160 @@ +#pragma once +#include "receiver_defs.h" +#include "sls_detector_defs.h" +#include "Implementation.h" +#include "ServerSocket.h" +class MySocketTCP; +class ServerInterface; + +#include +#include + +class ClientInterface : private virtual slsDetectorDefs { + private: + enum numberMode { DEC, HEX }; + + public: + virtual ~ClientInterface(); + ClientInterface(int portNumber = -1); + int64_t getReceiverVersion(); + + //***callback functions*** + /** params: filepath, filename, fileindex, datasize */ + void registerCallBackStartAcquisition(int (*func)(std::string, std::string, uint64_t, + uint32_t, void *), + void *arg); + + /** params: total frames caught */ + void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *), + void *arg); + + /** params: sls_receiver_header frame metadata, dataPointer, dataSize */ + void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t, + void *), + void *arg); + + /** params: sls_receiver_header frame metadata, dataPointer, modified size */ + void registerCallBackRawDataModifyReady(void (*func)(char *, char *, + uint32_t &, void *), + void *arg); + + private: + void startTCPServer(); + int functionTable(); + int decodeFunction(sls::ServerInterface &socket); + void functionNotImplemented(); + void modeNotImplemented(const std::string& modename, int mode); + template + void validate(T arg, T retval, const std::string& modename, numberMode hex); + void verifyLock(); + void verifyIdle(sls::ServerInterface &socket); + + + int exec_command(sls::ServerInterface &socket); + int exit_server(sls::ServerInterface &socket); + int lock_receiver(sls::ServerInterface &socket); + int get_last_client_ip(sls::ServerInterface &socket); + int set_port(sls::ServerInterface &socket); + int update_client(sls::ServerInterface &socket); + int send_update(sls::ServerInterface &socket); + int get_version(sls::ServerInterface &socket); + int set_detector_type(sls::ServerInterface &socket); + int set_detector_hostname(sls::ServerInterface &socket); + int set_roi(sls::ServerInterface &socket); + int set_num_frames(sls::ServerInterface &socket); + int set_num_analog_samples(sls::ServerInterface &socket); + int set_num_digital_samples(sls::ServerInterface &socket); + int set_exptime(sls::ServerInterface &socket); + int set_period(sls::ServerInterface &socket); + int set_subexptime(sls::ServerInterface &socket); + int set_subdeadtime(sls::ServerInterface &socket); + int set_dynamic_range(sls::ServerInterface &socket); + int set_streaming_frequency(sls::ServerInterface &socket); + int get_status(sls::ServerInterface &socket); + int start_receiver(sls::ServerInterface &socket); + int stop_receiver(sls::ServerInterface &socket); + int set_file_dir(sls::ServerInterface &socket); + int set_file_name(sls::ServerInterface &socket); + int set_file_index(sls::ServerInterface &socket); + int get_frame_index(sls::ServerInterface &socket); + int get_missing_packets(sls::ServerInterface &socket); + int get_frames_caught(sls::ServerInterface &socket); + int enable_file_write(sls::ServerInterface &socket); + int enable_master_file_write(sls::ServerInterface &socket); + int enable_compression(sls::ServerInterface &socket); + int enable_overwrite(sls::ServerInterface &socket); + int enable_tengiga(sls::ServerInterface &socket); + int set_fifo_depth(sls::ServerInterface &socket); + int set_activate(sls::ServerInterface &socket); + int set_data_stream_enable(sls::ServerInterface &socket); + int set_streaming_timer(sls::ServerInterface &socket); + int set_flipped_data(sls::ServerInterface &socket); + int set_file_format(sls::ServerInterface &socket); + int set_detector_posid(sls::ServerInterface &socket); + int set_multi_detector_size(sls::ServerInterface &socket); + int set_streaming_port(sls::ServerInterface &socket); + int set_streaming_source_ip(sls::ServerInterface &socket); + int set_silent_mode(sls::ServerInterface &socket); + int enable_gap_pixels(sls::ServerInterface &socket); + int restream_stop(sls::ServerInterface &socket); + int set_additional_json_header(sls::ServerInterface &socket); + int get_additional_json_header(sls::ServerInterface &socket); + int set_udp_socket_buffer_size(sls::ServerInterface &socket); + int get_real_udp_socket_buffer_size(sls::ServerInterface &socket); + int set_frames_per_file(sls::ServerInterface &socket); + int check_version_compatibility(sls::ServerInterface &socket); + int set_discard_policy(sls::ServerInterface &socket); + int set_padding_enable(sls::ServerInterface &socket); + int set_deactivated_padding_enable(sls::ServerInterface &socket); + int set_readout_mode(sls::ServerInterface &socket); + int set_adc_mask(sls::ServerInterface &socket); + int set_dbit_list(sls::ServerInterface &socket); + int get_dbit_list(sls::ServerInterface &socket); + int set_dbit_offset(sls::ServerInterface &socket); + int set_quad_type(sls::ServerInterface &socket); + int set_read_n_lines(sls::ServerInterface &socket); + int set_udp_ip(sls::ServerInterface &socket); + int set_udp_ip2(sls::ServerInterface &socket); + int set_udp_port(sls::ServerInterface &socket); + int set_udp_port2(sls::ServerInterface &socket); + int set_num_interfaces(sls::ServerInterface &socket); + int set_adc_mask_10g(sls::ServerInterface &socket); + int set_num_counters(sls::ServerInterface &socket); + + Implementation *impl() { + if (receiver != nullptr) { + return receiver.get(); + } else { + throw sls::SocketError( + "Receiver not set up. Please use rx_hostname first.\n"); + } + } + + detectorType myDetectorType; + std::unique_ptr receiver{nullptr}; + int (ClientInterface::*flist[NUM_REC_FUNCTIONS])( + sls::ServerInterface &socket); + int ret{OK}; + int fnum{-1}; + int lockedByClient{0}; + int portNumber{0}; + std::atomic killTcpThread{false}; + std::unique_ptr tcpThread; + + + + //***callback parameters*** + + int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t, + void *) = nullptr; + void *pStartAcquisition{nullptr}; + void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr; + void *pAcquisitionFinished{nullptr}; + void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr; + void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &, + void *) = nullptr; + void *pRawDataReady{nullptr}; + + protected: + std::unique_ptr server{nullptr}; +}; diff --git a/slsReceiverSoftware/include/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h similarity index 100% rename from slsReceiverSoftware/include/DataProcessor.h rename to slsReceiverSoftware/src/DataProcessor.h diff --git a/slsReceiverSoftware/include/DataStreamer.h b/slsReceiverSoftware/src/DataStreamer.h similarity index 100% rename from slsReceiverSoftware/include/DataStreamer.h rename to slsReceiverSoftware/src/DataStreamer.h diff --git a/slsReceiverSoftware/src/Fifo.cpp b/slsReceiverSoftware/src/Fifo.cpp index 0271f8685..f0af09abc 100755 --- a/slsReceiverSoftware/src/Fifo.cpp +++ b/slsReceiverSoftware/src/Fifo.cpp @@ -45,13 +45,17 @@ void Fifo::CreateFifos(uint32_t fifoItemSize) { fifoFree = new CircularFifo(fifoDepth); fifoStream = new CircularFifo(fifoDepth); //allocate memory - size_t mem_len = fifoItemSize * fifoDepth * sizeof(char); + size_t mem_len = (size_t)fifoItemSize * (size_t)fifoDepth * sizeof(char); memory = (char*) malloc (mem_len); if (memory == nullptr){ throw sls::RuntimeError("Could not allocate memory for fifos"); } memset(memory, 0, mem_len); - FILE_LOG(logDEBUG) << "Memory Allocated " << index << ": " << mem_len << " bytes"; + int pagesize = getpagesize(); + for (size_t i = 0; i < mem_len; i += pagesize) { + strcpy(memory + i, "memory"); + } + FILE_LOG(logDEBUG) << "Memory Allocated " << index << ": " << (double)mem_len/(double)(1024 * 1024) << " MB"; { //push free addresses into fifoFree fifo char* buffer = memory; @@ -72,18 +76,12 @@ void Fifo::DestroyFifos(){ free(memory); memory = nullptr; } - if (fifoBound) { - delete fifoBound; - fifoBound = nullptr; - } - if (fifoFree) { - delete fifoFree; - fifoFree = nullptr; - } - if (fifoStream) { - delete fifoStream; - fifoStream = nullptr; - } + delete fifoBound; + fifoBound = nullptr; + delete fifoFree; + fifoFree = nullptr; + delete fifoStream; + fifoStream = nullptr; } diff --git a/slsReceiverSoftware/include/Fifo.h b/slsReceiverSoftware/src/Fifo.h similarity index 98% rename from slsReceiverSoftware/include/Fifo.h rename to slsReceiverSoftware/src/Fifo.h index 7167ce4aa..f81d4567c 100755 --- a/slsReceiverSoftware/include/Fifo.h +++ b/slsReceiverSoftware/src/Fifo.h @@ -12,7 +12,7 @@ #include "sls_detector_defs.h" #include "logger.h" -#include "circularFifo.h" +#include "CircularFifo.h" class Fifo : private virtual slsDetectorDefs { diff --git a/slsReceiverSoftware/include/File.h b/slsReceiverSoftware/src/File.h similarity index 100% rename from slsReceiverSoftware/include/File.h rename to slsReceiverSoftware/src/File.h diff --git a/slsReceiverSoftware/include/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h similarity index 100% rename from slsReceiverSoftware/include/GeneralData.h rename to slsReceiverSoftware/src/GeneralData.h diff --git a/slsReceiverSoftware/include/HDF5File.h b/slsReceiverSoftware/src/HDF5File.h similarity index 100% rename from slsReceiverSoftware/include/HDF5File.h rename to slsReceiverSoftware/src/HDF5File.h diff --git a/slsReceiverSoftware/include/HDF5FileStatic.h b/slsReceiverSoftware/src/HDF5FileStatic.h similarity index 100% rename from slsReceiverSoftware/include/HDF5FileStatic.h rename to slsReceiverSoftware/src/HDF5FileStatic.h diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 0025d1e80..c3136aeb9 100755 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -193,10 +193,10 @@ void Implementation::SetupFifoStructure() { } FILE_LOG(logINFO) << "Memory Allocated Per Fifo: " - << (((generalData->imageSize) + - (generalData->fifoBufferHeaderSize)) * - fifoDepth) - << " bytes"; + << (double)(((size_t)(generalData->imageSize) + + (size_t)(generalData->fifoBufferHeaderSize)) * + (size_t)fifoDepth) / (double)(1024 * 1024) + << " MB"; FILE_LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed"; } diff --git a/slsReceiverSoftware/include/Implementation.h b/slsReceiverSoftware/src/Implementation.h similarity index 100% rename from slsReceiverSoftware/include/Implementation.h rename to slsReceiverSoftware/src/Implementation.h diff --git a/slsReceiverSoftware/src/Listener.cpp b/slsReceiverSoftware/src/Listener.cpp index 2347f3da1..17c689af0 100755 --- a/slsReceiverSoftware/src/Listener.cpp +++ b/slsReceiverSoftware/src/Listener.cpp @@ -12,6 +12,7 @@ #include "container_utils.h" // For sls::make_unique<> #include "genericSocket.h" #include "sls_detector_exceptions.h" +#include "UdpRxSocket.h" #include #include @@ -147,7 +148,6 @@ void Listener::SetGeneralData(GeneralData* g) { void Listener::CreateUDPSockets() { - if (!(*activated)) { return; } @@ -163,7 +163,7 @@ void Listener::CreateUDPSockets() { ShutDownUDPSocket(); try{ - udpSocket = sls::make_unique(*udpPortNumber, genericSocket::UDP, + udpSocket = sls::make_unique(*udpPortNumber, genericSocket::UDP, generalData->packetSize, ((*eth).length() ? (*eth).c_str() : nullptr), generalData->headerPacketSize, *udpSocketBufferSize); FILE_LOG(logINFO) << index << ": UDP port opened at port " << *udpPortNumber; @@ -213,7 +213,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) { //create dummy socket try { - genericSocket g(*udpPortNumber, genericSocket::UDP, + SELECTED_SOCKET g(*udpPortNumber, genericSocket::UDP, generalData->packetSize, ((*eth).length() ? (*eth).c_str() : nullptr), generalData->headerPacketSize, *udpSocketBufferSize); diff --git a/slsReceiverSoftware/include/Listener.h b/slsReceiverSoftware/src/Listener.h similarity index 97% rename from slsReceiverSoftware/include/Listener.h rename to slsReceiverSoftware/src/Listener.h index 423df0fa2..56da69171 100755 --- a/slsReceiverSoftware/include/Listener.h +++ b/slsReceiverSoftware/src/Listener.h @@ -16,6 +16,13 @@ class GeneralData; class Fifo; class genericSocket; +namespace sls{ + class UdpRxSocket; +} + + +// #define SELECTED_SOCKET genericSocket +#define SELECTED_SOCKET sls::UdpRxSocket class Listener : private virtual slsDetectorDefs, public ThreadObject { @@ -187,7 +194,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject { std::atomic* status; /** UDP Socket - Detector to Receiver */ - std::unique_ptr udpSocket; + std::unique_ptr udpSocket; /** UDP Port Number */ uint32_t* udpPortNumber; diff --git a/slsReceiverSoftware/src/multiReceiver.cpp b/slsReceiverSoftware/src/MultiReceiverApp.cpp similarity index 96% rename from slsReceiverSoftware/src/multiReceiver.cpp rename to slsReceiverSoftware/src/MultiReceiverApp.cpp index ce9053113..b6c0c24e5 100755 --- a/slsReceiverSoftware/src/multiReceiver.cpp +++ b/slsReceiverSoftware/src/MultiReceiverApp.cpp @@ -18,6 +18,7 @@ It is linked in manual/manual-api from slsReceiverSoftware/include ] #include "sls_detector_defs.h" #include "Receiver.h" +#include "container_utils.h" #include //SIGINT #include //system @@ -29,6 +30,7 @@ It is linked in manual/manual-api from slsReceiverSoftware/include ] #include //wait #include //tid #include //usleep +#include using namespace std; @@ -36,15 +38,14 @@ using namespace std; #define PRINT_IN_COLOR(c,f, ...) printf ("\033[%dm" f RESET, 30 + c+1, ##__VA_ARGS__) -/** Variable is true to continue running, set to false upon interrupt */ -bool keeprunning; +sem_t semaphore; /** * Control+C Interrupt Handler - * Sets the variable keeprunning to false, to let all the processes know to exit properly + * to let all the processes know to exit properly */ void sigInterruptHandler(int p){ - keeprunning = false; + sem_post(&semaphore); } /** @@ -165,7 +166,7 @@ int main(int argc, char *argv[]) { int numReceivers = 1; int startTCPPort = 1954; int withCallback = 0; - keeprunning = true; + sem_init(&semaphore,1,0); /** - get number of receivers and start tcp port from command line arguments */ if ( (argc != 4) || (!sscanf(argv[1],"%d", &startTCPPort)) || (!sscanf(argv[2],"%d", &numReceivers)) || (!sscanf(argv[3],"%d", &withCallback)) ) @@ -238,9 +239,9 @@ int main(int argc, char *argv[]) { else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,nullptr); } - /** - as long as keeprunning is true (changes with Ctrl+C) */ - while(keeprunning) - pause(); + /** - as long as no Ctrl+C */ + sem_wait(&semaphore); + sem_destroy(&semaphore); cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid)); exit(EXIT_SUCCESS); break; diff --git a/slsReceiverSoftware/src/Receiver.cpp b/slsReceiverSoftware/src/Receiver.cpp index 7b2b04b4a..e3bde8f1f 100755 --- a/slsReceiverSoftware/src/Receiver.cpp +++ b/slsReceiverSoftware/src/Receiver.cpp @@ -1,4 +1,5 @@ #include "Receiver.h" +#include "ClientInterface.h" #include "sls_detector_exceptions.h" #include "versionAPI.h" #include "container_utils.h" @@ -13,6 +14,7 @@ #include #include +Receiver::~Receiver() = default; Receiver::Receiver(int argc, char *argv[]): tcpipInterface (nullptr) { diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/ReceiverApp.cpp similarity index 96% rename from slsReceiverSoftware/src/main.cpp rename to slsReceiverSoftware/src/ReceiverApp.cpp index 6cb7b147e..e30785470 100755 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/ReceiverApp.cpp @@ -4,6 +4,7 @@ #include "logger.h" #include "Receiver.h" #include "sls_detector_defs.h" +#include "container_utils.h" #include //SIGINT #include //system @@ -14,11 +15,12 @@ #include #include //usleep #include +#include -bool keeprunning; +sem_t semaphore; void sigInterruptHandler(int p){ - keeprunning = false; + sem_post(&semaphore); } /** Define Colors to print data call back in different colors for different recievers */ @@ -65,7 +67,8 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){ int main(int argc, char *argv[]) { - keeprunning = true; + sem_init(&semaphore,1,0); + FILE_LOG(logINFOBLUE) << "Created [ Tid: " << syscall(SYS_gettid) << " ]"; // Catch signal SIGINT to close files and call destructors properly @@ -136,8 +139,8 @@ int main(int argc, char *argv[]) { //receiver->registerCallBackRawDataReady(rawDataReadyCallBack,NULL); FILE_LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]"; - while(keeprunning) - pause(); + sem_wait(&semaphore); + sem_destroy(&semaphore); FILE_LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]"; FILE_LOG(logINFO) << "Exiting Receiver"; return 0; diff --git a/slsReceiverSoftware/src/ThreadObject.cpp b/slsReceiverSoftware/src/ThreadObject.cpp index c4c426152..4a554e70f 100755 --- a/slsReceiverSoftware/src/ThreadObject.cpp +++ b/slsReceiverSoftware/src/ThreadObject.cpp @@ -66,7 +66,7 @@ void ThreadObject::SetThreadPriority(int priority) { struct sched_param param; param.sched_priority = priority; if (pthread_setschedparam(threadObject->native_handle(), SCHED_FIFO, ¶m) == EPERM) { - if (!index) { + if (index == 0) { FILE_LOG(logWARNING) << "Could not prioritize " << type << " thread. " "(No Root Privileges?)"; } diff --git a/slsReceiverSoftware/include/ThreadObject.h b/slsReceiverSoftware/src/ThreadObject.h similarity index 100% rename from slsReceiverSoftware/include/ThreadObject.h rename to slsReceiverSoftware/src/ThreadObject.h diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h similarity index 98% rename from slsReceiverSoftware/include/receiver_defs.h rename to slsReceiverSoftware/src/receiver_defs.h index 7e591c374..8fc71782c 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -1,7 +1,7 @@ #pragma once #include "sls_detector_defs.h" -#include +#include #define MAX_DIMENSIONS (2) #define MAX_NUMBER_OF_LISTENING_THREADS (2) diff --git a/slsReceiverSoftware/tests/CMakeLists.txt b/slsReceiverSoftware/tests/CMakeLists.txt index d8e89f687..0766f44be 100755 --- a/slsReceiverSoftware/tests/CMakeLists.txt +++ b/slsReceiverSoftware/tests/CMakeLists.txt @@ -1,4 +1,7 @@ target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-GeneralData.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-FileNames.cpp -) \ No newline at end of file + ${CMAKE_CURRENT_SOURCE_DIR}/test-CircularFifo.cpp +) + +target_include_directories(tests PUBLIC "$") \ No newline at end of file diff --git a/slsReceiverSoftware/tests/test-CircularFifo.cpp b/slsReceiverSoftware/tests/test-CircularFifo.cpp new file mode 100644 index 000000000..0bc376636 --- /dev/null +++ b/slsReceiverSoftware/tests/test-CircularFifo.cpp @@ -0,0 +1,52 @@ +#include "catch.hpp" +#include "CircularFifo.h" +#include + +TEST_CASE("Empty buffer"){ + CircularFifo fifo(0); + + //Since the fifo can hold zero elements + //its both empty and full + CHECK(fifo.isEmpty()== true); + CHECK(fifo.isFull()== true); + + + //push fails + char* c = new char; + *c = 'h'; + CHECK(fifo.push(c, true) == false); + + //pop fails + CHECK(fifo.pop(c, true) == false); + + delete c; + +} + +TEST_CASE("Push pop"){ + CircularFifo fifo(5); + + std::vector vec{3,7,12,3,4}; + int* p = &vec[0]; + + for(size_t i =0; i!=vec.size(); ++i){ + fifo.push(p); + ++p; + CHECK(fifo.getDataValue() == i+1); + CHECK(fifo.getFreeValue() == 4-i); + } + + CHECK(fifo.isEmpty()== false); + CHECK(fifo.isFull()== true); + + for(size_t i = 0; i!= vec.size(); ++i){ + fifo.pop(p); + CHECK(*p == vec[i]); + CHECK(fifo.getDataValue() == 4-i); + CHECK(fifo.getFreeValue() == i+1); + } + + CHECK(fifo.isEmpty()== true); + CHECK(fifo.isFull()== false); + +} \ No newline at end of file diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index a4d08690e..a068f786d 100755 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -4,7 +4,7 @@ set(SOURCES src/ClientSocket.cpp src/DataSocket.cpp src/ServerSocket.cpp - src/ServerInterface2.cpp + src/ServerInterface.cpp src/network_utils.cpp ) @@ -25,7 +25,7 @@ set(PUBLICHEADERS include/ClientSocket.h include/DataSocket.h include/ServerSocket.h - include/ServerInterface2.h + include/ServerInterface.h include/network_utils.h include/FixedCapacityContainer.h include/ToString.h @@ -58,6 +58,7 @@ set_target_properties(slsSupportLib PROPERTIES target_link_libraries(slsSupportLib slsProjectOptions slsProjectWarnings + ${ZeroMQ_LIBRARIES} rapidjson) if (SLS_USE_TESTS) diff --git a/slsSupportLib/include/ServerInterface2.h b/slsSupportLib/include/ServerInterface.h similarity index 80% rename from slsSupportLib/include/ServerInterface2.h rename to slsSupportLib/include/ServerInterface.h index 774378910..8f6d819fa 100644 --- a/slsSupportLib/include/ServerInterface2.h +++ b/slsSupportLib/include/ServerInterface.h @@ -2,18 +2,18 @@ #include "DataSocket.h" namespace sls { -class ServerInterface2; +class ServerInterface; } #include "ServerSocket.h" #include "sls_detector_defs.h" namespace sls { -class ServerInterface2 : public DataSocket { +class ServerInterface : public DataSocket { using defs = slsDetectorDefs; public: - ServerInterface2(int socketId) : DataSocket(socketId) {} + ServerInterface(int socketId) : DataSocket(socketId) {} int sendResult(int ret, void *retval, int retvalSize, char *mess = nullptr); diff --git a/slsSupportLib/include/ServerSocket.h b/slsSupportLib/include/ServerSocket.h index 6b344cf43..532980bbd 100755 --- a/slsSupportLib/include/ServerSocket.h +++ b/slsSupportLib/include/ServerSocket.h @@ -1,7 +1,7 @@ #pragma once #include "DataSocket.h" -#include "ServerInterface2.h" +#include "ServerInterface.h" #include "network_utils.h" #include #include @@ -14,7 +14,7 @@ namespace sls { class ServerSocket : public DataSocket { public: ServerSocket(int port); - ServerInterface2 accept(); + ServerInterface accept(); IpAddr getLastClient() const noexcept { return lastClient; } IpAddr getThisClient() const noexcept { return thisClient; } IpAddr getLockedBy() const noexcept { return lockedBy; } diff --git a/slsSupportLib/include/UdpRxSocket.h b/slsSupportLib/include/UdpRxSocket.h new file mode 100644 index 000000000..0e6b004a6 --- /dev/null +++ b/slsSupportLib/include/UdpRxSocket.h @@ -0,0 +1,151 @@ + +/* +UdpRxSocket provies socket control to receive +data on a udp socket. + +It provides a drop in replacement for +genericSocket. But please be careful since +this might be deprecated in the future + +*/ + +#include "genericSocket.h" +#include "network_utils.h" +#include "sls_detector_exceptions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sls { + +class UdpRxSocket { + const ssize_t packet_size; + char *buff; + int fd = -1; + + public: + UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr, + ssize_t buffer_size = 0) + : packet_size(packet_size) { + /* hostname = nullptr -> wildcard */ + + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = 0; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + struct addrinfo *res = 0; + + const std::string portname = std::to_string(port); + if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) { + throw RuntimeError("Failed at getaddrinfo with " + + std::string(hostname)); + } + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd == -1) { + throw RuntimeError("Failed to create UDP RX socket"); + } + if (bind(fd, res->ai_addr, res->ai_addrlen) == -1) { + throw RuntimeError("Failed to bind UDP RX socket"); + } + freeaddrinfo(res); + + // If we get a specified buffer size that is larger than the set one + // we set it. Otherwise we leave it there since it could have been + // set by the rx_udpsocksize command + if (buffer_size) { + auto current = getBufferSize() / 2; + if (current < buffer_size) { + setBufferSize(buffer_size); + if (getBufferSize() / 2 < buffer_size) { + FILE_LOG(logWARNING) + << "Could not set buffer size. Got: " + << getBufferSize() / 2 << " instead of " << buffer_size; + } + } + } + // Allocate at the end to avoid memory leak if we throw + buff = new char[packet_size]; + } + + // Delegating constructor to allow drop in replacement for old socket class + // This one might be removed in the future + UdpRxSocket(unsigned short int const port_number, + genericSocket::communicationProtocol p, + int ps = DEFAULT_PACKET_SIZE, const char *eth = NULL, + int hsize = 0, uint64_t buf_size = SOCKET_BUFFER_SIZE) + : UdpRxSocket(port_number, ps, InterfaceNameToIp(eth).str().c_str(), + buf_size) {} + + ~UdpRxSocket() { + delete[] buff; + Shutdown(); + } + + const char *LastPacket() const noexcept { return buff; } + constexpr ssize_t getPacketSize() const noexcept { return packet_size; } + + bool ReceivePacket() noexcept { + auto bytes_received = + recvfrom(fd, buff, packet_size, 0, nullptr, nullptr); + return bytes_received == packet_size; + } + + bool ReceivePacket(char *dst) noexcept { + auto bytes_received = + recvfrom(fd, buff, packet_size, 0, nullptr, nullptr); + return bytes_received == packet_size; + } + + // Only for backwards compatibility this function will be removed during + // refactoring of the receiver + ssize_t ReceiveDataOnly(char *dst) { + auto r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr); + constexpr ssize_t eiger_header_packet = + 40; // only detector that has this + if (r == eiger_header_packet) { + FILE_LOG(logWARNING) << "Got header pkg"; + r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr); + } + return r; + } + + ssize_t getBufferSize() const { + uint64_t ret_size = 0; + socklen_t optlen = sizeof(uint64_t); + if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1) + return -1; + else + return ret_size; + } + + // Only for backwards compatibility will be removed + ssize_t getActualUDPSocketBufferSize() const { return getBufferSize(); } + + // Only for backwards compatibility will be removed + void ShutDownSocket() { Shutdown(); } + + void setBufferSize(ssize_t size) { + socklen_t optlen = sizeof(size); + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, optlen)) { + throw RuntimeError("Could not set socket buffer size"); + } + } + + void Shutdown() { + shutdown(fd, SHUT_RDWR); + if (fd >= 0) { + close(fd); + fd = -1; + } + } +}; + +} // namespace sls \ No newline at end of file diff --git a/slsSupportLib/include/network_utils.h b/slsSupportLib/include/network_utils.h index ca90002bc..b010451f8 100755 --- a/slsSupportLib/include/network_utils.h +++ b/slsSupportLib/include/network_utils.h @@ -62,7 +62,7 @@ class MacAddr { IpAddr HostnameToIp(const char *hostname); std::string IpToInterfaceName(const std::string& ip); MacAddr InterfaceNameToMac(const std::string& inf); - +IpAddr InterfaceNameToIp(const std::string& ifn); std::ostream &operator<<(std::ostream &out, const IpAddr &addr); std::ostream &operator<<(std::ostream &out, const MacAddr &addr); diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 1fba61b89..dc0cdea8c 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -3,10 +3,10 @@ #define APILIB 0x190723 #define APIRECEIVER 0x190722 #define APIGUI 0x190723 -#define APIMOENCH 0x190820 -#define APICTB 0x200122 -#define APIGOTTHARD 0x200122 #define APIEIGER 0x200122 -#define APIMYTHEN3 0x200122 -#define APIGOTTHARD2 0x200123 -#define APIJUNGFRAU 0x200123 +#define APIGOTTHARD 0x200130 +#define APICTB 0x200131 +#define APIJUNGFRAU 0x200131 +#define APIMOENCH 0x200131 +#define APIMYTHEN3 0x200213 +#define APIGOTTHARD2 0x200204 diff --git a/slsSupportLib/src/ServerInterface2.cpp b/slsSupportLib/src/ServerInterface.cpp similarity index 83% rename from slsSupportLib/src/ServerInterface2.cpp rename to slsSupportLib/src/ServerInterface.cpp index 6406dfb61..2c6ee0e7c 100644 --- a/slsSupportLib/src/ServerInterface2.cpp +++ b/slsSupportLib/src/ServerInterface.cpp @@ -1,10 +1,10 @@ -#include "ServerInterface2.h" +#include "ServerInterface.h" #include #include #include namespace sls { -int ServerInterface2::sendResult(int ret, void *retval, int retvalSize, +int ServerInterface::sendResult(int ret, void *retval, int retvalSize, char *mess) { write(&ret, sizeof(ret)); diff --git a/slsSupportLib/src/ServerSocket.cpp b/slsSupportLib/src/ServerSocket.cpp index 93c9398da..9cd5723b3 100755 --- a/slsSupportLib/src/ServerSocket.cpp +++ b/slsSupportLib/src/ServerSocket.cpp @@ -1,4 +1,4 @@ -#include "ServerInterface2.h" +#include "ServerInterface.h" #include "ServerSocket.h" #include "DataSocket.h" @@ -37,7 +37,7 @@ ServerSocket::ServerSocket(int port) } } -ServerInterface2 ServerSocket::accept() { +ServerInterface ServerSocket::accept() { lastClient = thisClient; //update from previous connection struct sockaddr_in clientAddr; socklen_t addr_size = sizeof clientAddr; @@ -49,7 +49,7 @@ ServerInterface2 ServerSocket::accept() { char tc[INET_ADDRSTRLEN]{}; inet_ntop(AF_INET, &(clientAddr.sin_addr), tc, INET_ADDRSTRLEN); thisClient = IpAddr{tc}; - return ServerInterface2(newSocket); + return ServerInterface(newSocket); } }; // namespace sls diff --git a/slsSupportLib/src/network_utils.cpp b/slsSupportLib/src/network_utils.cpp index 2a55ab8ed..b53cd7aaa 100755 --- a/slsSupportLib/src/network_utils.cpp +++ b/slsSupportLib/src/network_utils.cpp @@ -1,36 +1,33 @@ #include "sls_detector_exceptions.h" #include +#include #include #include #include +#include #include -#include -#include -#include +#include #include +#include +#include +#include #include #include -#include -#include -#include #include "network_utils.h" namespace sls { - IpAddr::IpAddr(const std::string &address) { inet_pton(AF_INET, address.c_str(), &addr_); } IpAddr::IpAddr(const char *address) { inet_pton(AF_INET, address, &addr_); } -std::string IpAddr::str() const { - return arr().data(); -} +std::string IpAddr::str() const { return arr().data(); } -std::array IpAddr::arr() const{ +std::array IpAddr::arr() const { std::array ipstring{}; inet_ntop(AF_INET, &addr_, ipstring.data(), INET_ADDRSTRLEN); return ipstring; @@ -96,7 +93,7 @@ IpAddr HostnameToIp(const char *hostname) { } std::string IpToInterfaceName(const std::string &ip) { - //TODO! Copied from genericSocket needs to be refactored! + // TODO! Copied from genericSocket needs to be refactored! struct ifaddrs *addrs, *iap; struct sockaddr_in *sa; @@ -122,33 +119,61 @@ std::string IpToInterfaceName(const std::string &ip) { return std::string(buf); } -MacAddr InterfaceNameToMac(const std::string& inf) { - //TODO! Copied from genericSocket needs to be refactored! - struct ifreq ifr; - char mac[32]; - const int mac_len = sizeof(mac); - memset(mac,0,mac_len); +IpAddr InterfaceNameToIp(const std::string &ifn) { + struct ifaddrs *ifaddr, *ifa; + // int family, s; + char host[NI_MAXHOST]; - int sock=socket(PF_INET, SOCK_STREAM, 0); - strncpy(ifr.ifr_name,inf.c_str(),sizeof(ifr.ifr_name)-1); - ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0'; + if (getifaddrs(&ifaddr) == -1) { + return {}; + } + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; - if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) { - perror("ioctl(SIOCGIFHWADDR) "); - return MacAddr{}; - } - for (int j=0, k=0; j<6; j++) { - k+=snprintf(mac+k, mac_len-k-1, j ? ":%02X" : "%02X", - (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]); - } - mac[mac_len-1]='\0'; + auto s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, + NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - if(sock!=1){ - close(sock); - } - return MacAddr(mac); + if ((strcmp(ifa->ifa_name, ifn.c_str()) == 0) && + (ifa->ifa_addr->sa_family == AF_INET)) { + if (s != 0) { + return {}; + } + break; + } + } - } + freeifaddrs(ifaddr); + return IpAddr{host}; +} + +MacAddr InterfaceNameToMac(const std::string &inf) { + // TODO! Copied from genericSocket needs to be refactored! + struct ifreq ifr; + char mac[32]; + const int mac_len = sizeof(mac); + memset(mac, 0, mac_len); + + int sock = socket(PF_INET, SOCK_STREAM, 0); + strncpy(ifr.ifr_name, inf.c_str(), sizeof(ifr.ifr_name) - 1); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + if (-1 == ioctl(sock, SIOCGIFHWADDR, &ifr)) { + perror("ioctl(SIOCGIFHWADDR) "); + return MacAddr{}; + } + for (int j = 0, k = 0; j < 6; j++) { + k += snprintf( + mac + k, mac_len - k - 1, j ? ":%02X" : "%02X", + (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]); + } + mac[mac_len - 1] = '\0'; + + if (sock != 1) { + close(sock); + } + return MacAddr(mac); +} } // namespace sls diff --git a/slsSupportLib/tests/CMakeLists.txt b/slsSupportLib/tests/CMakeLists.txt index 6a7315042..bb84225d5 100755 --- a/slsSupportLib/tests/CMakeLists.txt +++ b/slsSupportLib/tests/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-FixedCapacityContainer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-ToString.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-TypeTraits.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test-UdpRxSocket.cpp ) \ No newline at end of file diff --git a/slsSupportLib/tests/test-UdpRxSocket.cpp b/slsSupportLib/tests/test-UdpRxSocket.cpp new file mode 100644 index 000000000..452fa9e72 --- /dev/null +++ b/slsSupportLib/tests/test-UdpRxSocket.cpp @@ -0,0 +1,89 @@ +#include "UdpRxSocket.h" +#include "catch.hpp" +#include "sls_detector_exceptions.h" +#include +#include +#include + +int open_socket(int port) { + const char *host = nullptr; // localhost + + // Create a socket for sending + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = 0; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + struct addrinfo *res = 0; + + const std::string portname = std::to_string(port); + if (getaddrinfo(host, portname.c_str(), &hints, &res)) { + throw sls::RuntimeError("Failed at getaddrinfo with " + + std::string(host)); + } + int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd == -1) { + throw sls::RuntimeError("Failed to create UDP RX socket"); + } + + if (connect(fd, res->ai_addr, res->ai_addrlen)){ + throw sls::RuntimeError("Failed to connect socket"); + } + freeaddrinfo(res); + return fd; +} + +TEST_CASE("Receive a packet on localhost") { + constexpr int port = 50001; + + std::vector data_to_send{4, 5, 3, 2, 5, 7, 2, 3}; + ssize_t packet_size = + sizeof(decltype(data_to_send)::value_type) * data_to_send.size(); + sls::UdpRxSocket udpsock{port, packet_size}; + + + int fd = open_socket(port); + // int n = sendto(fd, data_to_send.data(), packet_size, 0, res->ai_addr, + // res->ai_addrlen); + + auto n = write(fd, data_to_send.data(), packet_size); + CHECK(n == packet_size); + CHECK(udpsock.ReceivePacket()); + close(fd); + // Copy data from buffer and compare values + std::vector data_received(data_to_send.size()); + memcpy(data_received.data(), udpsock.LastPacket(), udpsock.getPacketSize()); + CHECK(data_received.size() == data_to_send.size()); // sanity check + for (size_t i = 0; i != data_to_send.size(); ++i) { + CHECK(data_to_send[i] == data_received[i]); + } +} + +TEST_CASE("Shutdown socket without hanging") { + constexpr int port = 50001; + constexpr ssize_t packet_size = 8000; + sls::UdpRxSocket s{port, packet_size}; + + // Start a thread and wait for package + // if the socket is left open we would block + std::future ret = + std::async(static_cast( + &sls::UdpRxSocket::ReceivePacket), + &s); + + s.Shutdown(); + auto r = ret.get(); + + CHECK(r == false); // since we didn't get the packet +} + +TEST_CASE("Too small packet"){ + constexpr int port = 50001; + sls::UdpRxSocket s(port, 2*sizeof(uint32_t)); + auto fd = open_socket(port); + uint32_t val = 10; + write(fd, &val, sizeof(val)); + CHECK(s.ReceivePacket() == false); + close(fd); +} \ No newline at end of file diff --git a/tests/src/testserver.cpp b/tests/src/testserver.cpp index 3e6d65795..03a1996f7 100644 --- a/tests/src/testserver.cpp +++ b/tests/src/testserver.cpp @@ -3,7 +3,7 @@ #include "tests/testenum.h" -#include "ServerInterface2.h" +#include "ServerInterface.h" #include "container_utils.h" #include #include @@ -15,7 +15,7 @@ struct EnumClassHash { } }; -using Interface = sls::ServerInterface2; +using Interface = sls::ServerInterface; using func_ptr = void (*)(Interface &); /********************************************