mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-17 15:27:13 +02:00
Compare commits
275 Commits
2022.2.3.d
...
2022.05.10
Author | SHA1 | Date | |
---|---|---|---|
cd4520b051 | |||
0129c2c686 | |||
f55bdd6eae | |||
36a1159f38 | |||
98e2ddbb74 | |||
fa12ab2858 | |||
afeee5501c | |||
b7153fe3e0 | |||
2db2694660 | |||
e1642cf37c | |||
086d22f1a3 | |||
52882cba20 | |||
27c7fd9a97 | |||
5d16ba7e16 | |||
d8c6f9141d | |||
e9dc3d8c38 | |||
62418c1316 | |||
835aa575b0 | |||
b42d65c5e2 | |||
150d27cf95 | |||
95ed9551c0 | |||
0f2ec47b5f | |||
fe895cd782 | |||
11bf6a5c58 | |||
8bce87c082 | |||
61f38bf5a9 | |||
cbc7066620 | |||
509ed9101f | |||
191cfa0abe | |||
f712847061 | |||
b875a95bd5 | |||
45f57ebeb7 | |||
0309eba3c6 | |||
f0448b3cec | |||
a18af0b726 | |||
6aa5cb8d3e | |||
479906a9eb | |||
28a503ed5a | |||
b3c5a431d0 | |||
43cde3609a | |||
9d2d8fe1d7 | |||
1826dd46cb | |||
cf6423dbbe | |||
8b1851e652 | |||
5913864cbb | |||
c2ef6d700e | |||
76296507ff | |||
03d2158472 | |||
bb7b676ca2 | |||
e1988bf088 | |||
8ef1a209c9 | |||
28572af3ab | |||
c57e528447 | |||
74e325edb4 | |||
e68499bb09 | |||
8ce6868e46 | |||
f5cca7a98f | |||
b9aa0f46e4 | |||
6cd780ae99 | |||
f2be834d55 | |||
e55e18d5e9 | |||
66900da476 | |||
13ec32c79a | |||
1ff35edb99 | |||
9a969c1549 | |||
039e1fd829 | |||
fc41d4313f | |||
4bd4364a3a | |||
4b697dd9db | |||
6470277e43 | |||
2453390cc3 | |||
fa694dbc4c | |||
ea1222ac5b | |||
cbed2e88c6 | |||
4cce1dbd7f | |||
1710177af4 | |||
5c79a1a1e8 | |||
0f02ffdc9a | |||
83d76267f9 | |||
9ff43efdc5 | |||
21c21a423d | |||
e479b7d4be | |||
8f0398681e | |||
b112cf81c4 | |||
589124845a | |||
90d1d0f8b8 | |||
1e564a1b33 | |||
5fe10c19a1 | |||
de5c298d99 | |||
2a1f6dc544 | |||
fc21a6763d | |||
fd8e1b2ef7 | |||
0803f1bc1f | |||
9995b74217 | |||
2823451c9d | |||
0f4bcf3a9d | |||
74d55db3f0 | |||
2b35101b17 | |||
f538b8b10b | |||
fb012aa9e9 | |||
82bad7fec6 | |||
717922f380 | |||
3250dda7eb | |||
dffac3014e | |||
586149f3e7 | |||
088dd2c9f8 | |||
89395bd990 | |||
3144f40068 | |||
2fe24c108b | |||
bbfe3b278f | |||
c9fd8ba569 | |||
faa4f09a82 | |||
1ca2e61a85 | |||
7fa51e2a8e | |||
adbd2b853d | |||
0e6d92118f | |||
3796182eb1 | |||
570651a9f8 | |||
afbc414afe | |||
ca0aa7144c | |||
3e5b8840b4 | |||
f1da831e10 | |||
06281ccae9 | |||
509946d964 | |||
95f9da9d70 | |||
4a663e9e50 | |||
b02dec8157 | |||
c361b9517c | |||
78823760b3 | |||
d80006a024 | |||
561777dad6 | |||
c1895c4bc8 | |||
7b66466186 | |||
ef1c52ddc1 | |||
7bd4b9d9d9 | |||
39d3ee2b15 | |||
401467c700 | |||
c9769579e3 | |||
7663d4ef53 | |||
9c1bc262e5 | |||
c17914e0a1 | |||
7d91a15834 | |||
43c46841c1 | |||
fc6c6985e6 | |||
14c63810d6 | |||
6f0eebfbb8 | |||
c8bed64b91 | |||
e1762605e8 | |||
62fff64d87 | |||
7a39822813 | |||
de9e83fd61 | |||
80d31bbb10 | |||
45171d82a4 | |||
9e050060f3 | |||
ed5a1cdf1c | |||
34588356e8 | |||
b6d63a8381 | |||
dd8aebb0ab | |||
261ac78743 | |||
0437bd0584 | |||
46578d1447 | |||
5566cfd24f | |||
5869c25658 | |||
0b7c202f98 | |||
4db34effda | |||
5a5d4eadf1 | |||
b9016fad12 | |||
a1ee681135 | |||
219318a52e | |||
89edf58f41 | |||
ef3df36e55 | |||
6d2302bcc1 | |||
939fc70284 | |||
6695b10354 | |||
94adba72bf | |||
1063e8b929 | |||
c9abeace8f | |||
5bfdbf59a2 | |||
1cd347a54d | |||
76eb09eb04 | |||
a936cc26cc | |||
92beb3aa2a | |||
543eb7bb60 | |||
2034362eca | |||
7245db5cc8 | |||
8c4a4b7182 | |||
11ad019d47 | |||
e29d73251e | |||
c14fb92c16 | |||
e4b80703ae | |||
2b2533f465 | |||
8f632db2a0 | |||
daa536077d | |||
bf1df92303 | |||
5e97bcde7f | |||
aa7dee1011 | |||
54313af2f8 | |||
ab302a5160 | |||
7a607c6dd1 | |||
83ff4ab112 | |||
fb631187fa | |||
8770c9f6fb | |||
6e0d7b91bd | |||
6433704086 | |||
aea0efa1b6 | |||
8ffa2c1d65 | |||
47f9ab4027 | |||
0d521b64b6 | |||
0fb6c8b823 | |||
d2731c77a3 | |||
40a9dce7e0 | |||
2ba89b8a45 | |||
4cfb35c176 | |||
4107938921 | |||
6d794cdf4b | |||
29cd944c11 | |||
e5ec218e5f | |||
0ac20a3bc8 | |||
c38f292613 | |||
faa9ecf97c | |||
6e32679def | |||
649451f824 | |||
83a65f85ab | |||
8eb5c19187 | |||
a1888bf7c9 | |||
fa929b138e | |||
7eb9cb1840 | |||
7e5e9faf1c | |||
9a9a8ae836 | |||
f2cca765be | |||
e8ededc1d1 | |||
dc1fbb8ce4 | |||
2cf539c16e | |||
bcca99e38c | |||
abfa627246 | |||
f9a88b0f79 | |||
5b4cc53f8c | |||
251f07a9ae | |||
75f98b27a3 | |||
c9fbd7afdf | |||
f228fde6f7 | |||
20f3fb19af | |||
cfe627d348 | |||
753387c34c | |||
83e0599a37 | |||
b8de1955e3 | |||
ac5d60155d | |||
7535decd7f | |||
8f2bacfd53 | |||
771b1e7877 | |||
e8cf366616 | |||
3350e3997e | |||
dae77a50e6 | |||
bb5782eb92 | |||
26faaa307b | |||
bc4cf95d0e | |||
97417737b6 | |||
47c6954044 | |||
7af5d991d9 | |||
cace18e535 | |||
1a1533cad8 | |||
59085f7dc3 | |||
8f30394f63 | |||
f49e45ca6c | |||
ef1e41fc12 | |||
d0f761b2ad | |||
5825428779 | |||
0ed7d1e9b1 | |||
9168bc3ec9 | |||
158719e325 | |||
2a63548f40 | |||
bf83c9b3e2 | |||
c236cbf17b | |||
ca8a1c046a | |||
a4cd4fd14a |
@ -19,6 +19,7 @@ Checks: '*,
|
||||
-google-readability-braces-around-statements,
|
||||
-modernize-use-trailing-return-type,
|
||||
-readability-isolate-declaration,
|
||||
-readability-implicit-bool-conversion,
|
||||
-llvmlibc-*'
|
||||
|
||||
HeaderFilterRegex: \.h
|
||||
|
191
CMakeLists.txt
191
CMakeLists.txt
@ -8,11 +8,8 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
include(cmake/project_version.cmake)
|
||||
|
||||
#functions to add compiler flags
|
||||
include(cmake/SlsAddFlag.cmake)
|
||||
|
||||
# Include additional modules that are used unconditionally
|
||||
include(cmake/SlsFindZeroMQ.cmake)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# If conda build, always set lib dir to 'lib'
|
||||
@ -26,7 +23,7 @@ string(TOLOWER "${PROJECT_NAME}" PROJECT_NAME_LOWER)
|
||||
|
||||
# Set targets export name (used by slsDetectorPackage and dependencies)
|
||||
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWER}-targets")
|
||||
#set(namespace "${PROJECT_NAME}::")
|
||||
set(namespace "sls::")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
@ -37,6 +34,8 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(SLS_MASTER_PROJECT ON)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
option(SLS_USE_HDF5 "HDF5 File format" OFF)
|
||||
option(SLS_BUILD_SHARED_LIBRARIES "Build shared libaries" ON)
|
||||
option(SLS_USE_TEXTCLIENT "Text Client" ON)
|
||||
@ -69,6 +68,20 @@ if(SLS_BUILD_ONLY_MOENCH)
|
||||
endif()
|
||||
|
||||
|
||||
option(SLS_EXT_BUILD "external build of part of the project" OFF)
|
||||
if(SLS_EXT_BUILD)
|
||||
message(STATUS "External build using already installed libraries")
|
||||
set(SLS_BUILD_SHARED_LIBRARIES OFF CACHE BOOL "Should already exist" FORCE)
|
||||
set(SLS_USE_TEXTCLIENT OFF CACHE BOOL "Should already exist" FORCE)
|
||||
set(SLS_USE_DETECTOR OFF CACHE BOOL "Should already exist" FORCE)
|
||||
set(SLS_USE_RECEIVER OFF CACHE BOOL "Should already exist" FORCE)
|
||||
set(SLS_USE_RECEIVER_BINARIES OFF CACHE BOOL "Should already exist" FORCE)
|
||||
set(SLS_MASTER_PROJECT OFF CACHE BOOL "No master proj in case of extbuild" FORCE)
|
||||
endif()
|
||||
|
||||
#Maybe have an option guarding this?
|
||||
set(SLS_INTERNAL_RAPIDJSON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/rapidjson)
|
||||
|
||||
set(ClangFormat_EXCLUDE_PATTERNS "build/"
|
||||
"libs/"
|
||||
"slsDetectorCalibration/"
|
||||
@ -79,9 +92,6 @@ set(ClangFormat_EXCLUDE_PATTERNS "build/"
|
||||
${CMAKE_BINARY_DIR})
|
||||
find_package(ClangFormat)
|
||||
|
||||
|
||||
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
@ -100,62 +110,68 @@ else()
|
||||
endif()
|
||||
|
||||
|
||||
#Add two fake libraries to manage options
|
||||
add_library(slsProjectOptions INTERFACE)
|
||||
add_library(slsProjectWarnings INTERFACE)
|
||||
target_compile_features(slsProjectOptions INTERFACE cxx_std_11)
|
||||
target_compile_options(slsProjectWarnings INTERFACE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
# -Wold-style-cast
|
||||
-Wnon-virtual-dtor
|
||||
-Woverloaded-virtual
|
||||
-Wdouble-promotion
|
||||
-Wformat=2
|
||||
-Wredundant-decls
|
||||
# -Wconversion
|
||||
-Wvla
|
||||
-Wdouble-promotion
|
||||
-Werror=return-type
|
||||
)
|
||||
|
||||
#Settings for C code
|
||||
add_library(slsProjectCSettings INTERFACE)
|
||||
target_compile_options(slsProjectCSettings INTERFACE
|
||||
-std=gnu99 #fixed
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
-Wdouble-promotion
|
||||
-Wformat=2
|
||||
-Wredundant-decls
|
||||
-Wdouble-promotion
|
||||
-Werror=return-type
|
||||
)
|
||||
|
||||
|
||||
#Testing for minimum version for compilers
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.2)
|
||||
message(FATAL_ERROR "Clang version must be at least 3.2!")
|
||||
endif()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
|
||||
message(FATAL_ERROR "GCC version must be at least 4.8!")
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)
|
||||
target_compile_options(slsProjectWarnings INTERFACE
|
||||
-Wno-missing-field-initializers)
|
||||
endif()
|
||||
if(SLS_EXT_BUILD)
|
||||
# Find ourself in case of external build
|
||||
find_package(slsDetectorPackage ${PROJECT_VERSION} REQUIRED)
|
||||
endif()
|
||||
|
||||
# Add or disable warnings depending on if the compiler supports them
|
||||
# The function checks internally and sets HAS_warning-name
|
||||
sls_enable_cxx_warning("-Wnull-dereference")
|
||||
sls_enable_cxx_warning("-Wduplicated-cond")
|
||||
sls_disable_cxx_warning("-Wclass-memaccess")
|
||||
sls_disable_c_warning("-Wstringop-truncation")
|
||||
|
||||
|
||||
# slsProjectOptions and slsProjectWarnings are used
|
||||
# to control options for the libraries
|
||||
if(NOT TARGET slsProjectOptions)
|
||||
add_library(slsProjectOptions INTERFACE)
|
||||
target_compile_features(slsProjectOptions INTERFACE cxx_std_11)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET slsProjectWarnings)
|
||||
add_library(slsProjectWarnings INTERFACE)
|
||||
target_compile_options(slsProjectWarnings INTERFACE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
# -Wold-style-cast
|
||||
-Wnon-virtual-dtor
|
||||
-Woverloaded-virtual
|
||||
-Wdouble-promotion
|
||||
-Wformat=2
|
||||
-Wredundant-decls
|
||||
# -Wconversion
|
||||
-Wvla
|
||||
-Wdouble-promotion
|
||||
-Werror=return-type
|
||||
)
|
||||
# Add or disable warnings depending on if the compiler supports them
|
||||
# The function checks internally and sets HAS_warning-name
|
||||
sls_enable_cxx_warning("-Wnull-dereference")
|
||||
sls_enable_cxx_warning("-Wduplicated-cond")
|
||||
sls_disable_cxx_warning("-Wclass-memaccess")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5 AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(slsProjectWarnings INTERFACE
|
||||
-Wno-missing-field-initializers)
|
||||
endif()
|
||||
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT TARGET slsProjectCSettings)
|
||||
#Settings for C code
|
||||
add_library(slsProjectCSettings INTERFACE)
|
||||
target_compile_options(slsProjectCSettings INTERFACE
|
||||
-std=gnu99 #fixed
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
-Wdouble-promotion
|
||||
-Wformat=2
|
||||
-Wredundant-decls
|
||||
-Wdouble-promotion
|
||||
-Werror=return-type
|
||||
)
|
||||
sls_disable_c_warning("-Wstringop-truncation")
|
||||
endif()
|
||||
|
||||
|
||||
if(SLS_USE_SANITIZER)
|
||||
@ -170,58 +186,22 @@ if(SLS_TUNE_LOCAL)
|
||||
endif()
|
||||
|
||||
|
||||
#rapidjson
|
||||
add_library(rapidjson INTERFACE)
|
||||
target_include_directories(rapidjson INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libs/rapidjson>
|
||||
)
|
||||
|
||||
# Install fake the libraries
|
||||
install(TARGETS slsProjectOptions slsProjectWarnings rapidjson
|
||||
if(SLS_MASTER_PROJECT)
|
||||
install(TARGETS slsProjectOptions slsProjectWarnings
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_INSTALL_RPATH $ORIGIN)
|
||||
# set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
|
||||
set(ZeroMQ_HINT "" CACHE STRING "Hint where ZeroMQ could be found")
|
||||
#Adapted from: https://github.com/zeromq/cppzmq/
|
||||
if (NOT TARGET libzmq)
|
||||
if(ZeroMQ_HINT)
|
||||
message(STATUS "Looking for ZeroMQ in: ${ZeroMQ_HINT}")
|
||||
find_package(ZeroMQ 4
|
||||
NO_DEFAULT_PATH
|
||||
HINTS ${ZeroMQ_DIR}
|
||||
)
|
||||
else()
|
||||
find_package(ZeroMQ 4 QUIET)
|
||||
endif()
|
||||
custom_find_zmq()
|
||||
|
||||
# libzmq autotools install: fallback to pkg-config
|
||||
if(NOT ZeroMQ_FOUND)
|
||||
message(STATUS "CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)")
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/libzmq-pkg-config)
|
||||
find_package(ZeroMQ 4 REQUIRED)
|
||||
endif()
|
||||
|
||||
# TODO "REQUIRED" above should already cause a fatal failure if not found, but this doesn't seem to work
|
||||
if(NOT ZeroMQ_FOUND)
|
||||
message(FATAL_ERROR "ZeroMQ was not found, neither as a CMake package nor via pkg-config")
|
||||
endif()
|
||||
|
||||
if (ZeroMQ_FOUND AND NOT TARGET libzmq)
|
||||
message(FATAL_ERROR "ZeroMQ version not supported!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_target_property(VAR libzmq INTERFACE_INCLUDE_DIRECTORIES)
|
||||
message(STATUS "zmq: ${VAR}")
|
||||
|
||||
if (SLS_USE_TESTS)
|
||||
enable_testing()
|
||||
@ -229,8 +209,9 @@ if (SLS_USE_TESTS)
|
||||
endif(SLS_USE_TESTS)
|
||||
|
||||
|
||||
# Common functionallity to detector and receiver
|
||||
add_subdirectory(slsSupportLib)
|
||||
if(NOT SLS_EXT_BUILD)
|
||||
add_subdirectory(slsSupportLib)
|
||||
endif()
|
||||
|
||||
if (SLS_USE_DETECTOR OR SLS_USE_TEXTCLIENT)
|
||||
add_subdirectory(slsDetectorSoftware)
|
||||
@ -254,7 +235,7 @@ endif (SLS_USE_INTEGRATION_TESTS)
|
||||
|
||||
if (SLS_USE_PYTHON)
|
||||
find_package (Python 3.6 COMPONENTS Interpreter Development)
|
||||
add_subdirectory(libs/pybind11)
|
||||
add_subdirectory(libs/pybind11 ${CMAKE_BINARY_DIR}/bin/)
|
||||
add_subdirectory(python)
|
||||
endif(SLS_USE_PYTHON)
|
||||
|
||||
|
47
RELEASE.txt
47
RELEASE.txt
@ -1,7 +1,7 @@
|
||||
SLS Detector Package Minor Release 6.1.0 released on 25.11.2021
|
||||
SLS Detector Package Minor Release 7.0.0 released on 25.11.2021
|
||||
===============================================================
|
||||
|
||||
This document describes the differences between v6.1.0 and v6.0.0.
|
||||
This document describes the differences between v7.0.0 and v6.x.x
|
||||
|
||||
|
||||
|
||||
@ -28,10 +28,47 @@ This document describes the differences between v6.1.0 and v6.0.0.
|
||||
- changed default vref of adc9257 to 2V for moench (from 1.33V)
|
||||
- moench and ctb - can set the starting frame number of next acquisition
|
||||
- mythen server kernel check incompatible (cet timezone)
|
||||
- m3 server crash (vthrehsold)
|
||||
- rx_arping
|
||||
- rx_threadsids max is now 9 (breaking api)
|
||||
- fixed datastream disabling for eiger. Its only available in 10g mode.
|
||||
- m3 server crash (vthrehsold dac names were not provided)
|
||||
- allow vtrim to be interpolated for Eiger settings
|
||||
|
||||
|
||||
- m3 setThresholdEnergy and setAllThresholdEnergy was overwriting gaincaps with settings enum
|
||||
- can set localhost with virtual server with minimum configuration: (hostname localhost, rx_hostname localhost, udp_dstip auto)
|
||||
- increases the progress according to listened index. (not processed index)
|
||||
- current frame index points to listened frame index (not processed index)
|
||||
- when in discard partial frames or empty mode, the frame number doesnt increase by 1, it increases to that number (so its faster)
|
||||
- file write disabled by default
|
||||
- eiger 12 bit mode
|
||||
- start non blocking acquisition at modular level
|
||||
- connect master commands to api (allow set master for eiger)
|
||||
--ignore-config command line
|
||||
- command line argument 'master' mainly for virtual servers (also master/top for real eiger), only one virtual server for eiger, use command lines for master/top
|
||||
- stop servers also check for errors at startup( in case it was running with an older version)
|
||||
- hostname cmd failed when connecting to servers in update mode (ctb, moench, jungfrau, eiger)
|
||||
- missingpackets signed (negative => extra packets)
|
||||
- framescaught and frameindex now returns a vector for each port
|
||||
- progress looks at activated or enabled ports, so progress does not stagnate
|
||||
- (eiger) disable datastreaming also for virtual servers only for 10g
|
||||
- missing packets also takes care of disabled ports
|
||||
- added geometry to metadata
|
||||
- 10g eiger nextframenumber get fixed.
|
||||
- stop, able to set nextframenumber to a consistent (max + 1) for all modules if different (eiger/ctb/jungfrau/moench)
|
||||
- ctb: can set names for all the dacs
|
||||
- fpga/kernel programming, checks if drive is a special file and not a normal file
|
||||
- gotthard 25 um image reconstructed in gui and virtual hdf5 (firmware updated for slave to reverse channels)
|
||||
- master binary file in json format now
|
||||
- fixed bug introduced in 6.0.0: hdf5 files created 1 file per frame after the initial file which had maxframesperfile
|
||||
- m3 polarity, interpolation (enables all counters when enabled), pump probe, analog pulsing, digital pulsing
|
||||
- updatedetectorserver - removes old server current binary pointing to for blackfin
|
||||
- removing copydetectorserver using tftp
|
||||
>>>>>>> developer
|
||||
- registerCallBackRawDataReady and registerCallBackRawDataModifyReady now gives a sls_receiver_header* instead of a char*, and uint32_t to size_t
|
||||
- registerCallBackStartAcquisition gave incorrect imagesize (+120 bytes). corrected.
|
||||
- registerCallBackStartAcquisition parameter is a const string reference
|
||||
- m3 (runnig config second time with tengiga 0, dr !=32, counters !=0x7) calculated incorrect image size expected
|
||||
- fixed row column indexing (mainly for multi module Jungfrau 2 interfaces )
|
||||
- eiger gui row indices not flipped anymore (fix in config)
|
||||
|
||||
2. Resolved Issues
|
||||
==================
|
||||
|
38
cmake/SlsFindZeroMQ.cmake
Normal file
38
cmake/SlsFindZeroMQ.cmake
Normal file
@ -0,0 +1,38 @@
|
||||
function(custom_find_zmq)
|
||||
set(ZeroMQ_HINT "" CACHE STRING "Hint where ZeroMQ could be found")
|
||||
#Adapted from: https://github.com/zeromq/cppzmq/
|
||||
if (NOT TARGET libzmq)
|
||||
if(ZeroMQ_HINT)
|
||||
message(STATUS "Looking for ZeroMQ in: ${ZeroMQ_HINT}")
|
||||
find_package(ZeroMQ 4
|
||||
NO_DEFAULT_PATH
|
||||
HINTS ${ZeroMQ_HINT}
|
||||
)
|
||||
else()
|
||||
find_package(ZeroMQ 4 QUIET)
|
||||
endif()
|
||||
|
||||
# libzmq autotools install: fallback to pkg-config
|
||||
if(ZeroMQ_FOUND)
|
||||
message(STATUS "Found libzmq using find_package")
|
||||
else()
|
||||
message(STATUS "CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)")
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/libzmq-pkg-config)
|
||||
find_package(ZeroMQ 4 REQUIRED)
|
||||
endif()
|
||||
|
||||
# TODO "REQUIRED" above should already cause a fatal failure if not found, but this doesn't seem to work
|
||||
if(NOT ZeroMQ_FOUND)
|
||||
message(FATAL_ERROR "ZeroMQ was not found, neither as a CMake package nor via pkg-config")
|
||||
endif()
|
||||
|
||||
if (ZeroMQ_FOUND AND NOT TARGET libzmq)
|
||||
message(FATAL_ERROR "ZeroMQ version not supported!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_target_property(VAR libzmq IMPORTED_LOCATION)
|
||||
message(STATUS "Using libzmq: ${VAR}")
|
||||
|
||||
|
||||
endfunction()
|
36
cmake/libzmq-pkg-config/FindZeroMQ.cmake
Executable file
36
cmake/libzmq-pkg-config/FindZeroMQ.cmake
Executable file
@ -0,0 +1,36 @@
|
||||
#From: https://github.com/zeromq/cppzmq/
|
||||
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_LIBZMQ QUIET libzmq)
|
||||
|
||||
set(ZeroMQ_VERSION ${PC_LIBZMQ_VERSION})
|
||||
|
||||
find_path(ZeroMQ_INCLUDE_DIR zmq.h
|
||||
PATHS ${ZeroMQ_DIR}/include
|
||||
${PC_LIBZMQ_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(ZeroMQ_LIBRARY
|
||||
NAMES zmq
|
||||
PATHS ${ZeroMQ_DIR}/lib
|
||||
${PC_LIBZMQ_LIBDIR}
|
||||
${PC_LIBZMQ_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(ZeroMQ_LIBRARY OR ZeroMQ_STATIC_LIBRARY)
|
||||
set(ZeroMQ_FOUND ON)
|
||||
message(STATUS "Found libzmq using PkgConfig")
|
||||
endif()
|
||||
|
||||
set ( ZeroMQ_LIBRARIES ${ZeroMQ_LIBRARY} )
|
||||
set ( ZeroMQ_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIR} )
|
||||
|
||||
if (NOT TARGET libzmq)
|
||||
add_library(libzmq UNKNOWN IMPORTED)
|
||||
set_target_properties(libzmq PROPERTIES
|
||||
IMPORTED_LOCATION ${ZeroMQ_LIBRARIES}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${ZeroMQ_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
include ( FindPackageHandleStandardArgs )
|
||||
find_package_handle_standard_args ( ZeroMQ DEFAULT_MSG ZeroMQ_LIBRARIES ZeroMQ_INCLUDE_DIRS )
|
@ -26,7 +26,7 @@ install(FILES
|
||||
)
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_SOURCE_DIR}/libzmq-pkg-config/FindZeroMQ.cmake"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/libzmq-pkg-config/FindZeroMQ.cmake"
|
||||
COMPONENT devel
|
||||
DESTINATION ${CMAKE_INSTALL_DIR}/libzmq-pkg-config
|
||||
)
|
||||
|
@ -19,4 +19,4 @@ cp build/install/bin/slsMultiReceiver $PREFIX/bin/.
|
||||
|
||||
|
||||
cp build/install/include/sls/* $PREFIX/include/sls
|
||||
cp -r build/install/share/ $PREFIX/share
|
||||
cp -rv build/install/share $PREFIX
|
||||
|
@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
#Copy the Moench executables
|
||||
mkdir -p $PREFIX/bin
|
||||
cp build/install/bin/moench04ZmqProcess $PREFIX/bin/.
|
||||
cp build/install/bin/moenchZmqProcess $PREFIX/bin/.
|
||||
cp build/install/bin/moench* $PREFIX/bin/.
|
||||
|
@ -34,7 +34,7 @@ add_executable(ctbGui
|
||||
ctbAdcs.cpp
|
||||
ctbPattern.cpp
|
||||
ctbAcquisition.cpp
|
||||
${CMAKE_SOURCE_DIR}/slsDetectorCalibration/tiffIO.cpp
|
||||
${CMAKE_SOURCE_DIR}/slsDetectorCalibration/tiffio/src/tiffIO.cpp
|
||||
)
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ target_include_directories(ctbGui PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/slsDetectorCalibration/dataStructures
|
||||
${CMAKE_SOURCE_DIR}/slsDetectorCalibration/interpolations
|
||||
${CMAKE_SOURCE_DIR}/slsDetectorCalibration/
|
||||
${CMAKE_SOURCE_DIR}/slsDetectorCalibration/tiffio/include/
|
||||
)
|
||||
|
||||
# Headders needed for ROOT dictionary generation
|
||||
|
@ -45,6 +45,7 @@ int main() {
|
||||
|
||||
for (const auto &cmd : commands) {
|
||||
std::ostringstream os;
|
||||
std::cout << cmd << '\n';
|
||||
proxy.Call(cmd, {}, -1, slsDetectorDefs::HELP_ACTION, os);
|
||||
|
||||
auto tmp = os.str().erase(0, cmd.size());
|
||||
|
@ -136,7 +136,7 @@ can use dir()
|
||||
'__str__', '__subclasshook__', '_adc_register', '_frozen',
|
||||
'_register', 'acquire', 'adcclk', 'adcphase', 'adcpipeline',
|
||||
'adcreg', 'asamples', 'auto_comp_disable', 'clearAcquiringFlag',
|
||||
'clearBit', 'clearROI', 'client_version', 'config', 'copyDetectorServer',
|
||||
'clearBit', 'clearROI', 'client_version', 'config',
|
||||
'counters', 'daclist', 'dacvalues', 'dbitclk', 'dbitphase' ...
|
||||
|
||||
Since the list for Detector is rather long it's an good idea to filter it.
|
||||
|
@ -5,17 +5,42 @@ Detector Server Upgrade
|
||||
|
||||
**Location:** slsDetectorPackage/serverBin/ folder for every release.
|
||||
|
||||
.. note ::
|
||||
|
||||
For Mythen3, Gotthard2 and Eiger, you need to add scripts to automatically start detector server upon power on. See :ref:`Automatic start<Automatic start servers>` for more details.
|
||||
|
||||
.. note ::
|
||||
|
||||
Eiger requires a manual reboot. Or killall the servers and restart the new linked one. If you are in the process of updating firmware, then don't reboot yet.
|
||||
|
||||
|
||||
From 6.1.1 and above (no tftp required)
|
||||
---------------------------------------
|
||||
|
||||
#. Program from console
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# the following command copies new server, creates a soft link to xxxDetectorServerxxx
|
||||
# [Jungfrau][CTB][Moench] also deletes the old server binary and edits initttab to respawn server on reboot
|
||||
# Then, the detector controller will reboot (except Eiger)
|
||||
sls_detector_put updatedetectorserver /complete-path-to-binary/xxxDetectorServerxxx
|
||||
|
||||
#. Copy the detector server specific config files or any others required to the detector:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sls_detector_put execcommand "tftp pcxxx -r configxxx -g"
|
||||
|
||||
5.0.0 - 6.1.1
|
||||
--------------
|
||||
|
||||
#. Install tftp and copy detector server binary to tftp folder
|
||||
#. Program from console
|
||||
|
||||
.. note ::
|
||||
|
||||
These instructions are for upgrades from v5.0.0. For earlier versions, contact us.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# copies new server from pc tftp folder, creates a soft link to xxxDetectorServerxxx
|
||||
# the following command copies new server from pc tftp folder, creates a soft link to xxxDetectorServerxxx
|
||||
# [Jungfrau][CTB][Moench] also edits initttab to respawn server on reboot
|
||||
# Then, the detector controller will reboot (except Eiger)
|
||||
sls_detector_put copydetectorserver xxxDetectorServerxxx pcxxx
|
||||
@ -27,18 +52,15 @@ Detector Server Upgrade
|
||||
sls_detector_put execcommand "tftp pcxxx -r configxxx -g"
|
||||
|
||||
|
||||
.. note ::
|
||||
|
||||
For Mythen3, Gotthard2 and Eiger, you need to add scripts to automatically start detector server upon power on. See :ref:`Automatic start<Automatic start servers>` for more details.
|
||||
|
||||
.. note ::
|
||||
|
||||
Eiger requires a manual reboot. Or killall the servers and restart the new linked one. If you are in the process of updating firmware, then don't reboot yet.
|
||||
|
||||
|
||||
Errors
|
||||
------
|
||||
Troubleshooting with tftp
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. tftp write error: There is no space left. Please delete some old binaries and try again.
|
||||
|
||||
#. text file busy: You are trying to copy the same server.
|
||||
|
||||
|
||||
Older than 5.0.0
|
||||
-----------------
|
||||
|
||||
Please contact us.
|
Submodule libs/pybind11 updated: 8de7772cc7...914c06fb25
@ -1,27 +0,0 @@
|
||||
#From: https://github.com/zeromq/cppzmq/
|
||||
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_LIBZMQ QUIET libzmq)
|
||||
|
||||
set(ZeroMQ_VERSION ${PC_LIBZMQ_VERSION})
|
||||
find_library(ZeroMQ_LIBRARY NAMES libzmq.so libzmq.dylib libzmq.dll
|
||||
PATHS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS})
|
||||
find_library(ZeroMQ_STATIC_LIBRARY NAMES libzmq-static.a libzmq.a libzmq.dll.a
|
||||
PATHS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS})
|
||||
|
||||
if(ZeroMQ_LIBRARY OR ZeroMQ_STATIC_LIBRARY)
|
||||
set(ZeroMQ_FOUND ON)
|
||||
endif()
|
||||
|
||||
if (TARGET libzmq)
|
||||
# avoid errors defining targets twice
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_library(libzmq SHARED IMPORTED)
|
||||
set_property(TARGET libzmq PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PC_LIBZMQ_INCLUDE_DIRS})
|
||||
set_property(TARGET libzmq PROPERTY IMPORTED_LOCATION ${ZeroMQ_LIBRARY})
|
||||
|
||||
add_library(libzmq-static STATIC IMPORTED ${PC_LIBZMQ_INCLUDE_DIRS})
|
||||
set_property(TARGET libzmq-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PC_LIBZMQ_INCLUDE_DIRS})
|
||||
set_property(TARGET libzmq-static PROPERTY IMPORTED_LOCATION ${ZeroMQ_STATIC_LIBRARY})
|
@ -6,49 +6,57 @@ sls::Detector class. The tool needs the libclang bindings
|
||||
to be installed.
|
||||
|
||||
When the Detector API is updated this file should be run
|
||||
manually
|
||||
manually.
|
||||
"""
|
||||
from clang import cindex
|
||||
import subprocess
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from parse import system_include_paths, clang_format_version
|
||||
|
||||
REDC = '\033[91m'
|
||||
GREENC = '\033[92m'
|
||||
ENDC = '\033[0m'
|
||||
def red(msg):
|
||||
return f'{REDC}{msg}{ENDC}'
|
||||
|
||||
def green(msg):
|
||||
return f'{GREENC}{msg}{ENDC}'
|
||||
|
||||
def check_clang_format_version(required_version):
|
||||
if (ver := clang_format_version()) != required_version:
|
||||
msg = red(f'Clang format version {required_version} required, detected: {ver}. Bye!')
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
else:
|
||||
msg = green(f'Found clang-format version {ver}')
|
||||
print(msg)
|
||||
|
||||
def check_for_compile_commands_json(path):
|
||||
# print(f"Looking for compile data base in: {path}")
|
||||
compile_data_base_file = path/'compile_commands.json'
|
||||
if not compile_data_base_file.exists():
|
||||
msg = red(f"No compile_commands.json file found in {path}. Bye!")
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
else:
|
||||
msg = green(f'Found: {compile_data_base_file}')
|
||||
print(msg)
|
||||
|
||||
from parse import system_include_paths
|
||||
|
||||
default_build_path = "/home/l_frojdh/sls/build/"
|
||||
fpath = "../../slsDetectorSoftware/src/Detector.cpp"
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--build_path",
|
||||
help="Path to the build database",
|
||||
type=str,
|
||||
default=default_build_path,
|
||||
)
|
||||
cargs = parser.parse_args()
|
||||
|
||||
db = cindex.CompilationDatabase.fromDirectory(cargs.build_path)
|
||||
index = cindex.Index.create()
|
||||
args = db.getCompileCommands(fpath)
|
||||
args = list(iter(args).__next__().arguments)[0:-1]
|
||||
args = args + "-x c++ --std=c++11".split()
|
||||
syspath = system_include_paths("clang++")
|
||||
incargs = ["-I" + inc for inc in syspath]
|
||||
args = args + incargs
|
||||
|
||||
|
||||
tu = index.parse(fpath, args=args)
|
||||
|
||||
|
||||
m = []
|
||||
ag = []
|
||||
|
||||
lines = []
|
||||
|
||||
ag2 = []
|
||||
|
||||
cn = []
|
||||
|
||||
def get_arguments(node):
|
||||
@ -66,7 +74,7 @@ def get_arguments_with_default(node):
|
||||
args = []
|
||||
for arg in node.get_arguments():
|
||||
tokens = [t.spelling for t in arg.get_tokens()]
|
||||
print(tokens)
|
||||
# print(tokens)
|
||||
if '=' in tokens:
|
||||
if arg.type.spelling == "sls::Positions": #TODO! automate
|
||||
args.append("py::arg() = Positions{}")
|
||||
@ -111,33 +119,67 @@ def visit(node):
|
||||
lines.append(
|
||||
f'.def("{child.spelling}",{fs} &Detector::{child.spelling}{args})'
|
||||
)
|
||||
if cargs.verbose:
|
||||
print(f'&Detector::{child.spelling}{args})')
|
||||
cn.append(child)
|
||||
for child in node.get_children():
|
||||
visit(child)
|
||||
|
||||
# .def("setRxHostname",
|
||||
# (void (Detector::*)(const std::string &, Positions)) &
|
||||
# Detector::setRxHostname,
|
||||
# py::arg(), py::arg() = Positions{})
|
||||
# .def("setRxHostname",
|
||||
# (void (Detector::*)(const std::vector<std::string> &)) &
|
||||
# Detector::setRxHostname,
|
||||
# py::arg())
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--build_path",
|
||||
help="Path to the build database",
|
||||
type=Path,
|
||||
default=default_build_path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
help="more output",
|
||||
action='store_true',
|
||||
)
|
||||
cargs = parser.parse_args()
|
||||
|
||||
visit(tu.cursor)
|
||||
check_clang_format_version(12)
|
||||
check_for_compile_commands_json(cargs.build_path)
|
||||
|
||||
print("Parsing functions in Detector.h - ", end = "", flush = True)
|
||||
t0 = time.perf_counter()
|
||||
#parse functions
|
||||
db = cindex.CompilationDatabase.fromDirectory(cargs.build_path)
|
||||
index = cindex.Index.create()
|
||||
args = db.getCompileCommands(fpath)
|
||||
args = list(iter(args).__next__().arguments)[0:-1]
|
||||
args = args + "-x c++ --std=c++11".split()
|
||||
syspath = system_include_paths("clang++")
|
||||
incargs = ["-I" + inc for inc in syspath]
|
||||
args = args + incargs
|
||||
tu = index.parse(fpath, args=args)
|
||||
visit(tu.cursor)
|
||||
print(green('OK'))
|
||||
print(f'Parsing took {time.perf_counter()-t0:.3f}s')
|
||||
|
||||
with open("../src/detector_in.cpp") as f:
|
||||
data = f.read()
|
||||
s = "".join(lines)
|
||||
s += ";"
|
||||
text = data.replace("[[FUNCTIONS]]", s)
|
||||
warning = "/* WARINING This file is auto generated any edits might be overwritten without warning */\n\n"
|
||||
with open("../src/detector.cpp", "w") as f:
|
||||
f.write(warning)
|
||||
f.write(text)
|
||||
print("Read detector_in.cpp - ", end = "")
|
||||
with open("../src/detector_in.cpp") as f:
|
||||
data = f.read()
|
||||
s = "".join(lines)
|
||||
s += ";"
|
||||
text = data.replace("[[FUNCTIONS]]", s)
|
||||
warning = "/* WARINING This file is auto generated any edits might be overwritten without warning */\n\n"
|
||||
print(green("OK"))
|
||||
print("Writing to detector.cpp - ", end = "")
|
||||
with open("../src/detector.cpp", "w") as f:
|
||||
f.write(warning)
|
||||
f.write(text)
|
||||
print(green('OK'))
|
||||
|
||||
# run clang format on the output
|
||||
subprocess.run(["clang-format", "../src/detector.cpp", "-i"])
|
||||
# run clang format on the output
|
||||
print('Running clang format on generated source -', end = "")
|
||||
subprocess.run(["clang-format", "../src/detector.cpp", "-i"])
|
||||
print(green(" OK"))
|
||||
|
||||
print("Changes since last commit:")
|
||||
subprocess.run(['git', 'diff', '../src/detector.cpp'])
|
||||
|
@ -5,6 +5,12 @@ import subprocess
|
||||
from subprocess import PIPE
|
||||
import os
|
||||
|
||||
def clang_format_version():
|
||||
p = subprocess.run(['clang-format', '--version'], capture_output = True)
|
||||
ver = p.stdout.decode().split()[2]
|
||||
major = int(ver.split('.')[0])
|
||||
return major
|
||||
|
||||
|
||||
def remove_comments(text):
|
||||
def replacer(match):
|
||||
|
@ -1,43 +1,45 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
from .detector import Detector
|
||||
from .detector import Detector, freeze
|
||||
from .utils import element_if_equal
|
||||
from .dacs import DetectorDacs
|
||||
from .dacs import DetectorDacs, NamedDacs
|
||||
import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
class CtbDacs(DetectorDacs):
|
||||
"""
|
||||
Ctb dacs
|
||||
"""
|
||||
_dacs = [('dac0', dacIndex(0), 0, 4000, 1400),
|
||||
('dac1', dacIndex(1), 0, 4000, 1200),
|
||||
('dac2', dacIndex(2), 0, 4000, 900),
|
||||
('dac3', dacIndex(3), 0, 4000, 1050),
|
||||
('dac4', dacIndex(4), 0, 4000, 1400),
|
||||
('dac5', dacIndex(5), 0, 4000, 655),
|
||||
('dac6', dacIndex(6), 0, 4000, 2000),
|
||||
('dac7', dacIndex(7), 0, 4000, 1400),
|
||||
('dac8', dacIndex(8), 0, 4000, 850),
|
||||
('dac9', dacIndex(9), 0, 4000, 2000),
|
||||
('dac10', dacIndex(10), 0, 4000, 2294),
|
||||
('dac11', dacIndex(11), 0, 4000, 983),
|
||||
('dac12', dacIndex(12), 0, 4000, 1475),
|
||||
('dac13', dacIndex(13), 0, 4000, 1200),
|
||||
('dac14', dacIndex(14), 0, 4000, 1600),
|
||||
('dac15', dacIndex(15), 0, 4000, 1455),
|
||||
('dac16', dacIndex(16), 0, 4000, 0),
|
||||
('dac17', dacIndex(17), 0, 4000, 1000),
|
||||
]
|
||||
_dacnames = [_d[0] for _d in _dacs]
|
||||
# class CtbDacs(DetectorDacs):
|
||||
# """
|
||||
# Ctb dacs
|
||||
# """
|
||||
# _dacs = [('dac0', dacIndex(0), 0, 4000, 1400),
|
||||
# ('dac1', dacIndex(1), 0, 4000, 1200),
|
||||
# ('dac2', dacIndex(2), 0, 4000, 900),
|
||||
# ('dac3', dacIndex(3), 0, 4000, 1050),
|
||||
# ('dac4', dacIndex(4), 0, 4000, 1400),
|
||||
# ('dac5', dacIndex(5), 0, 4000, 655),
|
||||
# ('dac6', dacIndex(6), 0, 4000, 2000),
|
||||
# ('dac7', dacIndex(7), 0, 4000, 1400),
|
||||
# ('dac8', dacIndex(8), 0, 4000, 850),
|
||||
# ('dac9', dacIndex(9), 0, 4000, 2000),
|
||||
# ('dac10', dacIndex(10), 0, 4000, 2294),
|
||||
# ('dac11', dacIndex(11), 0, 4000, 983),
|
||||
# ('dac12', dacIndex(12), 0, 4000, 1475),
|
||||
# ('dac13', dacIndex(13), 0, 4000, 1200),
|
||||
# ('dac14', dacIndex(14), 0, 4000, 1600),
|
||||
# ('dac15', dacIndex(15), 0, 4000, 1455),
|
||||
# ('dac16', dacIndex(16), 0, 4000, 0),
|
||||
# ('dac17', dacIndex(17), 0, 4000, 1000),
|
||||
# ]
|
||||
# _dacnames = [_d[0] for _d in _dacs]
|
||||
|
||||
from .utils import element
|
||||
@freeze
|
||||
class Ctb(Detector):
|
||||
def __init__(self, id = 0):
|
||||
super().__init__(id)
|
||||
self._frozen = False
|
||||
self._dacs = CtbDacs(self)
|
||||
# self._dacs = CtbDacs(self)
|
||||
self._dacs = NamedDacs(self)
|
||||
|
||||
@property
|
||||
def dacs(self):
|
||||
|
@ -36,6 +36,79 @@ class Dac(DetectorProperty):
|
||||
dacstr = ''.join([f'{item:5d}' for item in self.get()])
|
||||
return f'{self.__name__:15s}:{dacstr}'
|
||||
|
||||
class NamedDacs:
|
||||
"""
|
||||
New implementation of the detector dacs. Used at the momen for
|
||||
Ctb but should replace the old one for all detectors
|
||||
"""
|
||||
_frozen = False
|
||||
_direct_access = ['_detector', '_current', '_dacnames']
|
||||
def __init__(self, detector):
|
||||
self._detector = detector
|
||||
self._current = 0
|
||||
|
||||
self._dacnames = [n.replace(" ", "") for n in detector.getDacNames()]
|
||||
# # Populate the dacs
|
||||
for i,name in enumerate(self._dacnames):
|
||||
#name, enum, low, high, default, detector
|
||||
setattr(self, name, Dac(name, dacIndex(i), 0, 4000, 1000, detector))
|
||||
|
||||
self._frozen = True
|
||||
|
||||
# def __getattr__(self, name):
|
||||
# return self.__getattribute__('_' + name)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if not self._frozen:
|
||||
#durining init we need to be able to set up the class
|
||||
super().__setattr__(name, value)
|
||||
else:
|
||||
#Later we restrict us to manipulate dacs and a few fields
|
||||
if name in self._direct_access:
|
||||
super().__setattr__(name, value)
|
||||
elif name in self._dacnames:
|
||||
return self.__getattribute__(name).__setitem__(slice(None, None, None), value)
|
||||
else:
|
||||
raise AttributeError(f'Dac not found: {name}')
|
||||
|
||||
def __next__(self):
|
||||
if self._current >= len(self._dacnames):
|
||||
self._current = 0
|
||||
raise StopIteration
|
||||
else:
|
||||
self._current += 1
|
||||
return self.__getattribute__(self._dacnames[self._current-1])
|
||||
# return self.__getattr__(self._dacnames[self._current-1])
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
r_str = ['========== DACS =========']
|
||||
r_str += [repr(dac) for dac in self]
|
||||
return '\n'.join(r_str)
|
||||
def get_asarray(self):
|
||||
"""
|
||||
Read the dacs into a numpy array with dimensions [ndacs, nmodules]
|
||||
"""
|
||||
dac_array = np.zeros((len(self._dacnames), len(self._detector)))
|
||||
for i, _d in enumerate(self):
|
||||
dac_array[i,:] = _d[:]
|
||||
return dac_array
|
||||
|
||||
def to_array(self):
|
||||
return self.get_asarray()
|
||||
|
||||
def set_from_array(self, dac_array):
|
||||
"""
|
||||
Set the dacs from an numpy array with dac values. [ndacs, nmodules]
|
||||
"""
|
||||
dac_array = dac_array.astype(np.int)
|
||||
for i, _d in enumerate(self):
|
||||
_d[:] = dac_array[i]
|
||||
|
||||
def from_array(self, dac_array):
|
||||
self.set_from_array(dac_array)
|
||||
|
||||
class DetectorDacs:
|
||||
_dacs = []
|
||||
@ -50,7 +123,7 @@ class DetectorDacs:
|
||||
# Index to support iteration
|
||||
self._current = 0
|
||||
|
||||
# Populate the dacs
|
||||
# Name the attributes?
|
||||
for _d in self._dacs:
|
||||
setattr(self, '_'+_d[0], Dac(*_d, detector))
|
||||
|
||||
@ -59,6 +132,9 @@ class DetectorDacs:
|
||||
def __getattr__(self, name):
|
||||
return self.__getattribute__('_' + name)
|
||||
|
||||
@property
|
||||
def dacnames(self):
|
||||
return [_d[0] for _d in _dacs]
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name in self._dacnames:
|
||||
|
@ -258,7 +258,7 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def rx_threads(self):
|
||||
"""
|
||||
Get thread ids from the receiver in order of [parent, tcp, listener 0, processor 0, streamer 0, listener 1, processor 1, streamer 1].
|
||||
Get thread ids from the receiver in order of [parent, tcp, listener 0, processor 0, streamer 0, listener 1, processor 1, streamer 1, arping].
|
||||
|
||||
Note
|
||||
-----
|
||||
@ -268,6 +268,17 @@ class Detector(CppDetectorApi):
|
||||
"""
|
||||
return self.getRxThreadIds()
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_arping(self):
|
||||
"""Starts a thread in slsReceiver to arping the interface it is listening every minute. Useful in 10G mode. """
|
||||
return self.getRxArping()
|
||||
|
||||
@rx_arping.setter
|
||||
def rx_arping(self, value):
|
||||
ut.set_using_dict(self.setRxArping, value)
|
||||
|
||||
|
||||
@property
|
||||
@element
|
||||
def dr(self):
|
||||
@ -276,7 +287,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
Note
|
||||
-----
|
||||
[Eiger] Options: 4, 8, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n
|
||||
[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n
|
||||
[Mythen3] Options: 8, 16, 32 \n
|
||||
[Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16
|
||||
"""
|
||||
@ -588,7 +599,7 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
@element
|
||||
def rx_framescaught(self):
|
||||
"""Number of frames caught by receiver."""
|
||||
"""Number of frames caught by each port in receiver."""
|
||||
return self.getFramesCaught()
|
||||
|
||||
@property
|
||||
@ -1463,6 +1474,19 @@ class Detector(CppDetectorApi):
|
||||
def trimval(self, value):
|
||||
ut.set_using_dict(self.setAllTrimbits, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def master(self):
|
||||
"""
|
||||
[Eiger] Sets half module to master and others to slaves.\n
|
||||
[Gotthard][Gotthard2][Mythen3][Eiger] Gets if the current module/ half module is master.
|
||||
"""
|
||||
return self.getMaster()
|
||||
|
||||
@master.setter
|
||||
def master(self, value):
|
||||
ut.set_using_dict(self.setMaster, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def lock(self):
|
||||
@ -1547,8 +1571,16 @@ class Detector(CppDetectorApi):
|
||||
|
||||
@property
|
||||
def daclist(self):
|
||||
"""Gets the list of enums for every dac for this detector."""
|
||||
return self.getDacList()
|
||||
"""
|
||||
List of enums for every dac for this detector.
|
||||
:setter: Only implemented for Chiptestboard
|
||||
|
||||
"""
|
||||
return self.getDacNames()
|
||||
|
||||
@daclist.setter
|
||||
def daclist(self, value):
|
||||
self.setDacNames(value)
|
||||
|
||||
@property
|
||||
def dacvalues(self):
|
||||
@ -1894,13 +1926,13 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
@element
|
||||
def rx_frameindex(self):
|
||||
"""Current frame index received in receiver during acquisition."""
|
||||
"""Current frame index received for each port in receiver during acquisition."""
|
||||
return self.getRxCurrentFrameIndex()
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_missingpackets(self):
|
||||
"""Gets the number of missing packets for each port in receiver."""
|
||||
"""Gets the number of missing packets for each port in receiver. Negative number denotes extra packets. """
|
||||
return self.getNumMissingPackets()
|
||||
|
||||
"""
|
||||
@ -1913,7 +1945,7 @@ class Detector(CppDetectorApi):
|
||||
def datastream(self):
|
||||
"""
|
||||
datastream [left|right] [0, 1]
|
||||
[Eiger] Enables or disables data streaming from left or/and right side of detector. 1 (enabled) by default.
|
||||
[Eiger] Enables or disables data streaming from left or/and right side of detector for 10GbE mode. 1 (enabled) by default.
|
||||
"""
|
||||
result = {}
|
||||
for port in [defs.LEFT, defs.RIGHT]:
|
||||
@ -2115,6 +2147,21 @@ class Detector(CppDetectorApi):
|
||||
"""
|
||||
return ut.reduce_time(self.getMeasuredSubFramePeriod())
|
||||
|
||||
@property
|
||||
@element
|
||||
def top(self):
|
||||
"""[Eiger] Sets half module to top (1), else bottom.
|
||||
|
||||
Note
|
||||
-----
|
||||
Advanced Function!
|
||||
"""
|
||||
return self.getTop()
|
||||
|
||||
@top.setter
|
||||
def top(self, value):
|
||||
ut.set_using_dict(self.setTop, value)
|
||||
|
||||
"""
|
||||
------------------<<<Jungfrau specific>>>-------------------------
|
||||
"""
|
||||
@ -3451,10 +3498,60 @@ class Detector(CppDetectorApi):
|
||||
|
||||
def readout(self):
|
||||
"""
|
||||
Mythen3] Starts detector readout. Status changes to TRANSMITTING and automatically returns to idle at the end of readout.
|
||||
[Mythen3] Starts detector readout. Status changes to TRANSMITTING and automatically returns to idle at the end of readout.
|
||||
"""
|
||||
self.startDetectorReadout()
|
||||
|
||||
@property
|
||||
@element
|
||||
def polarity(self):
|
||||
"""[Mythen3] Set positive or negative polarity. Enum: polarity"""
|
||||
return self.getPolarity()
|
||||
|
||||
@polarity.setter
|
||||
def polarity(self, value):
|
||||
ut.set_using_dict(self.setPolarity, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def interpolation(self):
|
||||
"""[Mythen3] Enable or disable interpolation. Enabling also enables all counters """
|
||||
return self.getInterpolation()
|
||||
|
||||
@interpolation.setter
|
||||
def interpolation(self, value):
|
||||
ut.set_using_dict(self.setInterpolation, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def pumpprobe(self):
|
||||
"""[Mythen3] Enable or disable pump probe mode. """
|
||||
return self.getPumpProbe()
|
||||
|
||||
@pumpprobe.setter
|
||||
def pumpprobe(self, value):
|
||||
ut.set_using_dict(self.setPumpProbe, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def apulse(self):
|
||||
"""[Mythen3] Enable or disable analog pulsing. """
|
||||
return self.getAnalogPulsing()
|
||||
|
||||
@apulse.setter
|
||||
def apulse(self, value):
|
||||
ut.set_using_dict(self.setAnalogPulsing, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def dpulse(self):
|
||||
"""[Mythen3] Enable or disable digital pulsing. """
|
||||
return self.getDigitalPulsing()
|
||||
|
||||
@dpulse.setter
|
||||
def dpulse(self, value):
|
||||
ut.set_using_dict(self.setDigitalPulsing, value)
|
||||
|
||||
|
||||
"""
|
||||
---------------------------<<<Debug>>>---------------------------
|
||||
|
@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
/* WARINING This file is auto generated any edits might be overwritten without
|
||||
* warning */
|
||||
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include <pybind11/chrono.h>
|
||||
#include <pybind11/operators.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
@ -173,6 +173,12 @@ void init_det(py::module &m) {
|
||||
.def("setFlipRows",
|
||||
(void (Detector::*)(bool, sls::Positions)) & Detector::setFlipRows,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getMaster",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getMaster,
|
||||
py::arg() = Positions{})
|
||||
.def("setMaster", (void (Detector::*)(bool, int)) & Detector::setMaster,
|
||||
py::arg(), py::arg())
|
||||
.def("isVirtualDetectorServer",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::isVirtualDetectorServer,
|
||||
@ -470,7 +476,9 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)()) & Detector::clearAcquiringFlag)
|
||||
.def("startReceiver", (void (Detector::*)()) & Detector::startReceiver)
|
||||
.def("stopReceiver", (void (Detector::*)()) & Detector::stopReceiver)
|
||||
.def("startDetector", (void (Detector::*)()) & Detector::startDetector)
|
||||
.def("startDetector",
|
||||
(void (Detector::*)(sls::Positions)) & Detector::startDetector,
|
||||
py::arg() = Positions{})
|
||||
.def("startDetectorReadout",
|
||||
(void (Detector::*)()) & Detector::startDetectorReadout)
|
||||
.def("stopDetector",
|
||||
@ -485,14 +493,17 @@ void init_det(py::module &m) {
|
||||
Detector::getReceiverStatus,
|
||||
py::arg() = Positions{})
|
||||
.def("getFramesCaught",
|
||||
(Result<int64_t>(Detector::*)(sls::Positions) const) &
|
||||
(Result<std::vector<int64_t>>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getFramesCaught,
|
||||
py::arg() = Positions{})
|
||||
.def(
|
||||
"getNumMissingPackets",
|
||||
(Result<std::vector<uint64_t>>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getNumMissingPackets,
|
||||
py::arg() = Positions{})
|
||||
.def("getNumMissingPackets",
|
||||
(Result<std::vector<int64_t>>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getNumMissingPackets,
|
||||
py::arg() = Positions{})
|
||||
.def("getRxCurrentFrameIndex",
|
||||
(Result<std::vector<int64_t>>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getRxCurrentFrameIndex,
|
||||
py::arg() = Positions{})
|
||||
.def("getNextFrameNumber",
|
||||
(Result<uint64_t>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getNextFrameNumber,
|
||||
@ -765,9 +776,16 @@ void init_det(py::module &m) {
|
||||
Detector::getRxLastClientIP,
|
||||
py::arg() = Positions{})
|
||||
.def("getRxThreadIds",
|
||||
(Result<std::array<pid_t, 8>>(Detector::*)(sls::Positions) const) &
|
||||
(Result<std::array<pid_t, 9>>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getRxThreadIds,
|
||||
py::arg() = Positions{})
|
||||
.def("getRxArping",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getRxArping,
|
||||
py::arg() = Positions{})
|
||||
.def("setRxArping",
|
||||
(void (Detector::*)(bool, sls::Positions)) & Detector::setRxArping,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getFileFormat",
|
||||
(Result<defs::fileFormat>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getFileFormat,
|
||||
@ -997,6 +1015,13 @@ void init_det(py::module &m) {
|
||||
sls::Positions)) &
|
||||
Detector::setDataStream,
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("getTop",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getTop,
|
||||
py::arg() = Positions{})
|
||||
.def("setTop",
|
||||
(void (Detector::*)(bool, sls::Positions)) & Detector::setTop,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getChipVersion",
|
||||
(Result<double>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getChipVersion,
|
||||
@ -1255,10 +1280,6 @@ void init_det(py::module &m) {
|
||||
(Result<std::array<ns, 3>>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getGateDelayForAllGates,
|
||||
py::arg() = Positions{})
|
||||
.def("getMaster",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getMaster,
|
||||
py::arg() = Positions{})
|
||||
.def("getChipStatusRegister",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getChipStatusRegister,
|
||||
@ -1269,6 +1290,46 @@ void init_det(py::module &m) {
|
||||
.def("getGainCaps",
|
||||
(Result<int>(Detector::*)(sls::Positions)) & Detector::getGainCaps,
|
||||
py::arg() = Positions{})
|
||||
.def("getPolarity",
|
||||
(Result<defs::polarity>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getPolarity,
|
||||
py::arg() = Positions{})
|
||||
.def("setPolarity",
|
||||
(void (Detector::*)(defs::polarity, sls::Positions)) &
|
||||
Detector::setPolarity,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getInterpolation",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getInterpolation,
|
||||
py::arg() = Positions{})
|
||||
.def("setInterpolation",
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
Detector::setInterpolation,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getPumpProbe",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getPumpProbe,
|
||||
py::arg() = Positions{})
|
||||
.def("setPumpProbe",
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
Detector::setPumpProbe,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getAnalogPulsing",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getAnalogPulsing,
|
||||
py::arg() = Positions{})
|
||||
.def("setAnalogPulsing",
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
Detector::setAnalogPulsing,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getDigitalPulsing",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getDigitalPulsing,
|
||||
py::arg() = Positions{})
|
||||
.def("setDigitalPulsing",
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
Detector::setDigitalPulsing,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("getNumberOfAnalogSamples",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getNumberOfAnalogSamples,
|
||||
@ -1406,6 +1467,19 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
Detector::setLEDEnable,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("setDacNames",
|
||||
(void (Detector::*)(const std::vector<std::string>)) &
|
||||
Detector::setDacNames,
|
||||
py::arg())
|
||||
.def("getDacNames", (std::vector<std::string>(Detector::*)() const) &
|
||||
Detector::getDacNames)
|
||||
.def("getDacIndex",
|
||||
(defs::dacIndex(Detector::*)(const std::string &)) &
|
||||
Detector::getDacIndex,
|
||||
py::arg())
|
||||
.def("getDacName",
|
||||
(std::string(Detector::*)(defs::dacIndex)) & Detector::getDacName,
|
||||
py::arg())
|
||||
.def("setPattern",
|
||||
(void (Detector::*)(const std::string &, sls::Positions)) &
|
||||
Detector::setPattern,
|
||||
@ -1510,17 +1584,13 @@ void init_det(py::module &m) {
|
||||
Detector::setAdditionalJsonParameter,
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("programFPGA",
|
||||
(void (Detector::*)(const std::string &, sls::Positions)) &
|
||||
(void (Detector::*)(const std::string &, const bool,
|
||||
sls::Positions)) &
|
||||
Detector::programFPGA,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("resetFPGA",
|
||||
(void (Detector::*)(sls::Positions)) & Detector::resetFPGA,
|
||||
py::arg() = Positions{})
|
||||
.def("copyDetectorServer",
|
||||
(void (Detector::*)(const std::string &, const std::string &,
|
||||
sls::Positions)) &
|
||||
Detector::copyDetectorServer,
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("updateDetectorServer",
|
||||
(void (Detector::*)(const std::string &, sls::Positions)) &
|
||||
Detector::updateDetectorServer,
|
||||
@ -1547,7 +1617,7 @@ void init_det(py::module &m) {
|
||||
Detector::getUpdateMode,
|
||||
py::arg() = Positions{})
|
||||
.def("setUpdateMode",
|
||||
(void (Detector::*)(bool, sls::Positions)) &
|
||||
(void (Detector::*)(const bool, sls::Positions)) &
|
||||
Detector::setUpdateMode,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("readRegister",
|
||||
@ -1639,9 +1709,5 @@ void init_det(py::module &m) {
|
||||
Detector::getMeasurementTime,
|
||||
py::arg() = Positions{})
|
||||
.def("getUserDetails",
|
||||
(std::string(Detector::*)() const) & Detector::getUserDetails)
|
||||
.def("getRxCurrentFrameIndex",
|
||||
(Result<uint64_t>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getRxCurrentFrameIndex,
|
||||
py::arg() = Positions{});
|
||||
(std::string(Detector::*)() const) & Detector::getUserDetails);
|
||||
}
|
||||
|
@ -315,4 +315,9 @@ void init_enums(py::module &m) {
|
||||
.value("FIX_G2", slsDetectorDefs::gainMode::FIX_G2)
|
||||
.value("FIX_G0", slsDetectorDefs::gainMode::FIX_G0)
|
||||
.export_values();
|
||||
|
||||
py::enum_<slsDetectorDefs::polarity>(Defs, "polarity")
|
||||
.value("POSITIVE", slsDetectorDefs::polarity::POSITIVE)
|
||||
.value("NEGATIVE", slsDetectorDefs::polarity::NEGATIVE)
|
||||
.export_values();
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ foreach(exe ${MOENCH_EXECUTABLES})
|
||||
../dataStructures
|
||||
../interpolations
|
||||
../../slsReceiverSoftware/include/
|
||||
../../slsSupportLib/include/
|
||||
../../slsSupportLib/include/
|
||||
${SLS_INTERNAL_RAPIDJSON_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(${exe}
|
||||
|
@ -429,23 +429,28 @@ class singlePhotonDetector : public analogDetector<uint16_t> {
|
||||
for (ic = -(clusterSize / 2); ic < (clusterSize / 2) + 1;
|
||||
ic++) {
|
||||
|
||||
if ((iy + ir) >= iy && (iy + ir) < ny &&
|
||||
(ix + ic) >= ix && (ix + ic) < nx) {
|
||||
if ((iy + ir) >= 0 && (iy + ir) < ny &&
|
||||
(ix + ic) >= 0 && (ix + ic) < nx) {
|
||||
|
||||
|
||||
if ((iy + ir) >= iy && (ix + ic) >= ix ) {
|
||||
val[(iy + ir) * nx + ix + ic] =
|
||||
subtractPedestal(data, ix + ic, iy + ir, cm);
|
||||
v = &(val[(iy + ir) * nx + ix + ic]);
|
||||
tot += *v;
|
||||
if (ir <= 0 && ic <= 0)
|
||||
bl += *v;
|
||||
if (ir <= 0 && ic >= 0)
|
||||
br += *v;
|
||||
if (ir >= 0 && ic <= 0)
|
||||
tl += *v;
|
||||
if (ir >= 0 && ic >= 0)
|
||||
tr += *v;
|
||||
if (*v > max) {
|
||||
max = *v;
|
||||
}
|
||||
|
||||
}
|
||||
v = &(val[(iy + ir) * nx + ix + ic]);
|
||||
tot += *v;
|
||||
if (ir <= 0 && ic <= 0)
|
||||
bl += *v;
|
||||
if (ir <= 0 && ic >= 0)
|
||||
br += *v;
|
||||
if (ir >= 0 && ic <= 0)
|
||||
tl += *v;
|
||||
if (ir >= 0 && ic >= 0)
|
||||
tr += *v;
|
||||
if (*v > max) //{
|
||||
max = *v;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -513,12 +518,19 @@ class singlePhotonDetector : public analogDetector<uint16_t> {
|
||||
for (ic = -(clusterSize / 2);
|
||||
ic < (clusterSize / 2) + 1; ic++) {
|
||||
if ((iy + ir) >= 0 && (iy + ir) < ny &&
|
||||
(ix + ic) >= 0 && (ix + ic) < nx)
|
||||
(clusters + nph)
|
||||
(ix + ic) >= 0 && (ix + ic) < nx) {
|
||||
(clusters + nph)
|
||||
->set_data(val[(iy + ir) * nx + ix + ic],
|
||||
ic, ir);
|
||||
if (val[(iy + ir) * nx + ix + ic]>max)
|
||||
good=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (good==0) {
|
||||
(clusters + nph)->print();
|
||||
cout << max << " " << val[iy * nx + ix] << endl;
|
||||
}
|
||||
good = 1;
|
||||
if (eMin > 0 && tot < eMin)
|
||||
good = 0;
|
||||
|
@ -216,14 +216,18 @@ class single_photon_hit {
|
||||
|
||||
// int ix, iy;
|
||||
|
||||
printf("***************\n");
|
||||
printf("** %d %d **\n",x,y);
|
||||
for (int iy = 0; iy < dy; iy++) {
|
||||
for (int ix = 0; ix < dx; ix++) {
|
||||
printf("%d \t", data[ix + iy * dx]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("***************\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
assign the value to the element of the cluster matrix, with relative
|
||||
coordinates where the center of the cluster is (0,0) \param v value to be
|
||||
|
@ -97,6 +97,11 @@
|
||||
<string>65535</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4095</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>255</string>
|
||||
|
@ -91,8 +91,10 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
|
||||
void Update2dPlot();
|
||||
void Update1dXYRange();
|
||||
void Update2dXYRange();
|
||||
void rearrangeGotthard25data(double *data);
|
||||
|
||||
static const int NUM_PEDESTAL_FRAMES = 20;
|
||||
static const int NUM_GOTTHARD25_CHANS = 1280;
|
||||
sls::Detector *det;
|
||||
slsDetectorDefs::detectorType detType;
|
||||
|
||||
@ -164,4 +166,5 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
|
||||
uint32_t pixelMask{0};
|
||||
uint32_t gainMask{0};
|
||||
int gainOffset{0};
|
||||
bool gotthard25;
|
||||
};
|
||||
|
@ -69,5 +69,11 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject {
|
||||
enum { DYNAMIC, FORCE_SWITCH_G1, FORCE_SWITCH_G2, FIX_G1, FIX_G2, FIX_G0 };
|
||||
bool isVisibleFixG0{false};
|
||||
|
||||
enum { DYNAMICRANGE_32, DYNAMICRANGE_16, DYNAMICRANGE_8, DYNAMICRANGE_4 };
|
||||
enum {
|
||||
DYNAMICRANGE_32,
|
||||
DYNAMICRANGE_16,
|
||||
DYNAMICRANGE_12,
|
||||
DYNAMICRANGE_8,
|
||||
DYNAMICRANGE_4
|
||||
};
|
||||
};
|
||||
|
@ -80,6 +80,10 @@ void qDrawPlot::SetupWidgetWindow() {
|
||||
fileSaveName = "Image";
|
||||
}
|
||||
|
||||
gotthard25 = ((detType == slsDetectorDefs::GOTTHARD2 ||
|
||||
detType == slsDetectorDefs::GOTTHARD) &&
|
||||
det->size() == 2);
|
||||
|
||||
SetupPlots();
|
||||
SetDataCallBack(true);
|
||||
det->registerAcquisitionFinishedCallback(&(GetAcquisitionFinishedCallBack),
|
||||
@ -807,6 +811,11 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
|
||||
isGainDataExtracted = false;
|
||||
}
|
||||
|
||||
// gotthard25um rearranging
|
||||
if (gotthard25) {
|
||||
rearrangeGotthard25data(rawData);
|
||||
}
|
||||
|
||||
// title and frame index titles
|
||||
plotTitle =
|
||||
plotTitlePrefix + QString(data->fileName.c_str()).section('/', -1);
|
||||
@ -1064,6 +1073,8 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size,
|
||||
// mythen3 / gotthard2 debugging
|
||||
int discardBits = numDiscardBits;
|
||||
|
||||
uint16_t temp = 0;
|
||||
uint8_t *src = (uint8_t *)source;
|
||||
switch (dr) {
|
||||
|
||||
case 4:
|
||||
@ -1083,6 +1094,19 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size,
|
||||
}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
for (ichan = 0; ichan < size; ++ichan) {
|
||||
temp = (*src++ & 0xFF);
|
||||
temp |= ((*src & 0xF) << 8u);
|
||||
dest[ichan] = (double)temp;
|
||||
++ichan;
|
||||
|
||||
temp = ((*src++ & 0xF0) >> 4u);
|
||||
temp |= ((*src++ & 0xFF) << 4u);
|
||||
dest[ichan] = (double)temp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (detType == slsDetectorDefs::JUNGFRAU ||
|
||||
detType == slsDetectorDefs::GOTTHARD2) {
|
||||
@ -1130,6 +1154,18 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size,
|
||||
}
|
||||
}
|
||||
|
||||
void qDrawPlot::rearrangeGotthard25data(double *data) {
|
||||
const int nChans = NUM_GOTTHARD25_CHANS;
|
||||
double temp[nChans * 2] = {0.0};
|
||||
for (int i = 0; i != nChans; ++i) {
|
||||
// master module
|
||||
temp[i * 2] = data[i];
|
||||
// slave module
|
||||
temp[i * 2 + 1] = data[nChans + i];
|
||||
}
|
||||
memcpy(data, temp, nChans * 2 * sizeof(double));
|
||||
}
|
||||
|
||||
void qDrawPlot::UpdatePlot() {
|
||||
std::lock_guard<std::mutex> lock(mPlots);
|
||||
LOG(logDEBUG) << "Update Plot";
|
||||
|
@ -60,13 +60,19 @@ void qTabSettings::SetupWidgetWindow() {
|
||||
QStandardItemModel *model =
|
||||
qobject_cast<QStandardItemModel *>(comboDynamicRange->model());
|
||||
if (model) {
|
||||
QModelIndex index;
|
||||
QStandardItem *item;
|
||||
index =
|
||||
model->index(DYNAMICRANGE_4, comboDynamicRange->modelColumn(),
|
||||
comboDynamicRange->rootModelIndex());
|
||||
item = model->itemFromIndex(index);
|
||||
item->setEnabled(false);
|
||||
int dr = DYNAMICRANGE_4;
|
||||
for (int i = 0; i != 2; ++i) {
|
||||
// disable dr 4
|
||||
QModelIndex index =
|
||||
model->index(dr, comboDynamicRange->modelColumn(),
|
||||
comboDynamicRange->rootModelIndex());
|
||||
item = model->itemFromIndex(index);
|
||||
item->setEnabled(false);
|
||||
|
||||
// disable dr 12
|
||||
dr = DYNAMICRANGE_12;
|
||||
}
|
||||
}
|
||||
} else if (detType == slsDetectorDefs::EIGER) {
|
||||
lblDynamicRange->setEnabled(true);
|
||||
@ -305,6 +311,9 @@ void qTabSettings::GetDynamicRange() {
|
||||
case 16:
|
||||
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_16);
|
||||
break;
|
||||
case 12:
|
||||
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_12);
|
||||
break;
|
||||
case 8:
|
||||
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_8);
|
||||
break;
|
||||
@ -333,6 +342,9 @@ void qTabSettings::SetDynamicRange(int index) {
|
||||
case DYNAMICRANGE_16:
|
||||
det->setDynamicRange(16);
|
||||
break;
|
||||
case DYNAMICRANGE_12:
|
||||
det->setDynamicRange(12);
|
||||
break;
|
||||
case DYNAMICRANGE_8:
|
||||
det->setDynamicRange(8);
|
||||
break;
|
||||
|
Binary file not shown.
@ -433,16 +433,21 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
if (mapCSP0() == FAIL) {
|
||||
LOG(logERROR,
|
||||
("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!updateFlag && initError == OK) {
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
if (mapCSP0() == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
sharedMemory_setStop(0);
|
||||
#endif
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
@ -702,8 +707,16 @@ void resetPeripheral() {
|
||||
}
|
||||
|
||||
/* set parameters - dr, adcenablemask */
|
||||
int setDynamicRange(int dr) {
|
||||
if (dr == 16)
|
||||
return OK;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
|
||||
int getDynamicRange(int *retval) {
|
||||
*retval = DYNAMIC_RANGE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setADCEnableMask(uint32_t mask) {
|
||||
if (mask == 0u) {
|
||||
@ -2047,8 +2060,8 @@ void *start_timer(void *arg) {
|
||||
header->frameNumber = frameNr + iframes;
|
||||
header->packetNumber = i;
|
||||
header->modId = 0;
|
||||
header->row = detPos[X];
|
||||
header->column = detPos[Y];
|
||||
header->row = detPos[Y];
|
||||
header->column = detPos[X];
|
||||
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header),
|
||||
|
@ -177,7 +177,7 @@ void Beb_AdjustIPChecksum(struct udp_header_type *ip) {
|
||||
ip->ip_header_checksum[1] = ip_checksum & 0xff;
|
||||
}
|
||||
|
||||
void Beb_GetModuleConfiguration(int *master, int *top, int *normal) {
|
||||
int Beb_GetModuleConfiguration(int *master, int *top, int *normal) {
|
||||
*top = 0;
|
||||
*master = 0;
|
||||
// mapping new memory to read master top module configuration
|
||||
@ -187,6 +187,7 @@ void Beb_GetModuleConfiguration(int *master, int *top, int *normal) {
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd < 0) {
|
||||
LOG(logERROR, ("Module Configuration FAIL\n"));
|
||||
return FAIL;
|
||||
} else {
|
||||
// read data
|
||||
ret = Beb_Read32(csp0base, BEB_CONFIG_RD_OFST);
|
||||
@ -202,6 +203,7 @@ void Beb_GetModuleConfiguration(int *master, int *top, int *normal) {
|
||||
// close file pointer
|
||||
Beb_close(fd, csp0base);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Beb_IsTransmitting(int *retval, int tengiga, int waitForDelay) {
|
||||
@ -492,6 +494,11 @@ int Beb_SetDataStream(enum portPosition port, int enable) {
|
||||
u_int32_t reg = XPAR_GPIO_P15_STREAMING_REG;
|
||||
u_int32_t mask = (port == LEFT ? XPAR_GPIO_LFT_STRM_DSBL_MSK
|
||||
: XPAR_GPIO_RGHT_STRM_DSBL_MSK);
|
||||
// invert left/right if bottom
|
||||
if (!Beb_top) {
|
||||
mask = (port == LEFT ? XPAR_GPIO_RGHT_STRM_DSBL_MSK
|
||||
: XPAR_GPIO_LFT_STRM_DSBL_MSK);
|
||||
}
|
||||
|
||||
u_int32_t value = Beb_Read32(csp0base, reg);
|
||||
// disabling in firmware
|
||||
@ -529,6 +536,11 @@ int Beb_GetDataStream(enum portPosition port, int *retval) {
|
||||
u_int32_t reg = XPAR_GPIO_P15_STREAMING_REG;
|
||||
u_int32_t mask = (port == LEFT ? XPAR_GPIO_LFT_STRM_DSBL_MSK
|
||||
: XPAR_GPIO_RGHT_STRM_DSBL_MSK);
|
||||
// invert left/right if bottom
|
||||
if (!Beb_top) {
|
||||
mask = (port == LEFT ? XPAR_GPIO_RGHT_STRM_DSBL_MSK
|
||||
: XPAR_GPIO_LFT_STRM_DSBL_MSK);
|
||||
}
|
||||
|
||||
u_int32_t value = Beb_Read32(csp0base, reg);
|
||||
// disabling in firmware
|
||||
@ -682,6 +694,10 @@ int Beb_GetTransmissionDelayLeft() {
|
||||
return Beb_deactivated_transmission_delay_left;
|
||||
}
|
||||
u_int32_t offset = TXM_DELAY_LEFT_OFFSET;
|
||||
// invert left/right if bottom
|
||||
if (!Beb_top) {
|
||||
offset = TXM_DELAY_RIGHT_OFFSET;
|
||||
}
|
||||
u_int32_t *csp0base = 0;
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd <= 0) {
|
||||
@ -706,6 +722,10 @@ int Beb_SetTransmissionDelayLeft(int value) {
|
||||
return 1;
|
||||
}
|
||||
u_int32_t offset = TXM_DELAY_LEFT_OFFSET;
|
||||
// invert left/right if bottom
|
||||
if (!Beb_top) {
|
||||
offset = TXM_DELAY_RIGHT_OFFSET;
|
||||
}
|
||||
u_int32_t *csp0base = 0;
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd <= 0) {
|
||||
@ -726,6 +746,10 @@ int Beb_GetTransmissionDelayRight() {
|
||||
}
|
||||
|
||||
u_int32_t offset = TXM_DELAY_RIGHT_OFFSET;
|
||||
// invert left/right if bottom
|
||||
if (!Beb_top) {
|
||||
offset = TXM_DELAY_LEFT_OFFSET;
|
||||
}
|
||||
u_int32_t *csp0base = 0;
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd <= 0) {
|
||||
@ -750,6 +774,10 @@ int Beb_SetTransmissionDelayRight(int value) {
|
||||
return 1;
|
||||
}
|
||||
u_int32_t offset = TXM_DELAY_RIGHT_OFFSET;
|
||||
// invert left/right if bottom
|
||||
if (!Beb_top) {
|
||||
offset = TXM_DELAY_LEFT_OFFSET;
|
||||
}
|
||||
u_int32_t *csp0base = 0;
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd <= 0) {
|
||||
@ -836,11 +864,17 @@ void Beb_ResetFrameNumber() {
|
||||
}
|
||||
|
||||
int Beb_SetUpTransferParameters(short the_bit_mode) {
|
||||
if (the_bit_mode != 4 && the_bit_mode != 8 && the_bit_mode != 16 &&
|
||||
the_bit_mode != 32)
|
||||
switch (the_bit_mode) {
|
||||
case 4:
|
||||
case 8:
|
||||
case 12:
|
||||
case 16:
|
||||
case 32:
|
||||
Beb_bit_mode = the_bit_mode;
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
Beb_bit_mode = the_bit_mode;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int Beb_StopAcquisition() {
|
||||
@ -1061,19 +1095,19 @@ int *Beb_GetDetectorPosition() { return Beb_positions; }
|
||||
int Beb_SetDetectorPosition(int pos[]) {
|
||||
if (!Beb_activated)
|
||||
return OK;
|
||||
LOG(logINFO, ("Got Position values %d %d...\n", pos[0], pos[1]));
|
||||
LOG(logINFO, ("Setting Position: (%d, %d)\n", pos[X], pos[Y]));
|
||||
|
||||
// save positions
|
||||
Beb_positions[0] = pos[0];
|
||||
Beb_positions[1] = pos[1];
|
||||
Beb_positions[Y] = pos[Y];
|
||||
Beb_positions[X] = pos[X];
|
||||
|
||||
// get left and right
|
||||
int posLeft[2] = {pos[0], Beb_top ? pos[1] : pos[1] + 1};
|
||||
int posRight[2] = {pos[0], Beb_top ? pos[1] + 1 : pos[1]};
|
||||
int posLeft[2] = {Beb_top ? pos[X] : pos[X] + 1, pos[Y]};
|
||||
int posRight[2] = {Beb_top ? pos[X] + 1 : pos[X], pos[Y]};
|
||||
|
||||
if (Beb_quadEnable) {
|
||||
posRight[0] = 1; // right is next row
|
||||
posRight[1] = 0; // right same first column
|
||||
posRight[Y] = 1; // right is next row
|
||||
posRight[X] = 0; // right same first column
|
||||
}
|
||||
|
||||
int ret = FAIL;
|
||||
@ -1088,7 +1122,7 @@ int Beb_SetDetectorPosition(int pos[]) {
|
||||
uint32_t value = 0;
|
||||
ret = OK;
|
||||
// x left
|
||||
int posval = Beb_swap_uint16(posLeft[0]);
|
||||
int posval = Beb_swap_uint16(posLeft[Y]);
|
||||
value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST);
|
||||
value &= UDP_HEADER_ID_MSK; // to keep previous id value
|
||||
Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST,
|
||||
@ -1100,7 +1134,7 @@ int Beb_SetDetectorPosition(int pos[]) {
|
||||
ret = FAIL;
|
||||
}
|
||||
// x right
|
||||
posval = Beb_swap_uint16(posRight[0]);
|
||||
posval = Beb_swap_uint16(posRight[Y]);
|
||||
value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST);
|
||||
value &= UDP_HEADER_ID_MSK; // to keep previous id value
|
||||
Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST,
|
||||
@ -1113,7 +1147,7 @@ int Beb_SetDetectorPosition(int pos[]) {
|
||||
}
|
||||
|
||||
// y left (column)
|
||||
posval = Beb_swap_uint16(posLeft[1]);
|
||||
posval = Beb_swap_uint16(posLeft[X]);
|
||||
value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST);
|
||||
value &= UDP_HEADER_Z_MSK; // to keep previous z value
|
||||
Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST,
|
||||
@ -1126,7 +1160,7 @@ int Beb_SetDetectorPosition(int pos[]) {
|
||||
}
|
||||
|
||||
// y right
|
||||
posval = Beb_swap_uint16(posRight[1]);
|
||||
posval = Beb_swap_uint16(posRight[X]);
|
||||
value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST);
|
||||
value &= UDP_HEADER_Z_MSK; // to keep previous z value
|
||||
Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST,
|
||||
@ -1142,10 +1176,10 @@ int Beb_SetDetectorPosition(int pos[]) {
|
||||
Beb_close(fd, csp0base);
|
||||
}
|
||||
if (ret == OK) {
|
||||
LOG(logINFO, ("Position set to...\n"
|
||||
LOG(logINFO, ("Position set to (col, row):\n"
|
||||
"\tLeft: [%d, %d]\n"
|
||||
"\tRight:[%d, %d]\n",
|
||||
posLeft[0], posLeft[1], posRight[0], posRight[1]));
|
||||
posLeft[X], posLeft[Y], posRight[X], posRight[Y]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1225,20 +1259,20 @@ int Beb_GetNextFrameNumber(uint64_t *retval, int tengigaEnable) {
|
||||
|
||||
else {
|
||||
uint64_t left10g =
|
||||
Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_1G_LEFT_MSB_OFST);
|
||||
temp = Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_1G_LEFT_LSB_OFST);
|
||||
Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_10G_LEFT_MSB_OFST);
|
||||
temp = Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_10G_LEFT_LSB_OFST);
|
||||
left10g = ((left10g << 32) | temp) >> 16;
|
||||
++left10g; // increment for firmware
|
||||
|
||||
uint64_t right10g =
|
||||
Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_1G_LEFT_MSB_OFST);
|
||||
temp = Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_1G_LEFT_LSB_OFST);
|
||||
Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_10G_LEFT_MSB_OFST);
|
||||
temp = Beb_Read32(csp0base, UDP_HEADER_GET_FNUM_10G_LEFT_LSB_OFST);
|
||||
right10g = ((right10g << 32) | temp) >> 16;
|
||||
Beb_close(fd, csp0base);
|
||||
++right10g; // increment for firmware
|
||||
|
||||
if (left10g != right10g) {
|
||||
LOG(logERROR, ("Retrieved inconsistent frame numbers from `0g left "
|
||||
LOG(logERROR, ("Retrieved inconsistent frame numbers from 10g left "
|
||||
"%llu and right %llu\n",
|
||||
(long long int)left10g, (long long int)right10g));
|
||||
*retval = (left10g > right10g)
|
||||
|
@ -15,7 +15,7 @@ int Beb_SetHeaderData(uint64_t src_mac, uint32_t src_ip, uint16_t src_port,
|
||||
uint64_t dst_mac, uint32_t dst_ip, uint16_t dst_port);
|
||||
void Beb_AdjustIPChecksum(struct udp_header_type *ip);
|
||||
|
||||
void Beb_GetModuleConfiguration(int *master, int *top, int *normal);
|
||||
int Beb_GetModuleConfiguration(int *master, int *top, int *normal);
|
||||
int Beb_IsTransmitting(int *retval, int tengiga, int waitForDelay);
|
||||
|
||||
void Beb_SetTopVariable(int val);
|
||||
|
@ -16,91 +16,31 @@ include_directories(
|
||||
../../slsSupportLib/include
|
||||
)
|
||||
|
||||
add_executable(eigerDetectorServerMaster_virtual
|
||||
add_executable(eigerDetectorServer_virtual
|
||||
${src}
|
||||
)
|
||||
|
||||
target_include_directories(eigerDetectorServerMaster_virtual
|
||||
target_include_directories(eigerDetectorServer_virtual
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(eigerDetectorServerMaster_virtual
|
||||
PUBLIC EIGERD PCCOMPILE STOP_SERVER
|
||||
PUBLIC VIRTUAL #VIRTUAL_9M
|
||||
PUBLIC VIRTUAL_MASTER
|
||||
)
|
||||
|
||||
target_link_libraries(eigerDetectorServerMaster_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(eigerDetectorServerMaster_virtual PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
install(TARGETS eigerDetectorServerMaster_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
add_executable(eigerDetectorServerSlaveTop_virtual
|
||||
${src}
|
||||
)
|
||||
|
||||
target_include_directories(eigerDetectorServerSlaveTop_virtual
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(eigerDetectorServerSlaveTop_virtual
|
||||
PUBLIC EIGERD PCCOMPILE STOP_SERVER
|
||||
PUBLIC VIRTUAL #VIRTUAL_9M
|
||||
PUBLIC VIRTUAL_TOP
|
||||
)
|
||||
|
||||
target_link_libraries(eigerDetectorServerSlaveTop_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(eigerDetectorServerSlaveTop_virtual PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
install(TARGETS eigerDetectorServerSlaveTop_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
add_executable(eigerDetectorServerSlaveBottom_virtual
|
||||
${src}
|
||||
)
|
||||
|
||||
target_include_directories(eigerDetectorServerSlaveBottom_virtual
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(eigerDetectorServerSlaveBottom_virtual
|
||||
target_compile_definitions(eigerDetectorServer_virtual
|
||||
PUBLIC EIGERD PCCOMPILE STOP_SERVER
|
||||
PUBLIC VIRTUAL #VIRTUAL_9M
|
||||
)
|
||||
|
||||
target_link_libraries(eigerDetectorServerSlaveBottom_virtual
|
||||
target_link_libraries(eigerDetectorServer_virtual
|
||||
PUBLIC pthread rt slsProjectCSettings
|
||||
)
|
||||
|
||||
set_target_properties(eigerDetectorServerSlaveBottom_virtual PROPERTIES
|
||||
set_target_properties(eigerDetectorServer_virtual PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
install(TARGETS eigerDetectorServerSlaveBottom_virtual
|
||||
install(TARGETS eigerDetectorServer_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
|
||||
|
||||
configure_file(config_eiger.txt ${CMAKE_BINARY_DIR}/bin/config_eiger.txt COPYONLY)
|
||||
configure_file(detid_eiger.txt ${CMAKE_BINARY_DIR}/bin/detid_eiger.txt COPYONLY)
|
||||
|
@ -18,7 +18,7 @@
|
||||
const unsigned int Feb_Control_leftAddress = 0x100;
|
||||
const unsigned int Feb_Control_rightAddress = 0x200;
|
||||
|
||||
int Feb_Control_master = 0;
|
||||
int Feb_Control_master = -1;
|
||||
int Feb_Control_normal = 0;
|
||||
int Feb_Control_activated = 1;
|
||||
|
||||
@ -50,17 +50,16 @@ double ratemax = -1;
|
||||
// setup
|
||||
void Feb_Control_activate(int activate) { Feb_Control_activated = activate; }
|
||||
|
||||
void Feb_Control_FebControl() {
|
||||
Feb_Control_staticBits = Feb_Control_acquireNReadoutMode =
|
||||
Feb_Control_triggerMode = Feb_Control_externalEnableMode =
|
||||
Feb_Control_subFrameMode = 0;
|
||||
int Feb_Control_FebControl(int normal) {
|
||||
Feb_Control_staticBits = 0;
|
||||
Feb_Control_acquireNReadoutMode = 0;
|
||||
Feb_Control_triggerMode = 0;
|
||||
Feb_Control_externalEnableMode = 0;
|
||||
Feb_Control_subFrameMode = 0;
|
||||
Feb_Control_trimbit_size = 263680;
|
||||
Feb_Control_last_downloaded_trimbits =
|
||||
malloc(Feb_Control_trimbit_size * sizeof(int));
|
||||
}
|
||||
|
||||
int Feb_Control_Init(int master, int normal) {
|
||||
Feb_Control_master = master;
|
||||
Feb_Control_normal = normal;
|
||||
Feb_Interface_SetAddress(Feb_Control_rightAddress, Feb_Control_leftAddress);
|
||||
if (Feb_Control_activated) {
|
||||
@ -931,7 +930,10 @@ unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec) {
|
||||
|
||||
int Feb_Control_PrepareForAcquisition() {
|
||||
LOG(logINFOBLUE, ("Preparing for Acquisition\n"));
|
||||
Feb_Control_PrintAcquisitionSetup();
|
||||
if (!Feb_Control_PrintAcquisitionSetup()) {
|
||||
LOG(logERROR, ("Could not prepare acquisition\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Feb_Control_Reset() == STATUS_ERROR) {
|
||||
LOG(logERROR, ("Trouble reseting daq or data stream\n"));
|
||||
@ -988,20 +990,26 @@ int Feb_Control_PrepareForAcquisition() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Feb_Control_PrintAcquisitionSetup() {
|
||||
int Feb_Control_PrintAcquisitionSetup() {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
struct tm *timeinfo = localtime(&rawtime);
|
||||
LOG(logINFO,
|
||||
("Starting an exposure: (%s)"
|
||||
"\t Dynamic range nbits: %d\n"
|
||||
"\t Trigger mode: 0x%x\n"
|
||||
"\t Number of exposures: %d\n"
|
||||
"\t Exsposure time (if used): %f seconds.\n"
|
||||
"\t Exsposure period (if used): %f seconds.\n\n",
|
||||
asctime(timeinfo), Feb_Control_GetDynamicRange(),
|
||||
Feb_Control_triggerMode, Feb_Control_GetNExposures(),
|
||||
Feb_Control_exposure_time_in_sec, Feb_Control_exposure_period_in_sec));
|
||||
int dr = 0;
|
||||
if (!Feb_Control_GetDynamicRange(&dr)) {
|
||||
LOG(logERROR, ("Could not print acquisition set up\n"));
|
||||
return 0;
|
||||
}
|
||||
LOG(logINFO, ("Starting an exposure: (%s)"
|
||||
"\t Dynamic range nbits: %d\n"
|
||||
"\t Trigger mode: 0x%x\n"
|
||||
"\t Number of exposures: %d\n"
|
||||
"\t Exsposure time (if used): %f seconds.\n"
|
||||
"\t Exsposure period (if used): %f seconds.\n\n",
|
||||
asctime(timeinfo), dr, Feb_Control_triggerMode,
|
||||
Feb_Control_GetNExposures(), Feb_Control_exposure_time_in_sec,
|
||||
Feb_Control_exposure_period_in_sec));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Feb_Control_StartAcquisition() {
|
||||
@ -1169,49 +1177,106 @@ int Feb_Control_SoftwareTrigger(int block) {
|
||||
}
|
||||
|
||||
// parameters
|
||||
int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo) {
|
||||
int Feb_Control_SetDynamicRange(int dr) {
|
||||
static unsigned int everything_but_bit_mode = DAQ_STATIC_BIT_PROGRAM |
|
||||
DAQ_STATIC_BIT_CHIP_TEST |
|
||||
DAQ_STATIC_BIT_ROTEST;
|
||||
if (four_eight_sixteen_or_thirtytwo == 4) {
|
||||
switch (dr) {
|
||||
case 4:
|
||||
Feb_Control_staticBits =
|
||||
DAQ_STATIC_BIT_M4 |
|
||||
(Feb_Control_staticBits &
|
||||
everything_but_bit_mode); // leave test bits in currernt state
|
||||
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
|
||||
} else if (four_eight_sixteen_or_thirtytwo == 8) {
|
||||
break;
|
||||
case 8:
|
||||
Feb_Control_staticBits = DAQ_STATIC_BIT_M8 | (Feb_Control_staticBits &
|
||||
everything_but_bit_mode);
|
||||
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
|
||||
} else if (four_eight_sixteen_or_thirtytwo == 16) {
|
||||
break;
|
||||
case 12:
|
||||
case 16:
|
||||
Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits &
|
||||
everything_but_bit_mode);
|
||||
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
|
||||
} else if (four_eight_sixteen_or_thirtytwo == 32) {
|
||||
|
||||
// disable 16 bit conversion if 12 bit mode (enable if 16 bit)
|
||||
if (!Feb_Control_Disable16bitConversion(dr == 12))
|
||||
return 0;
|
||||
break;
|
||||
case 32:
|
||||
Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits &
|
||||
everything_but_bit_mode);
|
||||
Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
|
||||
} else {
|
||||
LOG(logERROR, ("dynamic range (%d) not valid, not setting bit mode.\n",
|
||||
four_eight_sixteen_or_thirtytwo));
|
||||
break;
|
||||
default:
|
||||
LOG(logERROR,
|
||||
("dynamic range (%d) not valid, not setting bit mode.\n", dr));
|
||||
LOG(logINFO, ("Set dynamic range int must equal 4,8 16, or 32.\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG(logINFO,
|
||||
("Dynamic range set to %d\n", four_eight_sixteen_or_thirtytwo));
|
||||
LOG(logINFO, ("Dynamic range set to %d\n", dr));
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int Feb_Control_GetDynamicRange() {
|
||||
if (Feb_Control_subFrameMode & DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING)
|
||||
return 32;
|
||||
else if (DAQ_STATIC_BIT_M4 & Feb_Control_staticBits)
|
||||
return 4;
|
||||
else if (DAQ_STATIC_BIT_M8 & Feb_Control_staticBits)
|
||||
return 8;
|
||||
int Feb_Control_GetDynamicRange(int *retval) {
|
||||
if (Feb_Control_subFrameMode & DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) {
|
||||
*retval = 32;
|
||||
} else if (DAQ_STATIC_BIT_M4 & Feb_Control_staticBits) {
|
||||
*retval = 4;
|
||||
} else if (DAQ_STATIC_BIT_M8 & Feb_Control_staticBits) {
|
||||
*retval = 8;
|
||||
} else {
|
||||
int disable16 = 0;
|
||||
if (!Feb_Control_Get16bitConversionDisabled(&disable16)) {
|
||||
LOG(logERROR, ("Could not get dynamic range (12 or 16 bit)\n"));
|
||||
return 0;
|
||||
}
|
||||
if (disable16) {
|
||||
*retval = 12;
|
||||
} else {
|
||||
*retval = 16;
|
||||
}
|
||||
}
|
||||
|
||||
return 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Feb_Control_Disable16bitConversion(int disable) {
|
||||
LOG(logINFO, ("%s 16 bit expansion\n", disable ? "Disabling" : "Enabling"));
|
||||
unsigned int regval = 0;
|
||||
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, ®val)) {
|
||||
LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n",
|
||||
(disable ? "disable" : "enable")));
|
||||
return 0;
|
||||
}
|
||||
if (disable) {
|
||||
regval |= DAQ_REG_HRDWRE_DSBL_16BIT_MSK;
|
||||
} else {
|
||||
regval &= ~DAQ_REG_HRDWRE_DSBL_16BIT_MSK;
|
||||
}
|
||||
|
||||
if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) {
|
||||
LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n",
|
||||
(disable ? "disable" : "enable")));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Feb_Control_Get16bitConversionDisabled(int *ret) {
|
||||
unsigned int regval = 0;
|
||||
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, ®val)) {
|
||||
LOG(logERROR, ("Could not get 16 bit expansion (bit mode)\n"));
|
||||
return 0;
|
||||
}
|
||||
if (regval & DAQ_REG_HRDWRE_DSBL_16BIT_MSK) {
|
||||
*ret = 1;
|
||||
} else {
|
||||
*ret = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Feb_Control_SetReadoutSpeed(unsigned int readout_speed) {
|
||||
@ -1490,9 +1555,8 @@ int Feb_Control_SetTop(enum TOPINDEX ind, int left, int right) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Feb_Control_SetMasterVariable(int val) { Feb_Control_master = val; }
|
||||
|
||||
int Feb_Control_SetMaster(enum MASTERINDEX ind) {
|
||||
|
||||
uint32_t offset = DAQ_REG_HRDWRE;
|
||||
unsigned int addr[2] = {Feb_Control_leftAddress, Feb_Control_rightAddress};
|
||||
char *master_names[] = {MASTER_NAMES};
|
||||
@ -1529,9 +1593,31 @@ int Feb_Control_SetMaster(enum MASTERINDEX ind) {
|
||||
LOG(logINFOBLUE, ("%s Master flag to %s Feb\n",
|
||||
(ind == MASTER_HARDWARE ? "Resetting" : "Overwriting"),
|
||||
master_names[ind]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Feb_Control_SetMasterEffects(int master, int controlServer) {
|
||||
int prevMaster = Feb_Control_master;
|
||||
|
||||
Feb_Control_master = master;
|
||||
// change in master for 9m
|
||||
if (controlServer && prevMaster != Feb_Control_master &&
|
||||
!Feb_Control_normal) {
|
||||
if (prevMaster) {
|
||||
Feb_Control_CloseSerialCommunication();
|
||||
}
|
||||
if (Feb_Control_master) {
|
||||
if (!Feb_Control_OpenSerialCommunication()) {
|
||||
LOG(logERROR, ("Could not intitalize feb control serial "
|
||||
"communication\n"));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Feb_Control_SetQuad(int val) {
|
||||
LOG(logINFO, ("Setting Quad to %d in Feb\n", val));
|
||||
Feb_Control_quadMode = val;
|
||||
@ -1554,7 +1640,10 @@ int Feb_Control_SetChipSignalsToTrimQuad(int enable) {
|
||||
regval &= ~(DAQ_REG_HRDWRE_PROGRAM_MSK | DAQ_REG_HRDWRE_M8_MSK);
|
||||
}
|
||||
|
||||
return Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval);
|
||||
if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) {
|
||||
LOG(logERROR, ("Could not set chip signals to trim quad\n"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1604,7 +1693,7 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
|
||||
|
||||
for (int iloop = 0; iloop < 2; ++iloop) {
|
||||
if (run[iloop]) {
|
||||
LOG(logINFO,
|
||||
LOG(logDEBUG1,
|
||||
("Writing 0x%x to %s 0x%x\n", data, side[iloop], actualOffset));
|
||||
if (!Feb_Interface_WriteRegister(addr[iloop], actualOffset, data, 0,
|
||||
0)) {
|
||||
@ -1612,6 +1701,18 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
|
||||
side[iloop], actualOffset));
|
||||
return 0;
|
||||
}
|
||||
uint32_t regVal = 0;
|
||||
if (!Feb_Interface_ReadRegister(addr[iloop], actualOffset,
|
||||
®Val)) {
|
||||
LOG(logERROR, ("Could not read %s register\n", addr[iloop]));
|
||||
return 0;
|
||||
}
|
||||
if (regVal != data) {
|
||||
LOG(logERROR,
|
||||
("Could not write %s register. Write 0x%x, read 0x%x\n",
|
||||
addr[iloop], data, regVal));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1648,8 +1749,8 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
|
||||
side[iloop], actualOffset));
|
||||
return 0;
|
||||
}
|
||||
LOG(logINFO, ("Read 0x%x from %s 0x%x\n", value[iloop], side[iloop],
|
||||
actualOffset));
|
||||
LOG(logDEBUG1, ("Read 0x%x from %s 0x%x\n", value[iloop],
|
||||
side[iloop], actualOffset));
|
||||
*retval = value[iloop];
|
||||
// if not the other (left, not right OR right, not left), return the
|
||||
// value
|
||||
@ -1824,7 +1925,11 @@ int64_t Feb_Control_Get_RateTable_Period_in_nsec() {
|
||||
|
||||
int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec) {
|
||||
// period = exptime if 16bit, period = subexptime if 32 bit
|
||||
int dr = Feb_Control_GetDynamicRange();
|
||||
int dr = 0;
|
||||
if (!Feb_Control_GetDynamicRange(&dr)) {
|
||||
LOG(logERROR, ("Could not set rate correction tau\n"));
|
||||
return 0;
|
||||
}
|
||||
double period_in_sec =
|
||||
(double)(Feb_Control_GetSubFrameExposureTime()) / (double)1e9;
|
||||
if (dr == 16)
|
||||
|
@ -7,8 +7,7 @@
|
||||
|
||||
// setup
|
||||
void Feb_Control_activate(int activate);
|
||||
void Feb_Control_FebControl();
|
||||
int Feb_Control_Init(int master, int normal);
|
||||
int Feb_Control_FebControl(int normal);
|
||||
int Feb_Control_OpenSerialCommunication();
|
||||
void Feb_Control_CloseSerialCommunication();
|
||||
int Feb_Control_CheckSetup();
|
||||
@ -55,7 +54,7 @@ int Feb_Control_ResetChipPartially();
|
||||
int Feb_Control_SendBitModeToBebServer();
|
||||
unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec);
|
||||
int Feb_Control_PrepareForAcquisition();
|
||||
void Feb_Control_PrintAcquisitionSetup();
|
||||
int Feb_Control_PrintAcquisitionSetup();
|
||||
int Feb_Control_StartAcquisition();
|
||||
int Feb_Control_StopAcquisition();
|
||||
int Feb_Control_IsReadyForTrigger(int *readyForTrigger);
|
||||
@ -63,8 +62,10 @@ int Feb_Control_SendSoftwareTrigger();
|
||||
int Feb_Control_SoftwareTrigger(int block);
|
||||
|
||||
// parameters
|
||||
int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo);
|
||||
unsigned int Feb_Control_GetDynamicRange();
|
||||
int Feb_Control_SetDynamicRange(int dr);
|
||||
int Feb_Control_GetDynamicRange(int *retval);
|
||||
int Feb_Control_Disable16bitConversion(int disable);
|
||||
int Feb_Control_Get16bitConversionDisabled();
|
||||
int Feb_Control_SetReadoutSpeed(unsigned int readout_speed);
|
||||
int Feb_Control_SetReadoutMode(unsigned int readout_mode);
|
||||
int Feb_Control_SetTriggerMode(unsigned int trigger_mode);
|
||||
@ -86,8 +87,8 @@ int Feb_Control_Get_Counter_Bit();
|
||||
int Feb_Control_SetInterruptSubframe(int val);
|
||||
int Feb_Control_GetInterruptSubframe();
|
||||
int Feb_Control_SetTop(enum TOPINDEX ind, int left, int right);
|
||||
void Feb_Control_SetMasterVariable(int val);
|
||||
int Feb_Control_SetMaster(enum MASTERINDEX ind);
|
||||
int Feb_Control_SetMasterEffects(int master, int controlServer);
|
||||
int Feb_Control_SetQuad(int val);
|
||||
int Feb_Control_SetChipSignalsToTrimQuad(int enable);
|
||||
int Feb_Control_SetReadNRows(int value);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#define DAQ_REG_HRDWRE_OW_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_OW_MASTER_OFST)
|
||||
#define DAQ_REG_HRDWRE_MASTER_OFST (4)
|
||||
#define DAQ_REG_HRDWRE_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_MASTER_OFST)
|
||||
#define DAQ_REG_HRDWRE_DSBL_16BIT_OFST (5)
|
||||
#define DAQ_REG_HRDWRE_DSBL_16BIT_MSK (0x00000001 << DAQ_REG_HRDWRE_DSBL_16BIT_OFST)
|
||||
#define DAQ_REG_HRDWRE_PROGRAM_OFST (30)
|
||||
#define DAQ_REG_HRDWRE_PROGRAM_MSK (0x00000001 << DAQ_REG_HRDWRE_PROGRAM_OFST)
|
||||
#define DAQ_REG_HRDWRE_M8_OFST (31)
|
||||
|
Binary file not shown.
@ -19,19 +19,24 @@
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
extern int portno;
|
||||
// Global variable from slsDetectorServer_funcs
|
||||
extern int debugflag;
|
||||
extern int updateFlag;
|
||||
extern udpStruct udpDetails[MAX_UDP_DESTINATION];
|
||||
extern int numUdpDestinations;
|
||||
extern const enum detectorType myDetectorType;
|
||||
extern int ignoreConfigFileFlag;
|
||||
|
||||
// Global variable from communication_funcs.c
|
||||
extern int isControlServer;
|
||||
extern void getMacAddressinString(char *cmac, int size, uint64_t mac);
|
||||
extern void getIpAddressinString(char *cip, uint32_t ip);
|
||||
|
||||
// Variables that will be exported
|
||||
int masterCommandLine = -1;
|
||||
int topCommandLine = -1;
|
||||
|
||||
int initError = OK;
|
||||
int initCheckDone = 0;
|
||||
char initErrorMessage[MAX_STR_LENGTH];
|
||||
@ -226,6 +231,23 @@ int getModuleId(int *ret, char *mess) {
|
||||
return getModuleIdInFile(ret, mess, ID_FILE);
|
||||
}
|
||||
|
||||
int updateModuleId() {
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
if (initError == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
eiger_virtual_module_id = modid;
|
||||
#else
|
||||
if (Beb_SetModuleId(modid) == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage, ("Could not get module id from the file"));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
u_int64_t getDetectorMAC() {
|
||||
char mac[255] = "";
|
||||
u_int64_t res = 0;
|
||||
@ -305,46 +327,36 @@ u_int32_t getDetectorIP() {
|
||||
void initControlServer() {
|
||||
LOG(logINFOBLUE, ("Configuring Control server\n"));
|
||||
if (!updateFlag && initError == OK) {
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
#ifdef VIRTUAL
|
||||
eiger_virtual_module_id = modid;
|
||||
#endif
|
||||
if (initError == FAIL) {
|
||||
if (updateModuleConfiguration() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
getModuleConfiguration();
|
||||
#ifndef VIRTUAL
|
||||
sharedMemory_lockLocalLink();
|
||||
Feb_Control_SetMasterVariable(master);
|
||||
Feb_Interface_FebInterface();
|
||||
Feb_Control_FebControl();
|
||||
// same addresses for top and bottom
|
||||
if (!Feb_Control_Init(master, normal)) {
|
||||
if (!Feb_Control_FebControl(normal)) {
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage, "Could not intitalize feb control\n");
|
||||
sprintf(initErrorMessage,
|
||||
"Could not intitalize eiger detector sever: feb control\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
// master of 9M, check high voltage serial communication to blackfin
|
||||
if (master && !normal) {
|
||||
if (!Feb_Control_OpenSerialCommunication()) {
|
||||
initError = FAIL;
|
||||
sprintf(
|
||||
initErrorMessage,
|
||||
"Could not intitalize feb control serial communication\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
if (Feb_Control_SetMasterEffects(master, isControlServer) == FAIL) {
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage, "Could not intitalize HV for eiger "
|
||||
"detector server: feb control serial "
|
||||
"communication\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
LOG(logDEBUG1, ("Control server: FEB Initialization done\n"));
|
||||
Beb_SetTopVariable(top);
|
||||
Beb_Beb();
|
||||
Beb_SetModuleId(modid);
|
||||
LOG(logDEBUG1, ("Control server: BEB Initialization done\n"));
|
||||
#endif
|
||||
// also reads config file and deactivates
|
||||
@ -354,73 +366,126 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
if (!updateFlag && initError == OK) {
|
||||
// wait a few s (control server is setting top/master from config file/
|
||||
// command line)
|
||||
usleep(WAIT_STOP_SERVER_START);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
if (updateModuleConfiguration() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
getModuleConfiguration();
|
||||
sharedMemory_setStop(0);
|
||||
// get top/master in virtual
|
||||
readConfigFile();
|
||||
sharedMemory_setStop(0);
|
||||
// force top or master if in config file
|
||||
if (readConfigFile() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
// force top or master if in command line
|
||||
if (checkCommandLineConfiguration() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// wait a few s (control server is setting top/master from config file)
|
||||
usleep(WAIT_STOP_SERVER_START);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
// exit(-1);
|
||||
getModuleConfiguration();
|
||||
sharedMemory_lockLocalLink();
|
||||
Feb_Control_SetMasterVariable(master);
|
||||
Feb_Interface_FebInterface();
|
||||
Feb_Control_FebControl();
|
||||
// same addresses for top and bottom
|
||||
Feb_Control_Init(master, normal);
|
||||
sharedMemory_unlockLocalLink();
|
||||
LOG(logDEBUG1, ("Stop server: FEB Initialization done\n"));
|
||||
// control server read config file and already set up master/top
|
||||
sharedMemory_lockLocalLink();
|
||||
Feb_Interface_FebInterface();
|
||||
if (!Feb_Control_FebControl(normal)) {
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage, "Could not intitalize feb control\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
if (Feb_Control_SetMasterEffects(master, isControlServer) == FAIL) {
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage, "Could not intitalize HV for eiger "
|
||||
"detector server: feb control serial "
|
||||
"communication\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
LOG(logDEBUG1, ("Stop server: FEB Initialization done\n"));
|
||||
Beb_SetTopVariable(top);
|
||||
Beb_Beb();
|
||||
LOG(logDEBUG1, ("Control server: BEB Initialization done\n"));
|
||||
#endif
|
||||
// client first connect (from shm) will activate
|
||||
if (setActivate(0) == FAIL) {
|
||||
LOG(logERROR, ("Could not deactivate in stop server\n"));
|
||||
// client first connect (from shm) will activate
|
||||
if (setActivate(0) == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage, "Could not deactivate\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
}
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
void getModuleConfiguration() {
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
void checkVirtual9MFlag() {
|
||||
#ifdef VIRTUAL
|
||||
#ifdef VIRTUAL_MASTER
|
||||
master = 1;
|
||||
top = 1;
|
||||
#else
|
||||
master = 0;
|
||||
#ifdef VIRTUAL_TOP
|
||||
top = 1;
|
||||
#else
|
||||
top = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VIRTUAL_9M
|
||||
normal = 0;
|
||||
#else
|
||||
normal = 1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
Beb_GetModuleConfiguration(&master, &top, &normal);
|
||||
int updateModuleConfiguration() {
|
||||
if (getModuleConfiguration(&master, &top, &normal) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
checkVirtual9MFlag();
|
||||
#endif
|
||||
if (isControlServer) {
|
||||
LOG(logINFOBLUE,
|
||||
("Module: %s %s %s\n", (top ? "TOP" : "BOTTOM"),
|
||||
(master ? "MASTER" : "SLAVE"), (normal ? "NORMAL" : "SPECIAL")));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getModuleConfiguration(int *m, int *t, int *n) {
|
||||
if (initError == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
*m = master;
|
||||
*t = top;
|
||||
*n = normal;
|
||||
#else
|
||||
if (Beb_GetModuleConfiguration(m, t, n) == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage, ("Could not get module configuration\n"));
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
LOG(logDEBUG,
|
||||
("module config read: master:%d top:%d normal:%d\n", *m, *t, *n));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int readConfigFile() {
|
||||
|
||||
if (initError == FAIL) {
|
||||
return initError;
|
||||
}
|
||||
master = -1;
|
||||
|
||||
if (ignoreConfigFileFlag) {
|
||||
LOG(logWARNING, ("Ignoring Config file\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifndef VIRTUAL
|
||||
// if not found in config file, they will be reset to hardware settings
|
||||
top = -1;
|
||||
master = -1;
|
||||
#endif
|
||||
|
||||
const int fileNameSize = 128;
|
||||
char fname[fileNameSize];
|
||||
@ -471,91 +536,54 @@ int readConfigFile() {
|
||||
|
||||
// top command
|
||||
if (!strncmp(line, "top", strlen("top"))) {
|
||||
int t = -1;
|
||||
// cannot scan values
|
||||
if (sscanf(line, "%s %d", command, &top) != 2) {
|
||||
if (sscanf(line, "%s %d", command, &t) != 2) {
|
||||
sprintf(initErrorMessage,
|
||||
"Could not scan top commands from on-board server "
|
||||
"config file. Line:[%s].\n",
|
||||
line);
|
||||
break;
|
||||
}
|
||||
#ifndef VIRTUAL
|
||||
enum TOPINDEX ind = (top == 1 ? OW_TOP : OW_BOTTOM);
|
||||
if (!Beb_SetTop(ind)) {
|
||||
sprintf(
|
||||
initErrorMessage,
|
||||
"Could not overwrite top to %d in Beb from on-board server "
|
||||
"config file. Line:[%s].\n",
|
||||
top, line);
|
||||
if (t != 0 && t != 1) {
|
||||
sprintf(initErrorMessage,
|
||||
"Invalid top argument from on-board server "
|
||||
"config file. Line:[%s].\n",
|
||||
line);
|
||||
break;
|
||||
}
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_SetTop(ind, 1, 1)) {
|
||||
sprintf(
|
||||
initErrorMessage,
|
||||
"Could not overwrite top to %d in Feb from on-board server "
|
||||
"config file. Line:[%s].\n",
|
||||
top, line);
|
||||
sharedMemory_unlockLocalLink();
|
||||
if (setTop(t == 1 ? OW_TOP : OW_BOTTOM) == FAIL) {
|
||||
sprintf(initErrorMessage,
|
||||
"Could not set top from config file. Line:[%s].\n",
|
||||
line);
|
||||
break;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
// validate change
|
||||
int actual_top = -1, temp = -1, temp2 = -1;
|
||||
Beb_GetModuleConfiguration(&temp, &actual_top, &temp2);
|
||||
if (actual_top != top) {
|
||||
sprintf(initErrorMessage, "Could not set top to %d. Read %d\n",
|
||||
top, actual_top);
|
||||
break;
|
||||
}
|
||||
Beb_SetTopVariable(top);
|
||||
#endif
|
||||
}
|
||||
|
||||
// master command
|
||||
else if (!strncmp(line, "master", strlen("master"))) {
|
||||
int m = -1;
|
||||
// cannot scan values
|
||||
if (sscanf(line, "%s %d", command, &master) != 2) {
|
||||
if (sscanf(line, "%s %d", command, &m) != 2) {
|
||||
sprintf(initErrorMessage,
|
||||
"Could not scan master commands from on-board server "
|
||||
"config file. Line:[%s].\n",
|
||||
line);
|
||||
break;
|
||||
}
|
||||
#ifndef VIRTUAL
|
||||
enum MASTERINDEX ind = (master == 1 ? OW_MASTER : OW_SLAVE);
|
||||
if (!Beb_SetMaster(ind)) {
|
||||
if (m != 0 && m != 1) {
|
||||
sprintf(initErrorMessage,
|
||||
"Could not overwrite master to %d in Beb from on-board "
|
||||
"server "
|
||||
"Invalid master argument from on-board server "
|
||||
"config file. Line:[%s].\n",
|
||||
master, line);
|
||||
line);
|
||||
break;
|
||||
}
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_SetMaster(ind)) {
|
||||
if (setMaster(m == 1 ? OW_MASTER : OW_SLAVE) == FAIL) {
|
||||
sprintf(initErrorMessage,
|
||||
"Could not overwrite master to %d in Feb from on-board "
|
||||
"server "
|
||||
"config file. Line:[%s].\n",
|
||||
master, line);
|
||||
sharedMemory_unlockLocalLink();
|
||||
"Could not set master from config file. Line:[%s].\n",
|
||||
line);
|
||||
break;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
// validate change
|
||||
int actual_master = -1, temp = -1, temp2 = -1;
|
||||
Beb_GetModuleConfiguration(&actual_master, &temp, &temp2);
|
||||
if (actual_master != master) {
|
||||
sprintf(initErrorMessage,
|
||||
"Could not set master to %d. Read %d\n", master,
|
||||
actual_master);
|
||||
break;
|
||||
}
|
||||
sharedMemory_lockLocalLink();
|
||||
Feb_Control_SetMasterVariable(master);
|
||||
sharedMemory_unlockLocalLink();
|
||||
#endif
|
||||
}
|
||||
|
||||
// other commands
|
||||
@ -576,8 +604,10 @@ int readConfigFile() {
|
||||
LOG(logINFO, ("Successfully read config file\n"));
|
||||
}
|
||||
|
||||
#ifndef VIRTUAL
|
||||
// reset to hardware settings if not in config file (if overwritten)
|
||||
resetToHardwareSettings();
|
||||
#endif
|
||||
|
||||
return initError;
|
||||
}
|
||||
@ -589,55 +619,56 @@ void resetToHardwareSettings() {
|
||||
}
|
||||
// top not set in config file
|
||||
if (top == -1) {
|
||||
if (!Beb_SetTop(TOP_HARDWARE)) {
|
||||
LOG(logINFO, ("Resetting Top to hardware settings\n"));
|
||||
if (setTop(TOP_HARDWARE) == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Could not reset Top flag to Beb hardware settings.\n");
|
||||
"Could not reset Top flag to hardware settings.\n");
|
||||
LOG(logERROR, ("%s\n\n", initErrorMessage));
|
||||
return;
|
||||
}
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_SetTop(TOP_HARDWARE, 1, 1)) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Could not reset Top flag to Feb hardware settings.\n");
|
||||
LOG(logERROR, ("%s\n\n", initErrorMessage));
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
int temp = -1, temp2 = -1;
|
||||
Beb_GetModuleConfiguration(&temp, &top, &temp2);
|
||||
Beb_SetTopVariable(top);
|
||||
}
|
||||
// master not set in config file
|
||||
if (master == -1) {
|
||||
if (!Beb_SetMaster(TOP_HARDWARE)) {
|
||||
LOG(logINFO, ("Resetting Master to hardware settings\n"));
|
||||
if (setMaster(MASTER_HARDWARE) == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Could not reset Master flag to Beb hardware settings.\n");
|
||||
"Could not reset Master flag to hardware settings.\n");
|
||||
LOG(logERROR, ("%s\n\n", initErrorMessage));
|
||||
return;
|
||||
}
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_SetMaster(TOP_HARDWARE)) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Could not reset Master flag to Feb hardware settings.\n");
|
||||
LOG(logERROR, ("%s\n\n", initErrorMessage));
|
||||
sharedMemory_unlockLocalLink();
|
||||
return;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
int temp = -1, temp2 = -1;
|
||||
Beb_GetModuleConfiguration(&master, &temp, &temp2);
|
||||
sharedMemory_lockLocalLink();
|
||||
Feb_Control_SetMasterVariable(master);
|
||||
sharedMemory_unlockLocalLink();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int checkCommandLineConfiguration() {
|
||||
if (masterCommandLine != -1) {
|
||||
LOG(logINFO, ("Setting %s from Command Line\n",
|
||||
(masterCommandLine == 1 ? "Master" : "Slave")));
|
||||
if (setMaster(masterCommandLine == 1 ? OW_MASTER : OW_SLAVE) == FAIL) {
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage, "Could not set %s from command line.\n",
|
||||
(masterCommandLine == 1 ? "Master" : "Slave"));
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (topCommandLine != -1) {
|
||||
LOG(logINFO, ("Setting %s from Command Line\n",
|
||||
(topCommandLine == 1 ? "Top" : "Bottom")));
|
||||
if (setTop(topCommandLine == 1 ? OW_TOP : OW_BOTTOM) == FAIL) {
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage, "Could not set %s from command line.\n",
|
||||
(topCommandLine == 1 ? "Top" : "Bottom"));
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
|
||||
void allocateDetectorStructureMemory() {
|
||||
@ -671,15 +702,29 @@ void allocateDetectorStructureMemory() {
|
||||
}
|
||||
|
||||
void setupDetector() {
|
||||
|
||||
allocateDetectorStructureMemory();
|
||||
|
||||
// force top or master if in config file
|
||||
if (readConfigFile() == FAIL)
|
||||
return;
|
||||
// force top or master if in command line
|
||||
if (checkCommandLineConfiguration() == FAIL)
|
||||
return;
|
||||
|
||||
LOG(logINFOBLUE,
|
||||
("Module: %s %s %s\n", (top ? "TOP" : "BOTTOM"),
|
||||
(master ? "MASTER" : "SLAVE"), (normal ? "NORMAL" : "SPECIAL")));
|
||||
|
||||
if (updateModuleId() == FAIL)
|
||||
return;
|
||||
|
||||
LOG(logINFOBLUE, ("Setting Default Parameters\n"));
|
||||
resetToDefaultDacs(0);
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStatus(IDLE);
|
||||
setupUDPCommParameters();
|
||||
#endif
|
||||
|
||||
LOG(logINFOBLUE, ("Setting Default Parameters\n"));
|
||||
// setting default measurement parameters
|
||||
setNumFrames(DEFAULT_NUM_FRAMES);
|
||||
setExpTime(DEFAULT_EXPTIME);
|
||||
@ -719,14 +764,6 @@ void setupDetector() {
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
#endif
|
||||
// force top or master if in config file
|
||||
if (readConfigFile() == FAIL) {
|
||||
return;
|
||||
}
|
||||
LOG(logINFOBLUE,
|
||||
("Module: %s %s %s\n", (top ? "TOP" : "BOTTOM"),
|
||||
(master ? "MASTER" : "SLAVE"), (normal ? "NORMAL" : "SPECIAL")));
|
||||
|
||||
if (setNumberofDestinations(numUdpDestinations) == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage, "Could not set number of udp destinations\n");
|
||||
@ -821,29 +858,38 @@ int readRegister(uint32_t offset, uint32_t *retval) {
|
||||
/* set parameters - dr, roi */
|
||||
|
||||
int setDynamicRange(int dr) {
|
||||
// setting dr
|
||||
if (dr > 0) {
|
||||
LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr));
|
||||
#ifndef VIRTUAL
|
||||
sharedMemory_lockLocalLink();
|
||||
if (Feb_Control_SetDynamicRange(dr)) {
|
||||
if (!Beb_SetUpTransferParameters(dr)) {
|
||||
LOG(logERROR, ("Could not set bit mode in the back end\n"));
|
||||
sharedMemory_unlockLocalLink();
|
||||
return eiger_dynamicrange;
|
||||
}
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
#endif
|
||||
eiger_dynamicrange = dr;
|
||||
if (dr <= 0) {
|
||||
return FAIL;
|
||||
}
|
||||
// getting dr
|
||||
#ifndef VIRTUAL
|
||||
#ifdef VIRTUAL
|
||||
LOG(logINFO, ("Setting dynamic range: %d\n", dr));
|
||||
#else
|
||||
sharedMemory_lockLocalLink();
|
||||
eiger_dynamicrange = Feb_Control_GetDynamicRange();
|
||||
if (Feb_Control_SetDynamicRange(dr)) {
|
||||
if (!Beb_SetUpTransferParameters(dr)) {
|
||||
LOG(logERROR, ("Could not set bit mode in the back end\n"));
|
||||
sharedMemory_unlockLocalLink();
|
||||
return eiger_dynamicrange;
|
||||
}
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
#endif
|
||||
return eiger_dynamicrange;
|
||||
eiger_dynamicrange = dr;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDynamicRange(int *retval) {
|
||||
#ifdef VIRTUAL
|
||||
*retval = eiger_dynamicrange;
|
||||
#else
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_GetDynamicRange(retval)) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* parameters - readout */
|
||||
@ -1158,6 +1204,7 @@ int setModule(sls_detector_module myMod, char *mess) {
|
||||
|
||||
// if quad, set M8 and PROGRAM manually
|
||||
if (!Feb_Control_SetChipSignalsToTrimQuad(1)) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -1170,6 +1217,7 @@ int setModule(sls_detector_module myMod, char *mess) {
|
||||
|
||||
// if quad, reset M8 and PROGRAM manually
|
||||
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -1179,6 +1227,7 @@ int setModule(sls_detector_module myMod, char *mess) {
|
||||
|
||||
// if quad, reset M8 and PROGRAM manually
|
||||
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -1450,7 +1499,120 @@ int setHighVoltage(int val) {
|
||||
|
||||
/* parameters - timing, extsig */
|
||||
|
||||
int isMaster() { return master; }
|
||||
int setMaster(enum MASTERINDEX m) {
|
||||
char *master_names[] = {MASTER_NAMES};
|
||||
LOG(logINFOBLUE, ("Setting up Master flag as %s\n", master_names[m]));
|
||||
#ifdef VIRTUAL
|
||||
switch (m) {
|
||||
case OW_MASTER:
|
||||
master = 1;
|
||||
break;
|
||||
case OW_SLAVE:
|
||||
master = 0;
|
||||
break;
|
||||
default:
|
||||
// hardware settings (do nothing)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// need to set it only once via the control server
|
||||
if (isControlServer) {
|
||||
if (!Beb_SetMaster(m)) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_SetMaster(m)) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
}
|
||||
|
||||
// get and update master variable (cannot get from m, could be hardware)
|
||||
if (isMaster(&master) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
// verify for master and slave (not hardware)
|
||||
if ((m == OW_MASTER && master == 0) || (m == OW_SLAVE && master == 1)) {
|
||||
LOG(logERROR,
|
||||
("could not set master/slave. Master value retrieved %d\n",
|
||||
master));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// feb variable and hv comms (9m)
|
||||
sharedMemory_lockLocalLink();
|
||||
if (Feb_Control_SetMasterEffects(master, isControlServer) == FAIL) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
int isMaster(int *retval) {
|
||||
int m = -1, t = -1, n = -1;
|
||||
if (getModuleConfiguration(&m, &t, &n) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
*retval = m;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setTop(enum TOPINDEX t) {
|
||||
char *top_names[] = {TOP_NAMES};
|
||||
LOG(logINFOBLUE, ("Setting up Top flag as %s\n", top_names[t]));
|
||||
#ifdef VIRTUAL
|
||||
switch (t) {
|
||||
case OW_TOP:
|
||||
top = 1;
|
||||
break;
|
||||
case OW_BOTTOM:
|
||||
top = 0;
|
||||
break;
|
||||
default:
|
||||
// hardware settings (do nothing)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (!Beb_SetTop(t)) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
sharedMemory_lockLocalLink();
|
||||
if (!Feb_Control_SetTop(t, 1, 1)) {
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
sharedMemory_unlockLocalLink();
|
||||
|
||||
// get and update top variable(cannot get from t, could be hardware)
|
||||
if (isTop(&top) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
// verify for master and slave (not hardware)
|
||||
if ((t == OW_TOP && top == 0) || (t == OW_BOTTOM && top == 1)) {
|
||||
LOG(logERROR,
|
||||
("could not set top/bottom. Top value retrieved %d\n", top));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
Beb_SetTopVariable(top);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
int isTop(int *retval) {
|
||||
int m = -1, t = -1, n = -1;
|
||||
if (getModuleConfiguration(&m, &t, &n) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
*retval = t;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setTiming(enum timingMode arg) {
|
||||
int ret = 0;
|
||||
@ -1923,7 +2085,8 @@ int setRateCorrection(
|
||||
else if (custom_tau_in_nsec == -1)
|
||||
custom_tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec();
|
||||
|
||||
int dr = Feb_Control_GetDynamicRange();
|
||||
int dr = eiger_dynamicrange;
|
||||
|
||||
// get period = subexptime if 32bit , else period = exptime if 16 bit
|
||||
int64_t actual_period =
|
||||
Feb_Control_GetSubFrameExposureTime(); // already in nsec
|
||||
@ -2105,6 +2268,9 @@ int setDataStream(enum portPosition port, int enable) {
|
||||
LOG(logERROR, ("Invalid setDataStream enable argument: %d\n", enable));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO,
|
||||
("%s 10GbE %s datastream\n", (enable ? "Enabling" : "Disabling"),
|
||||
(port == LEFT ? "left" : "right")));
|
||||
#ifdef VIRTUAL
|
||||
if (port == LEFT) {
|
||||
eiger_virtual_left_datastream = enable;
|
||||
@ -2282,15 +2448,17 @@ void *start_timer(void *arg) {
|
||||
}
|
||||
|
||||
int skipData = 0;
|
||||
int tgEnable = send_to_ten_gig;
|
||||
if (!eiger_virtual_activate ||
|
||||
(!eiger_virtual_left_datastream && !eiger_virtual_right_datastream)) {
|
||||
(tgEnable &&
|
||||
(!eiger_virtual_left_datastream && !eiger_virtual_right_datastream))) {
|
||||
skipData = 1;
|
||||
LOG(logWARNING, ("Not sending Left and Right datastream\n"));
|
||||
}
|
||||
if (!eiger_virtual_left_datastream) {
|
||||
if (tgEnable && !eiger_virtual_left_datastream) {
|
||||
LOG(logWARNING, ("Not sending Left datastream\n"));
|
||||
}
|
||||
if (!eiger_virtual_right_datastream) {
|
||||
if (tgEnable && !eiger_virtual_right_datastream) {
|
||||
LOG(logWARNING, ("Not sending Right datastream\n"));
|
||||
}
|
||||
|
||||
@ -2300,15 +2468,14 @@ void *start_timer(void *arg) {
|
||||
|
||||
int dr = eiger_dynamicrange;
|
||||
double bytesPerPixel = (double)dr / 8.00;
|
||||
int tgEnable = send_to_ten_gig;
|
||||
int datasize = (tgEnable ? 4096 : 1024);
|
||||
int packetsize = datasize + sizeof(sls_detector_header);
|
||||
int maxPacketsPerFrame = (tgEnable ? 4 : 16) * dr;
|
||||
int npixelsx = 256 * 2 * bytesPerPixel;
|
||||
int databytes = 256 * 256 * 2 * bytesPerPixel;
|
||||
int row = eiger_virtual_detPos[0];
|
||||
int colLeft = top ? eiger_virtual_detPos[1] : eiger_virtual_detPos[1] + 1;
|
||||
int colRight = top ? eiger_virtual_detPos[1] + 1 : eiger_virtual_detPos[1];
|
||||
int row = eiger_virtual_detPos[Y];
|
||||
int colLeft = top ? eiger_virtual_detPos[X] : eiger_virtual_detPos[X] + 1;
|
||||
int colRight = top ? eiger_virtual_detPos[X] + 1 : eiger_virtual_detPos[X];
|
||||
|
||||
int readNRows = getReadNRows();
|
||||
if (readNRows == -1) {
|
||||
@ -2318,7 +2485,7 @@ void *start_timer(void *arg) {
|
||||
const int maxRows = MAX_ROWS_PER_READOUT;
|
||||
const int packetsPerFrame = (maxPacketsPerFrame * readNRows) / maxRows;
|
||||
|
||||
LOG(logDEBUG1,
|
||||
LOG(logDEBUG,
|
||||
(" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n "
|
||||
"packetsize:%d\n maxnumpackes:%d\n npixelsx:%d\n databytes:%d\n",
|
||||
dr, bytesPerPixel, tgEnable, datasize, packetsize, maxPacketsPerFrame,
|
||||
@ -2335,11 +2502,13 @@ void *start_timer(void *arg) {
|
||||
npixels /= 2;
|
||||
}
|
||||
LOG(logDEBUG1,
|
||||
("pixels:%d pixelsperpacket:%d\n", npixels, pixelsPerPacket));
|
||||
("npixels:%d pixelsperpacket:%d\n", npixels, pixelsPerPacket));
|
||||
uint8_t *src = (uint8_t *)imageData;
|
||||
for (int i = 0; i < npixels; ++i) {
|
||||
if (i > 0 && i % pixelsPerPacket == 0) {
|
||||
++pixelVal;
|
||||
}
|
||||
|
||||
switch (dr) {
|
||||
case 4:
|
||||
*((uint8_t *)(imageData + i)) =
|
||||
@ -2354,9 +2523,45 @@ void *start_timer(void *arg) {
|
||||
*((uint8_t *)(imageData + i)) =
|
||||
eiger_virtual_test_mode ? 0xFE : (uint8_t)pixelVal;
|
||||
break;
|
||||
case 12:
|
||||
if (eiger_virtual_test_mode) {
|
||||
// first 12 bit pixel
|
||||
// first 8 byte
|
||||
*src++ = 0xFE;
|
||||
// second 12bit pixel
|
||||
++i;
|
||||
// second 8 byte
|
||||
*src++ = 0xEF;
|
||||
// third byte
|
||||
*src++ = 0xFF;
|
||||
} else {
|
||||
// first 12 bit pixel
|
||||
// first 8 byte
|
||||
*src++ = (uint8_t)(i & 0xFF);
|
||||
// second 8 byte (first nibble)
|
||||
*src = (uint8_t)((i++ >> 8u) & 0xF);
|
||||
// second 12bit pixel
|
||||
// second 8 byte (second nibble)
|
||||
*src++ |= ((uint8_t)(i & 0xF) << 4u);
|
||||
// third byte
|
||||
*src++ = (uint8_t)((i >> 4u) & 0xFF);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
// to debug multi module geometry (row, column) in virtual servers (all pixels
|
||||
// in a module set to particular value)
|
||||
#ifdef TEST_MOD_GEOMETRY
|
||||
if ((i % 1024) < 512) {
|
||||
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
|
||||
top ? (portno % 1900) : ((portno % 1900) + 1);
|
||||
} else {
|
||||
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
|
||||
top ? ((portno % 1900) + 1) : (portno % 1900);
|
||||
}
|
||||
#else
|
||||
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
|
||||
eiger_virtual_test_mode ? 0xFFE : (uint16_t)pixelVal;
|
||||
#endif
|
||||
break;
|
||||
case 32:
|
||||
*((uint32_t *)(imageData + i * sizeof(uint32_t))) =
|
||||
@ -2430,9 +2635,27 @@ void *start_timer(void *arg) {
|
||||
// fill data
|
||||
int dstOffset = sizeof(sls_detector_header);
|
||||
int dstOffset2 = sizeof(sls_detector_header);
|
||||
{
|
||||
for (int psize = 0; psize < datasize; psize += npixelsx) {
|
||||
if (dr == 12) {
|
||||
// multiple of 768,1024,4096
|
||||
int copysize = 256;
|
||||
for (int psize = 0; psize < datasize; psize += copysize) {
|
||||
memcpy(packetData + dstOffset, imageData + srcOffset,
|
||||
copysize);
|
||||
memcpy(packetData2 + dstOffset2, imageData + srcOffset2,
|
||||
copysize);
|
||||
srcOffset += copysize;
|
||||
srcOffset2 += copysize;
|
||||
dstOffset += copysize;
|
||||
dstOffset2 += copysize;
|
||||
|
||||
// reached 1 row (quarter module)
|
||||
if ((srcOffset % npixelsx) == 0) {
|
||||
srcOffset += npixelsx;
|
||||
srcOffset2 += npixelsx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int psize = 0; psize < datasize; psize += npixelsx) {
|
||||
if (dr == 32 && tgEnable == 0) {
|
||||
memcpy(packetData + dstOffset,
|
||||
imageData + srcOffset, npixelsx / 2);
|
||||
@ -2462,14 +2685,16 @@ void *start_timer(void *arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eiger_virtual_left_datastream && i >= startval &&
|
||||
i <= endval) {
|
||||
if ((!tgEnable ||
|
||||
(tgEnable && eiger_virtual_left_datastream)) &&
|
||||
i >= startval && i <= endval) {
|
||||
usleep(eiger_virtual_transmission_delay_left);
|
||||
sendUDPPacket(iRxEntry, 0, packetData, packetsize);
|
||||
LOG(logDEBUG1, ("Sent left packet: %d\n", i));
|
||||
}
|
||||
if (eiger_virtual_right_datastream && i >= startval &&
|
||||
i <= endval) {
|
||||
if ((!tgEnable ||
|
||||
(tgEnable && eiger_virtual_right_datastream)) &&
|
||||
i >= startval && i <= endval) {
|
||||
usleep(eiger_virtual_transmission_delay_right);
|
||||
sendUDPPacket(iRxEntry, 1, packetData2, packetsize);
|
||||
LOG(logDEBUG1, ("Sent right packet: %d\n", i));
|
||||
@ -2730,9 +2955,9 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
|
||||
|
||||
int calculateDataBytes() {
|
||||
if (send_to_ten_gig)
|
||||
return setDynamicRange(-1) * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE;
|
||||
return eiger_dynamicrange * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE;
|
||||
else
|
||||
return setDynamicRange(-1) * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE;
|
||||
return eiger_dynamicrange * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
int getTotalNumberOfChannels() {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#define LINKED_SERVER_NAME "eigerDetectorServer"
|
||||
|
||||
#define REQUIRED_FIRMWARE_VERSION (29)
|
||||
#define REQUIRED_FIRMWARE_VERSION (30)
|
||||
// virtual ones renamed for consistency
|
||||
// real ones keep previous name for compatibility (already in production)
|
||||
#ifdef VIRTUAL
|
||||
|
Binary file not shown.
@ -28,12 +28,16 @@ extern int updateFlag;
|
||||
extern int checkModuleFlag;
|
||||
extern udpStruct udpDetails[MAX_UDP_DESTINATION];
|
||||
extern const enum detectorType myDetectorType;
|
||||
extern int ignoreConfigFileFlag;
|
||||
|
||||
// Global variable from communication_funcs.c
|
||||
extern int isControlServer;
|
||||
extern void getMacAddressinString(char *cmac, int size, uint64_t mac);
|
||||
extern void getIpAddressinString(char *cip, uint32_t ip);
|
||||
|
||||
// Variables that will be exported
|
||||
int masterCommandLine = -1;
|
||||
|
||||
int initError = OK;
|
||||
int initCheckDone = 0;
|
||||
char initErrorMessage[MAX_STR_LENGTH];
|
||||
@ -69,6 +73,7 @@ int64_t burstPeriodReg = 0;
|
||||
int filterResistor = 0;
|
||||
int cdsGain = 0;
|
||||
int detPos[2] = {};
|
||||
int master = 1;
|
||||
|
||||
int isInitCheckDone() { return initCheckDone; }
|
||||
|
||||
@ -295,6 +300,18 @@ void setModuleId(int modid) {
|
||||
bus_r(MOD_ID_REG) | ((modid << MOD_ID_OFST) & MOD_ID_MSK));
|
||||
}
|
||||
|
||||
int updateModuleId() {
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
if (initError == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
virtual_moduleid = modid;
|
||||
#endif
|
||||
setModuleId(modid);
|
||||
return OK;
|
||||
}
|
||||
|
||||
u_int64_t getDetectorMAC() {
|
||||
#ifdef VIRTUAL
|
||||
return 0;
|
||||
@ -358,16 +375,27 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
if (mapCSP0() == FAIL) {
|
||||
LOG(logERROR,
|
||||
("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!updateFlag && initError == OK) {
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
if (mapCSP0() == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
sharedMemory_setStop(0);
|
||||
// not reading config file (nothing of interest to stop server)
|
||||
if (checkCommandLineConfiguration() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
@ -480,15 +508,13 @@ void setupDetector() {
|
||||
return;
|
||||
}
|
||||
|
||||
// set module id in register
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
#ifdef VIRTUAL
|
||||
virtual_moduleid = modid;
|
||||
#endif
|
||||
if (initError == FAIL) {
|
||||
// master for virtual
|
||||
if (checkCommandLineConfiguration() == FAIL)
|
||||
return;
|
||||
|
||||
if (updateModuleId() == FAIL) {
|
||||
return;
|
||||
}
|
||||
setModuleId(modid);
|
||||
|
||||
setBurstMode(DEFAULT_BURST_MODE);
|
||||
setFilterResistor(DEFAULT_FILTER_RESISTOR);
|
||||
@ -600,6 +626,11 @@ int readConfigFile() {
|
||||
return initError;
|
||||
}
|
||||
|
||||
if (ignoreConfigFileFlag) {
|
||||
LOG(logWARNING, ("Ignoring Config file\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
// require a sleep before and after the rst dac signal
|
||||
usleep(INITIAL_STARTUP_WAIT);
|
||||
|
||||
@ -924,6 +955,21 @@ int readConfigFile() {
|
||||
return initError;
|
||||
}
|
||||
|
||||
int checkCommandLineConfiguration() {
|
||||
if (masterCommandLine != -1) {
|
||||
#ifdef VIRTUAL
|
||||
master = masterCommandLine;
|
||||
#else
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Cannot set Master from command line for this detector. "
|
||||
"Should have been caught before!\n");
|
||||
return FAIL;
|
||||
#endif
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* firmware functions (resets) */
|
||||
|
||||
void cleanFifos() {
|
||||
@ -952,7 +998,16 @@ void resetPeripheral() {
|
||||
|
||||
/* set parameters - dr, roi */
|
||||
|
||||
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
|
||||
int setDynamicRange(int dr) {
|
||||
if (dr == 16)
|
||||
return OK;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int getDynamicRange(int *retval) {
|
||||
*retval = DYNAMIC_RANGE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* parameters - timer */
|
||||
void setNumFrames(int64_t val) {
|
||||
@ -1442,6 +1497,11 @@ int setHighVoltage(int val) {
|
||||
|
||||
/* parameters - timing */
|
||||
|
||||
int isMaster(int *retval) {
|
||||
*retval = master;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void updatingRegisters() {
|
||||
LOG(logINFO, ("\tUpdating registers\n"));
|
||||
// burst
|
||||
@ -1857,7 +1917,7 @@ int setDetectorPosition(int pos[]) {
|
||||
int ret = OK;
|
||||
|
||||
// row
|
||||
value = detPos[X];
|
||||
value = detPos[Y];
|
||||
bus_w(addr, (bus_r(addr) & ~COORD_ROW_MSK) |
|
||||
((value << COORD_ROW_OFST) & COORD_ROW_MSK));
|
||||
valueRead = ((bus_r(addr) & COORD_ROW_MSK) >> COORD_ROW_OFST);
|
||||
@ -1868,7 +1928,7 @@ int setDetectorPosition(int pos[]) {
|
||||
}
|
||||
|
||||
// col
|
||||
value = detPos[Y];
|
||||
value = detPos[X];
|
||||
bus_w(addr, (bus_r(addr) & ~COORD_COL_MSK) |
|
||||
((value << COORD_COL_OFST) & COORD_COL_MSK));
|
||||
valueRead = ((bus_r(addr) & COORD_COL_MSK) >> COORD_COL_OFST);
|
||||
@ -1879,7 +1939,8 @@ int setDetectorPosition(int pos[]) {
|
||||
}
|
||||
|
||||
if (ret == OK) {
|
||||
LOG(logINFO, ("\tPosition set to [%d, %d]\n", detPos[X], detPos[Y]));
|
||||
LOG(logINFO,
|
||||
("\tPosition set to [%d, %d] #(col, row)\n", detPos[X], detPos[Y]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1921,9 +1982,17 @@ int checkDetectorType() {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((abs(type - TYPE_GOTTHARD2_MODULE_VAL) > TYPE_TOLERANCE) &&
|
||||
(abs(type - TYPE_GOTTHARD2_25UM_MASTER_MODULE_VAL) > TYPE_TOLERANCE) &&
|
||||
(abs(type - TYPE_GOTTHARD2_25UM_SLAVE_MODULE_VAL) > TYPE_TOLERANCE)) {
|
||||
if (abs(type - TYPE_GOTTHARD2_25UM_MASTER_MODULE_VAL) <= TYPE_TOLERANCE) {
|
||||
LOG(logINFOBLUE, ("MASTER 25um Module\n"));
|
||||
master = 1;
|
||||
} else if (abs(type - TYPE_GOTTHARD2_25UM_SLAVE_MODULE_VAL) <=
|
||||
TYPE_TOLERANCE) {
|
||||
master = 0;
|
||||
LOG(logINFOBLUE, ("SLAVE 25um Module\n"));
|
||||
} else if (abs(type - TYPE_GOTTHARD2_MODULE_VAL) <= TYPE_TOLERANCE) {
|
||||
master = -1;
|
||||
LOG(logINFOBLUE, ("50um Module\n"));
|
||||
} else {
|
||||
LOG(logERROR,
|
||||
("Wrong Module attached! Expected %d, %d or %d for Gotthard2, got "
|
||||
"%d\n",
|
||||
@ -3027,8 +3096,8 @@ void *start_timer(void *arg) {
|
||||
header->frameNumber = virtual_currentFrameNumber;
|
||||
header->packetNumber = 0;
|
||||
header->modId = virtual_moduleid;
|
||||
header->row = detPos[X];
|
||||
header->column = detPos[Y];
|
||||
header->row = detPos[Y];
|
||||
header->column = detPos[X];
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header), imageData,
|
||||
datasize);
|
||||
|
Binary file not shown.
@ -25,9 +25,11 @@ extern int debugflag;
|
||||
extern int updateFlag;
|
||||
extern udpStruct udpDetails[MAX_UDP_DESTINATION];
|
||||
extern const enum detectorType myDetectorType;
|
||||
extern int ignoreConfigFileFlag;
|
||||
|
||||
// Variables that will be exported
|
||||
int phaseShift = DEFAULT_PHASE_SHIFT;
|
||||
int masterCommandLine = -1;
|
||||
|
||||
// Global variable from communication_funcs.c
|
||||
extern int isControlServer;
|
||||
@ -359,16 +361,28 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
if (mapCSP0() == FAIL) {
|
||||
LOG(logERROR,
|
||||
("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!updateFlag && initError == OK) {
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
if (mapCSP0() == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
sharedMemory_setStop(0);
|
||||
#endif
|
||||
// to get master from file
|
||||
readConfigFile();
|
||||
// to get master from file
|
||||
if (readConfigFile() == FAIL ||
|
||||
checkCommandLineConfiguration() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
@ -421,6 +435,13 @@ void setupDetector() {
|
||||
setROI(rois); // set adcsyncreg, daqreg, chipofinterestreg, cleanfifos,
|
||||
setGbitReadout();
|
||||
|
||||
// no config file or not first time server
|
||||
if (readConfigFile() == FAIL)
|
||||
return;
|
||||
|
||||
if (checkCommandLineConfiguration() == FAIL)
|
||||
return;
|
||||
|
||||
// master, slave (25um)
|
||||
setMasterSlaveConfiguration();
|
||||
|
||||
@ -624,6 +645,16 @@ void setGbitReadout() {
|
||||
}
|
||||
|
||||
int readConfigFile() {
|
||||
|
||||
if (initError == FAIL) {
|
||||
return initError;
|
||||
}
|
||||
|
||||
if (ignoreConfigFileFlag) {
|
||||
LOG(logWARNING, ("Ignoring Config file\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
const int fileNameSize = 128;
|
||||
char fname[fileNameSize];
|
||||
if (getAbsPath(fname, fileNameSize, CONFIG_FILE) == FAIL) {
|
||||
@ -647,7 +678,6 @@ int readConfigFile() {
|
||||
memset(key, 0, keySize);
|
||||
char value[keySize];
|
||||
memset(value, 0, keySize);
|
||||
int scan = OK;
|
||||
|
||||
// keep reading a line
|
||||
while (fgets(line, lineSize, fd)) {
|
||||
@ -667,19 +697,22 @@ int readConfigFile() {
|
||||
master = 0;
|
||||
LOG(logINFOBLUE, ("\tSlave or No Master\n"));
|
||||
} else {
|
||||
LOG(logERROR,
|
||||
("\tCould not scan masterflags %s value from config file\n",
|
||||
value));
|
||||
scan = FAIL;
|
||||
break;
|
||||
initError = FAIL;
|
||||
sprintf(
|
||||
initErrorMessage,
|
||||
"Could not scan masterflags %s value from config file\n",
|
||||
value);
|
||||
LOG(logERROR, (initErrorMessage))
|
||||
fclose(fd);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// not first server since detector power on
|
||||
if (!detectorFirstServer) {
|
||||
LOG(logINFOBLUE, ("\tServer has been started up before. "
|
||||
"Ignoring rest of config file\n"));
|
||||
LOG(logWARNING, ("\tServer has been started up before. "
|
||||
"Ignoring rest of config file\n"));
|
||||
fclose(fd);
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -688,11 +721,14 @@ int readConfigFile() {
|
||||
// convert value to int
|
||||
int ival = 0;
|
||||
if (sscanf(value, "%d", &ival) <= 0) {
|
||||
LOG(logERROR, ("\tCould not scan parameter %s value %s from "
|
||||
"config file\n",
|
||||
key, value));
|
||||
scan = FAIL;
|
||||
break;
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage,
|
||||
"Could not scan parameter %s value %s from "
|
||||
"config file\n",
|
||||
key, value);
|
||||
LOG(logERROR, (initErrorMessage))
|
||||
fclose(fd);
|
||||
return FAIL;
|
||||
}
|
||||
// set value
|
||||
if (!strcasecmp(key, "masterdefaultdelay"))
|
||||
@ -710,16 +746,16 @@ int readConfigFile() {
|
||||
else if (!strcasecmp(key, "startacqdelay"))
|
||||
startacqdelay = ival;
|
||||
else {
|
||||
LOG(logERROR,
|
||||
("\tCould not scan parameter %s from config file\n", key));
|
||||
scan = FAIL;
|
||||
break;
|
||||
initError = FAIL;
|
||||
sprintf(initErrorMessage,
|
||||
"Could not scan parameter %s from config file\n", key);
|
||||
LOG(logERROR, (initErrorMessage))
|
||||
fclose(fd);
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
if (scan == FAIL)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
LOG(logINFOBLUE,
|
||||
("\tmasterdefaultdelay:%d\n"
|
||||
@ -734,13 +770,28 @@ int readConfigFile() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int checkCommandLineConfiguration() {
|
||||
if (masterCommandLine != -1) {
|
||||
#ifdef VIRTUAL
|
||||
master = masterCommandLine;
|
||||
#else
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Cannot set Master from command line for this detector. "
|
||||
"Should have been caught before!\n");
|
||||
return FAIL;
|
||||
#endif
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setMasterSlaveConfiguration() {
|
||||
LOG(logINFO, ("Reading Master Slave Configuration\n"));
|
||||
|
||||
// no config file or not first time server
|
||||
if (readConfigFile() == FAIL)
|
||||
// not the first time its being read
|
||||
if (!detectorFirstServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(logINFO, ("Reading Master Slave Configuration\n"));
|
||||
// master configuration
|
||||
if (master) {
|
||||
// master default delay set, so reset delay
|
||||
@ -788,7 +839,16 @@ void setMasterSlaveConfiguration() {
|
||||
|
||||
/* set parameters - dr, roi */
|
||||
|
||||
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
|
||||
int setDynamicRange(int dr) {
|
||||
if (dr == 16)
|
||||
return OK;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int getDynamicRange(int *retval) {
|
||||
*retval = DYNAMIC_RANGE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setROI(ROI arg) {
|
||||
|
||||
@ -1238,7 +1298,10 @@ int setHighVoltage(int val) {
|
||||
|
||||
/* parameters - timing, extsig */
|
||||
|
||||
int isMaster() { return master; }
|
||||
int isMaster(int *retval) {
|
||||
*retval = master;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setTiming(enum timingMode arg) {
|
||||
u_int32_t addr = EXT_SIGNAL_REG;
|
||||
|
Binary file not shown.
@ -21,13 +21,14 @@
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
extern int portno;
|
||||
// Global variable from slsDetectorServer_funcs
|
||||
extern int debugflag;
|
||||
extern int updateFlag;
|
||||
extern udpStruct udpDetails[MAX_UDP_DESTINATION];
|
||||
extern int numUdpDestinations;
|
||||
extern const enum detectorType myDetectorType;
|
||||
extern int ignoreConfigFileFlag;
|
||||
|
||||
// Global variable from communication_funcs.c
|
||||
extern int isControlServer;
|
||||
@ -392,19 +393,29 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
if (mapCSP0() == FAIL) {
|
||||
LOG(logERROR,
|
||||
("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!updateFlag && initError == OK) {
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
if (mapCSP0() == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
if (readConfigFile() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
// temp threshold and reset event (read by stop server)
|
||||
setThresholdTemperature(DEFAULT_TMP_THRSHLD);
|
||||
setTemperatureEvent(0);
|
||||
sharedMemory_setStop(0);
|
||||
// temp threshold and reset event (read by stop server)
|
||||
setThresholdTemperature(DEFAULT_TMP_THRSHLD);
|
||||
setTemperatureEvent(0);
|
||||
#endif
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
@ -643,6 +654,11 @@ int readConfigFile() {
|
||||
return initError;
|
||||
}
|
||||
|
||||
if (ignoreConfigFileFlag) {
|
||||
LOG(logWARNING, ("Ignoring Config file\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
const int fileNameSize = 128;
|
||||
char fname[fileNameSize];
|
||||
if (getAbsPath(fname, fileNameSize, CONFIG_FILE) == FAIL) {
|
||||
@ -796,7 +812,16 @@ void resetPeripheral() {
|
||||
|
||||
/* set parameters - dr, roi */
|
||||
|
||||
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
|
||||
int setDynamicRange(int dr) {
|
||||
if (dr == 16)
|
||||
return OK;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int getDynamicRange(int *retval) {
|
||||
*retval = DYNAMIC_RANGE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setADCInvertRegister(uint32_t val) {
|
||||
LOG(logINFO, ("Setting ADC Port Invert Reg to 0x%x\n", val));
|
||||
@ -1596,6 +1621,7 @@ int configureMAC() {
|
||||
|
||||
int setDetectorPosition(int pos[]) {
|
||||
int ret = OK;
|
||||
// row, col
|
||||
uint32_t innerPos[2] = {pos[X], pos[Y]};
|
||||
uint32_t outerPos[2] = {pos[X], pos[Y]};
|
||||
int selInterface = getPrimaryInterface();
|
||||
@ -1605,15 +1631,16 @@ int setDetectorPosition(int pos[]) {
|
||||
("Setting detector position: 1 Interface %s \n(%d, %d)\n",
|
||||
(selInterface ? "Inner" : "Outer"), innerPos[X], innerPos[Y]));
|
||||
} else {
|
||||
++outerPos[X];
|
||||
// top has row incremented by 1
|
||||
++innerPos[Y];
|
||||
LOG(logDEBUG, ("Setting detector position: 2 Interfaces \n"
|
||||
" inner top(%d, %d), outer bottom(%d, %d)\n",
|
||||
innerPos[X], innerPos[Y], outerPos[X], outerPos[Y]));
|
||||
}
|
||||
detPos[0] = innerPos[0];
|
||||
detPos[1] = innerPos[1];
|
||||
detPos[2] = outerPos[0];
|
||||
detPos[3] = outerPos[1];
|
||||
detPos[0] = innerPos[X];
|
||||
detPos[1] = innerPos[Y];
|
||||
detPos[2] = outerPos[X];
|
||||
detPos[3] = outerPos[Y];
|
||||
|
||||
// row
|
||||
// outer
|
||||
@ -1651,8 +1678,8 @@ int setDetectorPosition(int pos[]) {
|
||||
|
||||
if (ret == OK) {
|
||||
if (getNumberofUDPInterfaces() == 1) {
|
||||
LOG(logINFOBLUE,
|
||||
("Position set to [%d, %d]\n", innerPos[X], innerPos[Y]));
|
||||
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",
|
||||
innerPos[X], innerPos[Y]));
|
||||
} else {
|
||||
LOG(logINFOBLUE, (" Inner (top) position set to [%d, %d]\n",
|
||||
innerPos[X], innerPos[Y]));
|
||||
@ -1675,7 +1702,7 @@ int setReadNRows(int value) {
|
||||
}
|
||||
if (isHardwareVersion2()) {
|
||||
LOG(logERROR, ("Could not set number of rows. Only available for "
|
||||
"Hardware Board version 2.0.\n"));
|
||||
"Hardware Board version 2.0.\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -2175,7 +2202,7 @@ int getFlipRows() {
|
||||
void setFlipRows(int arg) {
|
||||
if (isHardwareVersion2()) {
|
||||
LOG(logERROR, ("Could not set flip rows. Only available for "
|
||||
"Hardware Board version 2.0.\n"));
|
||||
"Hardware Board version 2.0.\n"));
|
||||
return;
|
||||
}
|
||||
if (arg >= 0) {
|
||||
@ -2506,8 +2533,16 @@ void *start_timer(void *arg) {
|
||||
if (i > 0 && i % pixelsPerPacket == 0) {
|
||||
++pixelVal;
|
||||
}
|
||||
// to debug multi module geometry (row, column) in virtual servers (all pixels
|
||||
// in a module set to particular value)
|
||||
#ifdef TEST_MOD_GEOMETRY
|
||||
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
|
||||
portno % 1900 + (i >= npixels / 2 ? 1 : 0);
|
||||
#else
|
||||
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
|
||||
virtual_image_test_mode ? 0x0FFE : (uint16_t)pixelVal;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -2532,6 +2567,10 @@ void *start_timer(void *arg) {
|
||||
|
||||
int srcOffset = 0;
|
||||
int srcOffset2 = DATA_BYTES / 2;
|
||||
int row0 = (numInterfaces == 1 ? detPos[1] : detPos[3]);
|
||||
int col0 = (numInterfaces == 1 ? detPos[0] : detPos[2]);
|
||||
int row1 = detPos[1];
|
||||
int col1 = detPos[0];
|
||||
// loop packet (128 packets)
|
||||
for (int i = 0; i != maxPacketsPerFrame; ++i) {
|
||||
|
||||
@ -2551,8 +2590,8 @@ void *start_timer(void *arg) {
|
||||
header->frameNumber = frameNr + iframes;
|
||||
header->packetNumber = pnum;
|
||||
header->modId = 0;
|
||||
header->row = detPos[0];
|
||||
header->column = detPos[1];
|
||||
header->row = row0;
|
||||
header->column = col0;
|
||||
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header),
|
||||
@ -2578,8 +2617,8 @@ void *start_timer(void *arg) {
|
||||
header->frameNumber = frameNr + iframes;
|
||||
header->packetNumber = pnum;
|
||||
header->modId = 0;
|
||||
header->row = detPos[2];
|
||||
header->column = detPos[3];
|
||||
header->row = row1;
|
||||
header->column = col1;
|
||||
|
||||
// fill data
|
||||
memcpy(packetData2 + sizeof(sls_detector_header),
|
||||
|
Binary file not shown.
@ -67,7 +67,13 @@ int defaultDacValues[NDAC] = DEFAULT_DAC_VALS;
|
||||
int vLimit = 0;
|
||||
enum detectorSettings thisSettings = UNINITIALIZED;
|
||||
int highvoltage = 0;
|
||||
|
||||
// getNumberofchannels return 0 for y in --update mode (virtual servers)
|
||||
#ifdef VIRTUAL
|
||||
int nSamples = DEFAULT_NUM_SAMPLES;
|
||||
#else
|
||||
int nSamples = 1;
|
||||
#endif
|
||||
int detPos[2] = {0, 0};
|
||||
|
||||
int isInitCheckDone() { return initCheckDone; }
|
||||
@ -430,16 +436,22 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
if (mapCSP0() == FAIL) {
|
||||
LOG(logERROR,
|
||||
("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!updateFlag && initError == OK) {
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
if (mapCSP0() == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
sharedMemory_setStop(0);
|
||||
#endif
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
@ -700,7 +712,16 @@ void resetPeripheral() {
|
||||
|
||||
/* set parameters - dr, adcenablemask */
|
||||
|
||||
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
|
||||
int setDynamicRange(int dr) {
|
||||
if (dr == 16)
|
||||
return OK;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int getDynamicRange(int *retval) {
|
||||
*retval = DYNAMIC_RANGE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setADCEnableMask(uint32_t mask) {
|
||||
if (mask == 0u) {
|
||||
@ -1710,8 +1731,8 @@ void *start_timer(void *arg) {
|
||||
header->frameNumber = frameNr + iframes;
|
||||
header->packetNumber = i;
|
||||
header->modId = 0;
|
||||
header->row = detPos[X];
|
||||
header->column = detPos[Y];
|
||||
header->row = detPos[Y];
|
||||
header->column = detPos[X];
|
||||
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header),
|
||||
|
Binary file not shown.
@ -10,20 +10,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
// Common C/C++ structure to handle pattern data
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint64_t word[MAX_PATTERN_LENGTH];
|
||||
uint64_t ioctrl;
|
||||
uint32_t limits[2];
|
||||
// loop0 start, loop0 stop .. loop2 start, loop2 stop
|
||||
uint32_t loop[6];
|
||||
uint32_t nloop[3];
|
||||
uint32_t wait[3];
|
||||
uint64_t waittime[3];
|
||||
} patternParameters;
|
||||
*/
|
||||
|
||||
int chipStatusRegister = 0;
|
||||
|
||||
int setBit(int ibit, int patword) { return patword |= (1 << ibit); }
|
||||
@ -32,44 +18,6 @@ int clearBit(int ibit, int patword) { return patword &= ~(1 << ibit); }
|
||||
|
||||
int getChipStatusRegister() { return chipStatusRegister; }
|
||||
|
||||
int gainCapsToCsr(int caps) {
|
||||
// Translates bit representation
|
||||
int csr = 0;
|
||||
if (!(caps & M3_C10pre))
|
||||
csr |= 1 << _CSR_C10pre;
|
||||
if (caps & M3_C15sh)
|
||||
csr |= 1 << CSR_C15sh;
|
||||
if (caps & M3_C30sh)
|
||||
csr |= 1 << CSR_C30sh;
|
||||
if (caps & M3_C50sh)
|
||||
csr |= 1 << CSR_C50sh;
|
||||
if (caps & M3_C225ACsh)
|
||||
csr |= 1 << CSR_C225ACsh;
|
||||
if (!(caps & M3_C15pre))
|
||||
csr |= 1 << _CSR_C15pre;
|
||||
|
||||
return csr;
|
||||
}
|
||||
|
||||
int csrToGainCaps(int csr) {
|
||||
// Translates bit representation
|
||||
int caps = 0;
|
||||
if (!(csr & (1 << _CSR_C10pre)))
|
||||
caps |= M3_C10pre;
|
||||
if (csr & (1 << CSR_C15sh))
|
||||
caps |= M3_C15sh;
|
||||
if (csr & (1 << CSR_C30sh))
|
||||
caps |= M3_C30sh;
|
||||
if (csr & (1 << CSR_C50sh))
|
||||
caps |= M3_C50sh;
|
||||
if (csr & (1 << CSR_C225ACsh))
|
||||
caps |= M3_C225ACsh;
|
||||
if (!(csr & (1 << _CSR_C15pre)))
|
||||
caps |= M3_C15pre;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
patternParameters *setChipStatusRegisterPattern(int csr) {
|
||||
int iaddr = 0;
|
||||
int nbits = 18;
|
||||
@ -149,54 +97,116 @@ patternParameters *setChipStatusRegisterPattern(int csr) {
|
||||
return pat;
|
||||
}
|
||||
|
||||
patternParameters *setInterpolation(int mask) {
|
||||
int csr;
|
||||
if (mask)
|
||||
csr = chipStatusRegister | (1 << CSR_interp);
|
||||
else
|
||||
csr = chipStatusRegister & ~(1 << CSR_interp);
|
||||
int getGainCaps() {
|
||||
int csr = chipStatusRegister;
|
||||
// Translates bit representation
|
||||
int caps = 0;
|
||||
if (!(csr & (1 << _CSR_C10pre)))
|
||||
caps |= M3_C10pre;
|
||||
if (csr & (1 << CSR_C15sh))
|
||||
caps |= M3_C15sh;
|
||||
if (csr & (1 << CSR_C30sh))
|
||||
caps |= M3_C30sh;
|
||||
if (csr & (1 << CSR_C50sh))
|
||||
caps |= M3_C50sh;
|
||||
if (csr & (1 << CSR_C225ACsh))
|
||||
caps |= M3_C225ACsh;
|
||||
if (!(csr & (1 << _CSR_C15pre)))
|
||||
caps |= M3_C15pre;
|
||||
|
||||
return setChipStatusRegisterPattern(csr);
|
||||
return caps;
|
||||
}
|
||||
|
||||
patternParameters *setPumpProbe(int mask) {
|
||||
int csr;
|
||||
if (mask)
|
||||
csr = chipStatusRegister | (1 << CSR_pumprobe);
|
||||
else
|
||||
csr = chipStatusRegister & ~(1 << CSR_pumprobe);
|
||||
int M3SetGainCaps(int caps) {
|
||||
int csr = chipStatusRegister & ~GAIN_MASK;
|
||||
|
||||
return setChipStatusRegisterPattern(csr);
|
||||
// Translates bit representation
|
||||
if (!(caps & M3_C10pre))
|
||||
csr |= 1 << _CSR_C10pre;
|
||||
if (caps & M3_C15sh)
|
||||
csr |= 1 << CSR_C15sh;
|
||||
if (caps & M3_C30sh)
|
||||
csr |= 1 << CSR_C30sh;
|
||||
if (caps & M3_C50sh)
|
||||
csr |= 1 << CSR_C50sh;
|
||||
if (caps & M3_C225ACsh)
|
||||
csr |= 1 << CSR_C225ACsh;
|
||||
if (!(caps & M3_C15pre))
|
||||
csr |= 1 << _CSR_C15pre;
|
||||
|
||||
return csr;
|
||||
}
|
||||
patternParameters *setDigitalPulsing(int mask) {
|
||||
|
||||
int csr;
|
||||
if (mask)
|
||||
csr = chipStatusRegister | (1 << CSR_dpulse);
|
||||
else
|
||||
csr = chipStatusRegister & ~(1 << CSR_dpulse);
|
||||
|
||||
return setChipStatusRegisterPattern(csr);
|
||||
int getInterpolation() {
|
||||
return ((chipStatusRegister & CSR_interp_MSK) >> CSR_interp);
|
||||
}
|
||||
patternParameters *setAnalogPulsing(int mask) {
|
||||
|
||||
int csr;
|
||||
if (mask)
|
||||
csr = chipStatusRegister | (1 << CSR_apulse);
|
||||
int M3SetInterpolation(int enable) {
|
||||
int csr = 0;
|
||||
if (enable)
|
||||
csr = chipStatusRegister | CSR_interp_MSK;
|
||||
else
|
||||
csr = chipStatusRegister & ~(1 << CSR_apulse);
|
||||
|
||||
return setChipStatusRegisterPattern(csr);
|
||||
csr = chipStatusRegister & ~CSR_interp_MSK;
|
||||
return csr;
|
||||
}
|
||||
patternParameters *setNegativePolarity(int mask) {
|
||||
|
||||
int csr;
|
||||
if (mask)
|
||||
csr = chipStatusRegister | (1 << CSR_invpol);
|
||||
int getPumpProbe() {
|
||||
return ((chipStatusRegister & CSR_pumprobe_MSK) >> CSR_pumprobe);
|
||||
}
|
||||
|
||||
int M3SetPumpProbe(int enable) {
|
||||
LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = 0;
|
||||
if (enable)
|
||||
csr = chipStatusRegister | CSR_pumprobe_MSK;
|
||||
else
|
||||
csr = chipStatusRegister & ~(1 << CSR_invpol);
|
||||
csr = chipStatusRegister & ~CSR_pumprobe_MSK;
|
||||
return csr;
|
||||
}
|
||||
|
||||
return setChipStatusRegisterPattern(csr);
|
||||
int getDigitalPulsing() {
|
||||
return ((chipStatusRegister & CSR_dpulse_MSK) >> CSR_dpulse);
|
||||
}
|
||||
|
||||
int M3SetDigitalPulsing(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Digital Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = 0;
|
||||
if (enable)
|
||||
csr = chipStatusRegister | CSR_dpulse_MSK;
|
||||
else
|
||||
csr = chipStatusRegister & ~CSR_dpulse_MSK;
|
||||
return csr;
|
||||
}
|
||||
|
||||
int getAnalogPulsing() {
|
||||
return ((chipStatusRegister & CSR_apulse_MSK) >> CSR_apulse);
|
||||
}
|
||||
|
||||
int M3SetAnalogPulsing(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Analog Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = 0;
|
||||
if (enable)
|
||||
csr = chipStatusRegister | CSR_apulse_MSK;
|
||||
else
|
||||
csr = chipStatusRegister & ~CSR_apulse_MSK;
|
||||
return csr;
|
||||
}
|
||||
|
||||
int getNegativePolarity() {
|
||||
return ((chipStatusRegister & CSR_invpol_MSK) >> CSR_invpol);
|
||||
}
|
||||
|
||||
int M3SetNegativePolarity(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Negative Polarity\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = 0;
|
||||
if (enable)
|
||||
csr = chipStatusRegister | CSR_invpol_MSK;
|
||||
else
|
||||
csr = chipStatusRegister & ~CSR_invpol_MSK;
|
||||
return csr;
|
||||
}
|
||||
|
||||
patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits) {
|
||||
|
@ -49,6 +49,12 @@
|
||||
// shaper)
|
||||
#define _CSR_C15pre 14 // negative polarity
|
||||
|
||||
#define CSR_invpol_MSK (0x1 << CSR_invpol)
|
||||
#define CSR_dpulse_MSK (0x1 << CSR_dpulse)
|
||||
#define CSR_interp_MSK (0x1 << CSR_interp)
|
||||
#define CSR_pumprobe_MSK (0x1 << CSR_pumprobe)
|
||||
#define CSR_apulse_MSK (0x1 << CSR_apulse)
|
||||
|
||||
#define CSR_default (1 << _CSR_C10pre) | (1 << CSR_C30sh)
|
||||
|
||||
#define GAIN_MASK \
|
||||
@ -58,15 +64,20 @@
|
||||
int setBit(int ibit, int patword);
|
||||
int clearBit(int ibit, int patword);
|
||||
int getChipStatusRegister();
|
||||
int gainCapsToCsr(int caps);
|
||||
int csrToGainCaps(int csr);
|
||||
|
||||
patternParameters *setChipStatusRegisterPattern(int csr);
|
||||
patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits);
|
||||
patternParameters *setInterpolation(int mask);
|
||||
patternParameters *setPumpProbe(int mask);
|
||||
patternParameters *setDigitalPulsing(int mask);
|
||||
patternParameters *setAnalogPulsing(int mask);
|
||||
patternParameters *setNegativePolarity(int mask);
|
||||
int getGainCaps();
|
||||
int M3SetGainCaps(int caps);
|
||||
int getInterpolation();
|
||||
int M3SetInterpolation(int enable);
|
||||
int getPumpProbe();
|
||||
int M3SetPumpProbe(int enable);
|
||||
int getDigitalPulsing();
|
||||
int M3SetDigitalPulsing(int enable);
|
||||
int getAnalogPulsing();
|
||||
int M3SetAnalogPulsing(int enable);
|
||||
int getNegativePolarity();
|
||||
int M3SetNegativePolarity(int enable);
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,9 @@ extern int isControlServer;
|
||||
extern void getMacAddressinString(char *cmac, int size, uint64_t mac);
|
||||
extern void getIpAddressinString(char *cip, uint32_t ip);
|
||||
|
||||
// Variables that will be exported
|
||||
int masterCommandLine = -1;
|
||||
|
||||
int initError = OK;
|
||||
int initCheckDone = 0;
|
||||
char initErrorMessage[MAX_STR_LENGTH];
|
||||
@ -289,6 +292,18 @@ void setModuleId(int modid) {
|
||||
bus_r(MOD_ID_REG) | ((modid << MOD_ID_OFST) & MOD_ID_MSK));
|
||||
}
|
||||
|
||||
int updateModuleId() {
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
if (initError == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
virtual_moduleid = modid;
|
||||
#endif
|
||||
setModuleId(modid);
|
||||
return OK;
|
||||
}
|
||||
|
||||
u_int64_t getDetectorMAC() {
|
||||
#ifdef VIRTUAL
|
||||
return 0;
|
||||
@ -352,16 +367,26 @@ void initControlServer() {
|
||||
}
|
||||
|
||||
void initStopServer() {
|
||||
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
if (mapCSP0() == FAIL) {
|
||||
LOG(logERROR,
|
||||
("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!updateFlag && initError == OK) {
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
LOG(logINFOBLUE, ("Configuring Stop server\n"));
|
||||
if (mapCSP0() == FAIL) {
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n");
|
||||
LOG(logERROR, (initErrorMessage));
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
sharedMemory_setStop(0);
|
||||
sharedMemory_setStop(0);
|
||||
if (checkCommandLineConfiguration() == FAIL) {
|
||||
initCheckDone = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
initCheckDone = 1;
|
||||
}
|
||||
|
||||
/* set up detector */
|
||||
@ -407,6 +432,12 @@ void setupDetector() {
|
||||
|
||||
allocateDetectorStructureMemory();
|
||||
|
||||
if (checkCommandLineConfiguration() == FAIL)
|
||||
return;
|
||||
|
||||
if (updateModuleId() == FAIL)
|
||||
return;
|
||||
|
||||
clkDivider[READOUT_C0] = DEFAULT_READOUT_C0;
|
||||
clkDivider[READOUT_C1] = DEFAULT_READOUT_C1;
|
||||
clkDivider[SYSTEM_C0] = DEFAULT_SYSTEM_C0;
|
||||
@ -447,16 +478,6 @@ void setupDetector() {
|
||||
setASICDefaults();
|
||||
setADIFDefaults();
|
||||
|
||||
// set module id in register
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
#ifdef VIRTUAL
|
||||
virtual_moduleid = modid;
|
||||
#endif
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
setModuleId(modid);
|
||||
|
||||
// set trigger flow for m3 (for all timing modes)
|
||||
bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK);
|
||||
|
||||
@ -480,10 +501,6 @@ void setupDetector() {
|
||||
setInitialExtSignals();
|
||||
// 10G UDP
|
||||
enableTenGigabitEthernet(1);
|
||||
getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
setSettings(DEFAULT_SETTINGS);
|
||||
|
||||
// check module type attached if not in debug mode
|
||||
@ -700,6 +717,27 @@ void setADIFDefaults() {
|
||||
ADIF_ADDTNL_OFST_MSK)));
|
||||
}
|
||||
|
||||
int checkCommandLineConfiguration() {
|
||||
if (masterCommandLine != -1) {
|
||||
#ifdef VIRTUAL
|
||||
if (masterCommandLine == 1) {
|
||||
bus_w(SYSTEM_STATUS_REG,
|
||||
bus_r(SYSTEM_STATUS_REG) & ~SYSTEM_STATUS_SLV_BRD_DTCT_MSK);
|
||||
} else {
|
||||
bus_w(SYSTEM_STATUS_REG,
|
||||
bus_r(SYSTEM_STATUS_REG) | SYSTEM_STATUS_SLV_BRD_DTCT_MSK);
|
||||
}
|
||||
#else
|
||||
initError = FAIL;
|
||||
strcpy(initErrorMessage,
|
||||
"Cannot set Master from command line for this detector. "
|
||||
"Should have been caught before!\n");
|
||||
return FAIL;
|
||||
#endif
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* firmware functions (resets) */
|
||||
|
||||
void cleanFifos() {
|
||||
@ -729,46 +767,54 @@ void resetPeripheral() {
|
||||
/* set parameters - dr, roi */
|
||||
|
||||
int setDynamicRange(int dr) {
|
||||
if (dr > 0) {
|
||||
uint32_t regval = 0;
|
||||
switch (dr) {
|
||||
/*case 1: TODO:Not implemented in firmware yet
|
||||
regval = CONFIG_DYNAMIC_RANGE_1_VAL;
|
||||
break;*/
|
||||
case 8:
|
||||
regval = CONFIG_DYNAMIC_RANGE_8_VAL;
|
||||
break;
|
||||
case 16:
|
||||
regval = CONFIG_DYNAMIC_RANGE_16_VAL;
|
||||
break;
|
||||
case 32:
|
||||
regval = CONFIG_DYNAMIC_RANGE_24_VAL;
|
||||
break;
|
||||
default:
|
||||
LOG(logERROR, ("Invalid dynamic range %d\n", dr));
|
||||
return -1;
|
||||
}
|
||||
// set it
|
||||
bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_DYNAMIC_RANGE_MSK);
|
||||
bus_w(CONFIG_REG, bus_r(CONFIG_REG) | regval);
|
||||
updatePacketizing();
|
||||
if (dr <= 0) {
|
||||
return FAIL;
|
||||
}
|
||||
uint32_t regval = 0;
|
||||
switch (dr) {
|
||||
/*case 1: TODO:Not implemented in firmware yet
|
||||
regval = CONFIG_DYNAMIC_RANGE_1_VAL;
|
||||
break;*/
|
||||
case 8:
|
||||
regval = CONFIG_DYNAMIC_RANGE_8_VAL;
|
||||
break;
|
||||
case 16:
|
||||
regval = CONFIG_DYNAMIC_RANGE_16_VAL;
|
||||
break;
|
||||
case 32:
|
||||
regval = CONFIG_DYNAMIC_RANGE_24_VAL;
|
||||
break;
|
||||
default:
|
||||
LOG(logERROR, ("Invalid dynamic range %d\n", dr));
|
||||
return -1;
|
||||
}
|
||||
// set it
|
||||
bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_DYNAMIC_RANGE_MSK);
|
||||
bus_w(CONFIG_REG, bus_r(CONFIG_REG) | regval);
|
||||
updatePacketizing();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDynamicRange(int *retval) {
|
||||
uint32_t regval = bus_r(CONFIG_REG) & CONFIG_DYNAMIC_RANGE_MSK;
|
||||
switch (regval) {
|
||||
/*case CONFIG_DYNAMIC_RANGE_1_VAL: TODO:Not implemented in firmware yet
|
||||
return 1;*/
|
||||
case CONFIG_DYNAMIC_RANGE_8_VAL:
|
||||
return 8;
|
||||
*retval = 8;
|
||||
break;
|
||||
case CONFIG_DYNAMIC_RANGE_16_VAL:
|
||||
return 16;
|
||||
*retval = 16;
|
||||
break;
|
||||
case CONFIG_DYNAMIC_RANGE_24_VAL:
|
||||
return 32;
|
||||
*retval = 32;
|
||||
break;
|
||||
default:
|
||||
LOG(logERROR, ("Invalid dynamic range %d read back\n",
|
||||
regval >> CONFIG_DYNAMIC_RANGE_OFST));
|
||||
return -1;
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* set parameters - readout */
|
||||
@ -1091,7 +1137,8 @@ void updatePacketizing() {
|
||||
|
||||
// 10g
|
||||
if (tgEnable) {
|
||||
const int dr = setDynamicRange(-1);
|
||||
int dr = 0;
|
||||
getDynamicRange(&dr);
|
||||
packetsPerFrame = 1;
|
||||
if (dr == 32 && ncounters > 1) {
|
||||
packetsPerFrame = 2;
|
||||
@ -1364,6 +1411,9 @@ enum detectorSettings setSettings(enum detectorSettings sett) {
|
||||
}
|
||||
|
||||
void validateSettings() {
|
||||
LOG(logWARNING, ("Not validating dac settings temporarily"));
|
||||
return;
|
||||
|
||||
// if any special dac value is changed individually => undefined
|
||||
const int specialDacs[NSPECIALDACS] = SPECIALDACINDEX;
|
||||
int *specialDacValues[] = {defaultDacValue_standard, defaultDacValue_fast,
|
||||
@ -1545,14 +1595,18 @@ int setHighVoltage(int val) {
|
||||
|
||||
/* parameters - timing */
|
||||
|
||||
int isMaster() {
|
||||
return !((bus_r(SYSTEM_STATUS_REG) & SYSTEM_STATUS_SLV_BRD_DTCT_MSK) >>
|
||||
SYSTEM_STATUS_SLV_BRD_DTCT_OFST);
|
||||
int isMaster(int *retval) {
|
||||
int slave = ((bus_r(SYSTEM_STATUS_REG) & SYSTEM_STATUS_SLV_BRD_DTCT_MSK) >>
|
||||
SYSTEM_STATUS_SLV_BRD_DTCT_OFST);
|
||||
*retval = (slave == 0 ? 1 : 0);
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setTiming(enum timingMode arg) {
|
||||
|
||||
if (!isMaster() && arg == AUTO_TIMING)
|
||||
int master = 0;
|
||||
isMaster(&master);
|
||||
if (!master && arg == AUTO_TIMING)
|
||||
arg = TRIGGER_EXPOSURE;
|
||||
|
||||
uint32_t addr = CONFIG_REG;
|
||||
@ -1638,6 +1692,55 @@ void setInitialExtSignals() {
|
||||
DOUTIF_RISING_LNGTH_PORT_1_MSK));
|
||||
}
|
||||
|
||||
int setGainCaps(int caps) {
|
||||
LOG(logINFO, ("Setting gain caps to: %u\n", caps));
|
||||
int csr = M3SetGainCaps(caps);
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
int setInterpolation(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Interpolation\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
if (enable) {
|
||||
setCounterMask(MAX_COUNTER_MSK);
|
||||
if (getCounterMask() != MAX_COUNTER_MSK) {
|
||||
LOG(logERROR,
|
||||
("Could not set interpolation. Could not enable all counters"));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tEnabled all counters\n"));
|
||||
}
|
||||
int csr = M3SetInterpolation(enable);
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
int setPumpProbe(int enable) {
|
||||
LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = M3SetPumpProbe(enable);
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
int setDigitalPulsing(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Digital Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = M3SetDigitalPulsing(enable);
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
int setAnalogPulsing(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Analog Pulsing\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = M3SetAnalogPulsing(enable);
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
int setNegativePolarity(int enable) {
|
||||
LOG(logINFO,
|
||||
("%s Negative Polarity\n", enable == 0 ? "Disabling" : "Enabling"));
|
||||
int csr = M3SetNegativePolarity(enable);
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
void setExtSignal(int signalIndex, enum externalSignalFlag mode) {
|
||||
LOG(logDEBUG1, ("Setting signal flag[%d] to %d\n", signalIndex, mode));
|
||||
|
||||
@ -1841,7 +1944,7 @@ int setDetectorPosition(int pos[]) {
|
||||
int ret = OK;
|
||||
|
||||
// row
|
||||
value = detPos[X];
|
||||
value = detPos[Y];
|
||||
bus_w(addr, (bus_r(addr) & ~COORD_ROW_MSK) |
|
||||
((value << COORD_ROW_OFST) & COORD_ROW_MSK));
|
||||
valueRead = ((bus_r(addr) & COORD_ROW_MSK) >> COORD_ROW_OFST);
|
||||
@ -1852,7 +1955,7 @@ int setDetectorPosition(int pos[]) {
|
||||
}
|
||||
|
||||
// col
|
||||
value = detPos[Y];
|
||||
value = detPos[X];
|
||||
bus_w(addr, (bus_r(addr) & ~COORD_COL_MSK) |
|
||||
((value << COORD_COL_OFST) & COORD_COL_MSK));
|
||||
valueRead = ((bus_r(addr) & COORD_COL_MSK) >> COORD_COL_OFST);
|
||||
@ -1863,7 +1966,8 @@ int setDetectorPosition(int pos[]) {
|
||||
}
|
||||
|
||||
if (ret == OK) {
|
||||
LOG(logINFO, ("\tPosition set to [%d, %d]\n", detPos[X], detPos[Y]));
|
||||
LOG(logINFO,
|
||||
("\tPosition set to [%d, %d] #(col, row)\n", detPos[X], detPos[Y]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -2202,7 +2306,8 @@ void *start_timer(void *arg) {
|
||||
|
||||
const int imageSize = calculateDataBytes();
|
||||
const int tgEnable = enableTenGigabitEthernet(-1);
|
||||
const int dr = setDynamicRange(-1);
|
||||
int dr = 0;
|
||||
getDynamicRange(&dr);
|
||||
int ncounters = __builtin_popcount(getCounterMask());
|
||||
int dataSize = 0;
|
||||
int packetsPerFrame = 0;
|
||||
@ -2284,8 +2389,8 @@ void *start_timer(void *arg) {
|
||||
header->frameNumber = virtual_currentFrameNumber;
|
||||
header->packetNumber = i;
|
||||
header->modId = virtual_moduleid;
|
||||
header->row = detPos[X];
|
||||
header->column = detPos[Y];
|
||||
header->row = detPos[Y];
|
||||
header->column = detPos[X];
|
||||
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header),
|
||||
@ -2523,7 +2628,8 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
|
||||
|
||||
int calculateDataBytes() {
|
||||
int numCounters = __builtin_popcount(getCounterMask());
|
||||
int dr = setDynamicRange(-1);
|
||||
int dr = 0;
|
||||
getDynamicRange(&dr);
|
||||
return (NCHAN_1_COUNTER * NCHIP * numCounters * ((double)dr / 8.00));
|
||||
}
|
||||
|
||||
@ -2570,21 +2676,3 @@ int setChipStatusRegister(int csr) {
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
int setGainCaps(int caps) {
|
||||
LOG(logINFO, ("Setting gain caps to: %u\n", caps));
|
||||
// Update only gain caps, leave the rest of the CSR unchanged
|
||||
int csr = getChipStatusRegister();
|
||||
csr &= ~GAIN_MASK;
|
||||
|
||||
caps = gainCapsToCsr(caps);
|
||||
// caps &= GAIN_MASK;
|
||||
csr |= caps;
|
||||
return setChipStatusRegister(csr);
|
||||
}
|
||||
|
||||
int getGainCaps() {
|
||||
int csr = getChipStatusRegister();
|
||||
int caps = csrToGainCaps(csr);
|
||||
return caps;
|
||||
}
|
||||
|
@ -66,3 +66,5 @@ int moveBinaryFile(char *mess, char *dest, char *src, char *errorPrefix);
|
||||
|
||||
int createEmptyFile(char *mess, char *fname, char *errorPrefix);
|
||||
int deleteFile(char *mess, char *fname, char *errorPrefix);
|
||||
|
||||
int deleteOldServers(char *mess, char *newServerPath, char *errorPrefix);
|
||||
|
@ -26,10 +26,12 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd,
|
||||
uint64_t fsize);
|
||||
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
|
||||
char *functionType, char *clientChecksum,
|
||||
ssize_t fsize);
|
||||
ssize_t fsize, int forceDeleteNormalFile);
|
||||
int getDrive(char *mess, enum PROGRAM_INDEX index);
|
||||
/** Notify fpga not to touch flash, open src and flash drive to write */
|
||||
int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd);
|
||||
int openFileForFlash(char *mess, enum PROGRAM_INDEX index, FILE **flashfd, FILE **srcfd,
|
||||
int forceDeleteNormalFile);
|
||||
int checkNormalFile(char *mess, enum PROGRAM_INDEX index, int forceDeleteNormalFile);
|
||||
int eraseFlash(char *mess);
|
||||
/* write from tmp file to flash */
|
||||
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd);
|
||||
|
@ -97,6 +97,9 @@ u_int32_t getDetectorNumber();
|
||||
#if defined(GOTTHARD2D) || defined(EIGERD) || defined(MYTHEN3D)
|
||||
int getModuleId(int *ret, char *mess);
|
||||
#endif
|
||||
#if defined(EIGERD) || defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
int updateModuleId();
|
||||
#endif
|
||||
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
|
||||
void setModuleId(int modid);
|
||||
#endif
|
||||
@ -110,7 +113,11 @@ u_int32_t getBoardRevision();
|
||||
void initControlServer();
|
||||
void initStopServer();
|
||||
#ifdef EIGERD
|
||||
void getModuleConfiguration();
|
||||
int updateModuleConfiguration();
|
||||
int getModuleConfiguration(int *m, int *t, int *n);
|
||||
#ifdef VIRTUAL
|
||||
void checkVirtual9MFlag();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// set up detector
|
||||
@ -137,6 +144,10 @@ void setADIFDefaults();
|
||||
#if defined(GOTTHARD2D) || defined(EIGERD) || defined(JUNGFRAUD)
|
||||
int readConfigFile();
|
||||
#endif
|
||||
#if defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \
|
||||
defined(MYTHEN3D)
|
||||
int checkCommandLineConfiguration();
|
||||
#endif
|
||||
#ifdef EIGERD
|
||||
void resetToHardwareSettings();
|
||||
#endif
|
||||
@ -173,6 +184,7 @@ void setMasterSlaveConfiguration();
|
||||
|
||||
// parameters - dr, roi
|
||||
int setDynamicRange(int dr);
|
||||
int getDynamicRange(int *retval);
|
||||
#ifdef GOTTHARDD
|
||||
int setROI(ROI arg);
|
||||
ROI getROI();
|
||||
@ -362,9 +374,16 @@ int getADC(enum ADCINDEX ind);
|
||||
int setHighVoltage(int val);
|
||||
|
||||
// parameters - timing, extsig
|
||||
#if defined(MYTHEN3D) || defined(EIGERD) || defined(GOTTHARDD)
|
||||
int isMaster();
|
||||
#ifdef EIGERD
|
||||
int setMaster(enum MASTERINDEX m);
|
||||
int setTop(enum TOPINDEX t);
|
||||
int isTop(int *retval);
|
||||
#endif
|
||||
#if defined(MYTHEN3D) || defined(EIGERD) || defined(GOTTHARDD) || \
|
||||
defined(GOTTHARD2D)
|
||||
int isMaster(int *retval);
|
||||
#endif
|
||||
|
||||
#ifdef GOTTHARD2D
|
||||
void updatingRegisters();
|
||||
#endif
|
||||
@ -372,9 +391,13 @@ void setTiming(enum timingMode arg);
|
||||
enum timingMode getTiming();
|
||||
#ifdef MYTHEN3D
|
||||
void setInitialExtSignals();
|
||||
int setGainCaps(int caps);
|
||||
int getGainCaps();
|
||||
int setChipStatusRegister(int csr);
|
||||
int setGainCaps(int caps);
|
||||
int setInterpolation(int enable);
|
||||
int setPumpProbe(int enable);
|
||||
int setDigitalPulsing(int enable);
|
||||
int setAnalogPulsing(int enable);
|
||||
int setNegativePolarity(int enable);
|
||||
int setDACS(int *dacs);
|
||||
#endif
|
||||
#if defined(GOTTHARDD) || defined(MYTHEN3D)
|
||||
|
@ -132,7 +132,6 @@ int check_version(int);
|
||||
int software_trigger(int);
|
||||
int led(int);
|
||||
int digital_io_delay(int);
|
||||
int copy_detector_server(int);
|
||||
int reboot_controller(int);
|
||||
int set_adc_enable_mask(int);
|
||||
int get_adc_enable_mask(int);
|
||||
@ -245,6 +244,7 @@ int get_pattern(int);
|
||||
int load_default_pattern(int);
|
||||
int get_all_threshold_energy(int);
|
||||
int get_master(int);
|
||||
int set_master(int);
|
||||
int get_csr();
|
||||
int set_gain_caps(int);
|
||||
int get_gain_caps(int);
|
||||
@ -284,9 +284,22 @@ int update_detector_server(int);
|
||||
int receive_program(int file_des, enum PROGRAM_INDEX index);
|
||||
void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
|
||||
char *functionType, uint64_t filesize,
|
||||
char *checksum, char *serverName);
|
||||
char *checksum, char *serverName,
|
||||
int forceDeleteNormalFile);
|
||||
void receive_program_default(int file_des, enum PROGRAM_INDEX index,
|
||||
char *functionType, uint64_t filesize,
|
||||
char *checksum, char *serverName);
|
||||
int get_update_mode(int);
|
||||
int set_update_mode(int);
|
||||
int get_top(int);
|
||||
int set_top(int);
|
||||
int get_polarity(int);
|
||||
int set_polarity(int);
|
||||
int get_interpolation(int);
|
||||
int set_interpolation(int);
|
||||
int get_pump_probe(int);
|
||||
int set_pump_probe(int);
|
||||
int get_analog_pulsing(int);
|
||||
int set_analog_pulsing(int);
|
||||
int get_digital_pulsing(int);
|
||||
int set_digital_pulsing(int);
|
||||
|
@ -50,6 +50,10 @@ int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
|
||||
}
|
||||
|
||||
int getAbsPath(char *buf, size_t bufSize, char *fname) {
|
||||
if (fname[0] == '/') {
|
||||
strcpy(buf, fname);
|
||||
return OK;
|
||||
}
|
||||
// get path of current binary
|
||||
char path[bufSize];
|
||||
memset(path, 0, bufSize);
|
||||
@ -60,10 +64,14 @@ int getAbsPath(char *buf, size_t bufSize, char *fname) {
|
||||
}
|
||||
path[len] = '\0';
|
||||
|
||||
// get dir path and attach config file name
|
||||
// get dir path and attach file name
|
||||
char *dir = dirname(path);
|
||||
memset(buf, 0, bufSize);
|
||||
sprintf(buf, "%s/%s", dir, fname);
|
||||
if (!strcmp(dir, "/")) {
|
||||
sprintf(buf, "/%s", fname);
|
||||
} else {
|
||||
sprintf(buf, "%s/%s", dir, fname);
|
||||
}
|
||||
LOG(logDEBUG1, ("full path for %s: %s\n", fname, buf));
|
||||
return OK;
|
||||
}
|
||||
@ -466,7 +474,7 @@ int setupDetectorServer(char *mess, char *sname) {
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tSymbolic link created\n"));
|
||||
LOG(logINFO, ("\tSymbolic link created %s -> %s\n", linkname, sname));
|
||||
|
||||
// blackfin boards (respawn) (only kept for backwards compatibility)
|
||||
#ifndef VIRTUAL
|
||||
@ -485,7 +493,7 @@ int setupDetectorServer(char *mess, char *sname) {
|
||||
|
||||
// add new link name to /etc/inittab
|
||||
if (snprintf(cmd, MAX_STR_LENGTH,
|
||||
"echo 'ttyS0::respawn:/./%s' >> /etc/inittab",
|
||||
"echo 'ttyS0::respawn:%s' >> /etc/inittab",
|
||||
linkname) >= MAX_STR_LENGTH) {
|
||||
strcpy(mess, "Could not copy detector server. Command "
|
||||
"to add new server for spawning is too long\n");
|
||||
@ -670,3 +678,26 @@ int deleteFile(char *mess, char *fname, char *errorPrefix) {
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int deleteOldServers(char *mess, char *newServerPath, char *errorPrefix) {
|
||||
LOG(logINFO, ("\tChecking if current binary is to be deleted ...\n"))
|
||||
// get path of current binary (get file name if link)
|
||||
char currentBinary[MAX_STR_LENGTH];
|
||||
memset(currentBinary, 0, MAX_STR_LENGTH);
|
||||
ssize_t len = readlink("/proc/self/exe", currentBinary, MAX_STR_LENGTH - 1);
|
||||
if (len < 0) {
|
||||
LOG(logWARNING, ("(%s): Could not delete old servers. Could not "
|
||||
"readlink current binary\n",
|
||||
errorPrefix));
|
||||
return FAIL;
|
||||
}
|
||||
currentBinary[len] = '\0';
|
||||
LOG(logDEBUG1, ("Current binary:%s\n", currentBinary));
|
||||
|
||||
// delete file
|
||||
if (deleteFile(mess, currentBinary, errorPrefix) == FAIL) {
|
||||
LOG(logWARNING, ("(%s). Could not delete old servers\n", errorPrefix));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "slsDetectorServer_defs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
@ -38,6 +39,9 @@
|
||||
|
||||
#define CMD_GET_AMD_FLASH "dmesg | grep Amd"
|
||||
|
||||
#define CMD_CREATE_DEVICE_FILE_PART1 "mknod"
|
||||
#define CMD_CREATE_DEVICE_FILE_PART2 "c 90 6"
|
||||
|
||||
#define FLASH_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB
|
||||
// clang-format on
|
||||
|
||||
@ -274,7 +278,8 @@ int allowUpdate(char *mess, char *functionType) {
|
||||
getKernelVersion(retvals);
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. Kernel version %s is too old to "
|
||||
"update the Amd flash/ root directory. Most likely, blackfin needs rescue or replacement. Please contact us.\n",
|
||||
"update the Amd flash/ root directory. Most likely, blackfin "
|
||||
"needs rescue or replacement. Please contact us.\n",
|
||||
functionType, retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
@ -319,7 +324,7 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd,
|
||||
|
||||
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
|
||||
char *functionType, char *clientChecksum,
|
||||
ssize_t fsize) {
|
||||
ssize_t fsize, int forceDeleteNormalFile) {
|
||||
|
||||
memset(messageType, 0, sizeof(messageType));
|
||||
strcpy(messageType, functionType);
|
||||
@ -330,7 +335,8 @@ int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
|
||||
|
||||
FILE *flashfd = NULL;
|
||||
FILE *srcfd = NULL;
|
||||
if (openFileForFlash(mess, &flashfd, &srcfd) == FAIL) {
|
||||
if (openFileForFlash(mess, index, &flashfd, &srcfd, forceDeleteNormalFile) ==
|
||||
FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -434,7 +440,8 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) {
|
||||
int openFileForFlash(char *mess, enum PROGRAM_INDEX index, FILE **flashfd, FILE **srcfd,
|
||||
int forceDeleteNormalFile) {
|
||||
// open src file
|
||||
*srcfd = fopen(TEMP_PROG_FILE_NAME, "r");
|
||||
if (*srcfd == NULL) {
|
||||
@ -447,6 +454,11 @@ int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) {
|
||||
}
|
||||
LOG(logDEBUG1, ("Temp file ready for reading\n"));
|
||||
|
||||
if (checkNormalFile(mess, index, forceDeleteNormalFile) == FAIL) {
|
||||
fclose(*srcfd);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// open flash drive for writing
|
||||
*flashfd = fopen(flashDriveName, "w");
|
||||
if (*flashfd == NULL) {
|
||||
@ -462,6 +474,95 @@ int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int checkNormalFile(char *mess, enum PROGRAM_INDEX index, int forceDeleteNormalFile) {
|
||||
#ifndef VIRTUAL
|
||||
// check if its a normal file or special file
|
||||
struct stat buf;
|
||||
if (stat(flashDriveName, &buf) == -1) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to find the flash drive %s\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
// zero = normal file (not char special drive file)
|
||||
if (!S_ISCHR(buf.st_mode)) {
|
||||
// kernel memory is not permanent
|
||||
if (index != PROGRAM_FPGA) {
|
||||
sprintf(mess,
|
||||
"Could not %s. The flash drive found is a normal file. "
|
||||
"Reboot board using 'rebootcontroller' command to load "
|
||||
"proper device tree\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// user does not allow to fix it (default)
|
||||
if (forceDeleteNormalFile == 0) {
|
||||
sprintf(mess,
|
||||
"Could not %s. The flash drive %s found for fpga programming is a normal file. To "
|
||||
"fix this (by deleting this file, creating the flash drive and proceeding with "
|
||||
"programming), re-run the programming command 'programfpga' with parameter "
|
||||
"'--force-delete-normal-file'\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// fpga memory stays after a reboot, user allowed to fix it
|
||||
LOG(logWARNING, ("Flash drive invalidated (normal file). Fixing it...\n"));
|
||||
|
||||
// user allows to fix it, so force delete normal file
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "rm %s", flashDriveName) >=
|
||||
MAX_STR_LENGTH) {
|
||||
sprintf(mess,
|
||||
"Could not update %s. Command to delete normal file %s is "
|
||||
"too long\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(
|
||||
mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. (could not delete normal file %s: %s)\n",
|
||||
messageType, flashDriveName, retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tDeleted Normal File (%s)\n", flashDriveName));
|
||||
|
||||
// create special drive
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "%s %s %s",
|
||||
CMD_CREATE_DEVICE_FILE_PART1, flashDriveName,
|
||||
CMD_CREATE_DEVICE_FILE_PART2) >= MAX_STR_LENGTH) {
|
||||
sprintf(mess,
|
||||
"Could not update %s. Command to create special file %s is "
|
||||
"too long\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(
|
||||
mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. (could not create special file %s: %s)\n",
|
||||
messageType, flashDriveName, retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tSpecial File created (%s)\n", flashDriveName));
|
||||
} else {
|
||||
LOG(logINFO, ("\tValidated flash drive (not a normal file)\n"));
|
||||
}
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
int eraseFlash(char *mess) {
|
||||
LOG(logINFO, ("\tErasing Flash...\n"));
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h> // usleep
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* global variables */
|
||||
|
||||
@ -146,6 +147,30 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) {
|
||||
}
|
||||
|
||||
int openFileForFlash(char *mess, FILE **flashfd) {
|
||||
#ifndef VIRTUAL
|
||||
// check if its a normal file or special file
|
||||
struct stat buf;
|
||||
if (stat(flashDriveName, &buf) == -1) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to find the flash drive %s\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
// zero = normal file (not char drive special file)
|
||||
if (!S_ISCHR(buf.st_mode)) {
|
||||
// memory is not permanent
|
||||
sprintf(mess,
|
||||
"Could not %s. The flash drive found is a normal file. "
|
||||
"Reboot board using 'rebootcontroller' command to load "
|
||||
"proper device tree\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tValidated flash drive (not a normal file)\n"));
|
||||
#endif
|
||||
|
||||
*flashfd = fopen(flashDriveName, "w");
|
||||
if (*flashfd == NULL) {
|
||||
sprintf(mess,
|
||||
|
@ -26,11 +26,20 @@ extern int sockfd;
|
||||
extern int debugflag;
|
||||
extern int updateFlag;
|
||||
extern int checkModuleFlag;
|
||||
extern int ignoreConfigFileFlag;
|
||||
|
||||
// Global variables from slsDetectorFunctionList
|
||||
#ifdef GOTTHARDD
|
||||
extern int phaseShift;
|
||||
#endif
|
||||
#if defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \
|
||||
defined(MYTHEN3D)
|
||||
extern int masterCommandLine;
|
||||
#endif
|
||||
#ifdef EIGERD
|
||||
extern int topCommandLine;
|
||||
#endif
|
||||
int portno = DEFAULT_PORTNO;
|
||||
|
||||
void error(char *msg) { perror(msg); }
|
||||
|
||||
@ -42,32 +51,62 @@ void sigInterruptHandler(int p) {
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// options
|
||||
int portno = DEFAULT_PORTNO;
|
||||
isControlServer = 1;
|
||||
debugflag = 0;
|
||||
updateFlag = 0;
|
||||
checkModuleFlag = 1;
|
||||
int version = 0;
|
||||
ignoreConfigFileFlag = 0;
|
||||
#if defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \
|
||||
defined(MYTHEN3D)
|
||||
masterCommandLine = -1;
|
||||
#endif
|
||||
#ifdef EIGERD
|
||||
topCommandLine = -1;
|
||||
#endif
|
||||
|
||||
// help message
|
||||
char helpMessage[MAX_STR_LENGTH];
|
||||
memset(helpMessage, 0, MAX_STR_LENGTH);
|
||||
sprintf(
|
||||
helpMessage,
|
||||
"Usage: %s [arguments]\n"
|
||||
"Possible arguments are:\n"
|
||||
"\t-v, --version : Software version\n"
|
||||
"\t-p, --port <port> : TCP communication port with client. \n"
|
||||
"\t-g, --nomodule : [Mythen3][Gotthard2] Generic or No "
|
||||
"Module mode. Skips detector type checks. \n"
|
||||
"\t-f, --phaseshift <value> : [Gotthard] only. Sets phase shift. \n"
|
||||
"\t-d, --devel : Developer mode. Skips firmware checks. \n"
|
||||
"\t-u, --update : Update mode. Skips firmware checks and "
|
||||
"initial detector setup. \n"
|
||||
"\t-s, --stopserver : Stop server. Do not use as it is created "
|
||||
"by "
|
||||
"control server \n\n",
|
||||
argv[0]);
|
||||
const size_t helpMessageSize = 1200;
|
||||
char helpMessage[helpMessageSize];
|
||||
{
|
||||
memset(helpMessage, 0, helpMessageSize);
|
||||
int len = snprintf(
|
||||
helpMessage, helpMessageSize,
|
||||
"Usage: %s [arguments]\n"
|
||||
"Possible arguments are:\n"
|
||||
"\t-v, --version : Software version\n"
|
||||
"\t-p, --port <port> : TCP communication port with client. "
|
||||
"\n"
|
||||
"\t-g, --nomodule : [Mythen3][Gotthard2] \n"
|
||||
"\t Generic or No Module mode. Skips "
|
||||
"detector type checks. \n"
|
||||
"\t-f, --phaseshift <value> : [Gotthard] only. Sets phase shift. \n"
|
||||
"\t-d, --devel : Developer mode. Skips firmware "
|
||||
"checks. \n"
|
||||
"\t-u, --update : Update mode. Skips firmware checks "
|
||||
"and "
|
||||
"initial detector setup. \n"
|
||||
"\t-i, --ignore-config : "
|
||||
"[Eiger][Jungfrau][Gotthard][Gotthard2] \n"
|
||||
"\t Ignore config file. \n"
|
||||
"\t-m, --master <master> : "
|
||||
"[Eiger][Mythen3][Gotthard][Gotthard2] \n"
|
||||
"\t Set Master to 0 or 1. Precedence "
|
||||
"over "
|
||||
"config file. Only for virtual servers except Eiger. \n"
|
||||
"\t-t, --top <top> : [Eiger] Set Top to 0 or 1. "
|
||||
"Precedence "
|
||||
"over config file. \n"
|
||||
"\t-s, --stopserver : Stop server. Do not use as it is "
|
||||
"created "
|
||||
"by control server \n\n",
|
||||
argv[0]);
|
||||
if (len >= (int)helpMessageSize) {
|
||||
LOG(logERROR, ("Help for Server command line arguments size %d "
|
||||
"exceed capacity of %d characters\n",
|
||||
len, helpMessageSize));
|
||||
}
|
||||
}
|
||||
|
||||
// parse command line for config
|
||||
static struct option long_options[] = {
|
||||
@ -80,6 +119,9 @@ int main(int argc, char *argv[]) {
|
||||
{"nomodule", no_argument, NULL, 'g'}, // generic
|
||||
{"devel", no_argument, NULL, 'd'},
|
||||
{"update", no_argument, NULL, 'u'},
|
||||
{"ignore-config", no_argument, NULL, 'i'},
|
||||
{"master", required_argument, NULL, 'm'},
|
||||
{"top", required_argument, NULL, 't'},
|
||||
{"stopserver", no_argument, NULL, 's'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
@ -89,7 +131,8 @@ int main(int argc, char *argv[]) {
|
||||
int c = 0;
|
||||
|
||||
while (c != -1) {
|
||||
c = getopt_long(argc, argv, "hvp:f:gdus", long_options, &option_index);
|
||||
c = getopt_long(argc, argv, "hvp:f:gduim:t:s", long_options,
|
||||
&option_index);
|
||||
|
||||
// Detect the end of the options
|
||||
if (c == -1)
|
||||
@ -160,6 +203,57 @@ int main(int argc, char *argv[]) {
|
||||
isControlServer = 0;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
#if defined(EIGERD) || defined(GOTTHARDD) || defined(GOTTHARD2D) || \
|
||||
defined(JUNGFRAUD)
|
||||
LOG(logINFO, ("Ignoring config file\n"));
|
||||
ignoreConfigFileFlag = 1;
|
||||
#else
|
||||
LOG(logERROR, ("No server config files for this detector\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
#if (defined(MYTHEN3D) || defined(GOTTHARDD) || defined(GOTTHARD2D)) && \
|
||||
!defined(VIRTUAL)
|
||||
LOG(logERROR, ("Cannot set master via the detector server for this "
|
||||
"detector\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
#elif defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \
|
||||
defined(MYTHEN3D)
|
||||
if (sscanf(optarg, "%d", &masterCommandLine) != 1) {
|
||||
LOG(logERROR, ("Cannot scan master argument\n%s", helpMessage));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (masterCommandLine == 1) {
|
||||
LOG(logINFO, ("Detector Master mode\n"));
|
||||
} else {
|
||||
LOG(logINFO, ("Detector Slave mode\n"));
|
||||
}
|
||||
#else
|
||||
LOG(logERROR, ("No master implemented for this detector server\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 't':
|
||||
#ifdef EIGERD
|
||||
if (sscanf(optarg, "%d", &topCommandLine) != 1) {
|
||||
LOG(logERROR, ("Cannot scan top argument\n%s", helpMessage));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (topCommandLine == 1) {
|
||||
LOG(logINFO, ("Detector Top mode\n"));
|
||||
} else {
|
||||
LOG(logINFO, ("Detector Bottom mode\n"));
|
||||
}
|
||||
#else
|
||||
LOG(logERROR, ("No top implemented for this detector server\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
printf("%s", helpMessage);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -37,6 +37,8 @@ const enum detectorType myDetectorType = GOTTHARD2;
|
||||
const enum detectorType myDetectorType = GENERIC;
|
||||
#endif
|
||||
|
||||
#define LOCALHOSTIP_INT 2130706433
|
||||
|
||||
// Global variables from communication_funcs
|
||||
extern int lockStatus;
|
||||
extern uint32_t lastClientIP;
|
||||
@ -52,6 +54,7 @@ int sockfd = 0;
|
||||
int debugflag = 0;
|
||||
int updateFlag = 0;
|
||||
int checkModuleFlag = 1;
|
||||
int ignoreConfigFileFlag = 0;
|
||||
|
||||
udpStruct udpDetails[MAX_UDP_DESTINATION];
|
||||
int numUdpDestinations = 1;
|
||||
@ -59,8 +62,8 @@ int firstUDPDestination = 0;
|
||||
|
||||
int configured = FAIL;
|
||||
char configureMessage[MAX_STR_LENGTH] = "udp parameters not configured yet";
|
||||
int maxydet = -1;
|
||||
int detectorId = -1;
|
||||
int maxYMods = -1;
|
||||
int moduleIndex = -1;
|
||||
|
||||
// Local variables
|
||||
int (*flist[NUM_DET_FUNCTIONS])(int);
|
||||
@ -78,28 +81,18 @@ char scanErrMessage[MAX_STR_LENGTH] = "";
|
||||
/* initialization functions */
|
||||
|
||||
int updateModeAllowedFunction(int file_des) {
|
||||
unsigned int listsize = 19;
|
||||
enum detFuncs list[] = {F_EXEC_COMMAND,
|
||||
F_GET_DETECTOR_TYPE,
|
||||
F_GET_FIRMWARE_VERSION,
|
||||
F_GET_SERVER_VERSION,
|
||||
F_GET_SERIAL_NUMBER,
|
||||
F_WRITE_REGISTER,
|
||||
F_READ_REGISTER,
|
||||
F_LOCK_SERVER,
|
||||
F_GET_LAST_CLIENT_IP,
|
||||
F_PROGRAM_FPGA,
|
||||
F_RESET_FPGA,
|
||||
F_CHECK_VERSION,
|
||||
F_COPY_DET_SERVER,
|
||||
F_REBOOT_CONTROLLER,
|
||||
F_GET_KERNEL_VERSION,
|
||||
F_UPDATE_KERNEL,
|
||||
F_UPDATE_DETECTOR_SERVER,
|
||||
F_GET_UPDATE_MODE,
|
||||
F_SET_UPDATE_MODE};
|
||||
for (unsigned int i = 0; i < listsize; ++i) {
|
||||
if ((unsigned int)fnum == list[i]) {
|
||||
enum detFuncs allowedFuncs[] = {
|
||||
F_EXEC_COMMAND, F_GET_DETECTOR_TYPE, F_GET_FIRMWARE_VERSION,
|
||||
F_GET_SERVER_VERSION, F_GET_SERIAL_NUMBER, F_WRITE_REGISTER,
|
||||
F_READ_REGISTER, F_LOCK_SERVER, F_GET_LAST_CLIENT_IP,
|
||||
F_PROGRAM_FPGA, F_RESET_FPGA, F_CHECK_VERSION,
|
||||
F_REBOOT_CONTROLLER, F_GET_KERNEL_VERSION, F_UPDATE_KERNEL,
|
||||
F_UPDATE_DETECTOR_SERVER, F_GET_UPDATE_MODE, F_SET_UPDATE_MODE,
|
||||
F_GET_NUM_CHANNELS, F_GET_NUM_INTERFACES, F_ACTIVATE};
|
||||
size_t allowedFuncsSize = sizeof(allowedFuncs) / sizeof(enum detFuncs);
|
||||
|
||||
for (unsigned int i = 0; i < allowedFuncsSize; ++i) {
|
||||
if ((unsigned int)fnum == allowedFuncs[i]) {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@ -119,10 +112,12 @@ int printSocketReadError() {
|
||||
}
|
||||
|
||||
void init_detector() {
|
||||
memset(udpDetails, 0, sizeof(udpDetails));
|
||||
#ifdef VIRTUAL
|
||||
LOG(logINFO, ("This is a VIRTUAL detector\n"));
|
||||
udpDetails[0].srcip = LOCALHOSTIP_INT;
|
||||
udpDetails[0].srcip2 = LOCALHOSTIP_INT;
|
||||
#endif
|
||||
memset(udpDetails, 0, sizeof(udpDetails));
|
||||
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
|
||||
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
|
||||
#ifdef EIGERD
|
||||
@ -314,7 +309,6 @@ void function_table() {
|
||||
flist[F_SOFTWARE_TRIGGER] = &software_trigger;
|
||||
flist[F_LED] = &led;
|
||||
flist[F_DIGITAL_IO_DELAY] = &digital_io_delay;
|
||||
flist[F_COPY_DET_SERVER] = ©_detector_server;
|
||||
flist[F_REBOOT_CONTROLLER] = &reboot_controller;
|
||||
flist[F_SET_ADC_ENABLE_MASK] = &set_adc_enable_mask;
|
||||
flist[F_GET_ADC_ENABLE_MASK] = &get_adc_enable_mask;
|
||||
@ -461,6 +455,19 @@ void function_table() {
|
||||
flist[F_UPDATE_DETECTOR_SERVER] = &update_detector_server;
|
||||
flist[F_GET_UPDATE_MODE] = &get_update_mode;
|
||||
flist[F_SET_UPDATE_MODE] = &set_update_mode;
|
||||
flist[F_SET_MASTER] = &set_master;
|
||||
flist[F_GET_TOP] = &get_top;
|
||||
flist[F_SET_TOP] = &set_top;
|
||||
flist[F_GET_POLARITY] = &get_polarity;
|
||||
flist[F_SET_POLARITY] = &set_polarity;
|
||||
flist[F_GET_INTERPOLATION] = &get_interpolation;
|
||||
flist[F_SET_INTERPOLATION] = &set_interpolation;
|
||||
flist[F_GET_PUMP_PROBE] = &get_pump_probe;
|
||||
flist[F_SET_PUMP_PROBE] = &set_pump_probe;
|
||||
flist[F_GET_ANALOG_PULSING] = &get_analog_pulsing;
|
||||
flist[F_SET_ANALOG_PULSING] = &set_analog_pulsing;
|
||||
flist[F_GET_DIGITAL_PULSING] = &get_digital_pulsing;
|
||||
flist[F_SET_DIGITAL_PULSING] = &set_digital_pulsing;
|
||||
|
||||
// check
|
||||
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
||||
@ -2808,6 +2815,9 @@ int set_dynamic_range(int file_des) {
|
||||
#endif
|
||||
#if defined(EIGERD) || defined(MYTHEN3D)
|
||||
case 8:
|
||||
#ifdef EIGERD
|
||||
case 12:
|
||||
#endif
|
||||
case 16:
|
||||
case 32:
|
||||
#endif
|
||||
@ -2815,14 +2825,25 @@ int set_dynamic_range(int file_des) {
|
||||
defined(MOENCHD) || defined(GOTTHARD2D)
|
||||
case 16:
|
||||
#endif
|
||||
retval = setDynamicRange(dr);
|
||||
LOG(logDEBUG1, ("Dynamic range: %d\n", retval));
|
||||
if (retval == -1) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not get dynamic range.\n");
|
||||
LOG(logERROR, (mess));
|
||||
if (dr >= 0) {
|
||||
ret = setDynamicRange(dr);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set dynamic range to %d\n", dr);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
|
||||
// get
|
||||
if (ret == OK) {
|
||||
ret = getDynamicRange(&retval);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not get dynamic range\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
LOG(logDEBUG1, ("Dynamic range: %d\n", retval));
|
||||
validate(&ret, mess, dr, retval, "set dynamic range", DEC);
|
||||
}
|
||||
}
|
||||
validate(&ret, mess, dr, retval, "set dynamic range", DEC);
|
||||
break;
|
||||
default:
|
||||
modeNotImplemented("Dynamic range", dr);
|
||||
@ -2932,7 +2953,7 @@ int enable_ten_giga(int file_des) {
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFOBLUE, ("Setting 10GbE: %d\n", arg));
|
||||
LOG(logDEBUG, ("Setting 10GbE: %d\n", arg));
|
||||
|
||||
#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(GOTTHARD2D)
|
||||
functionNotImplemented();
|
||||
@ -3970,29 +3991,27 @@ int check_version(int file_des) {
|
||||
return printSocketReadError();
|
||||
|
||||
// check software- firmware compatibility and basic tests
|
||||
if (isControlServer) {
|
||||
LOG(logDEBUG1, ("Checking software-firmware compatibility and basic "
|
||||
"test result\n"));
|
||||
LOG(logDEBUG1, ("Checking software-firmware compatibility and basic "
|
||||
"test result\n"));
|
||||
|
||||
// check if firmware check is done
|
||||
// check if firmware check is done
|
||||
if (!isInitCheckDone()) {
|
||||
usleep(3 * 1000 * 1000);
|
||||
if (!isInitCheckDone()) {
|
||||
usleep(3 * 1000 * 1000);
|
||||
if (!isInitCheckDone()) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Firmware Software Compatibility Check (Server "
|
||||
"Initialization) "
|
||||
"still not done done in server. Unexpected.\n");
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Server Initialization still not done done in server. "
|
||||
"Unexpected.\n");
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
// check firmware check result
|
||||
if (ret == OK) {
|
||||
char *firmware_message = NULL;
|
||||
if (getInitResult(&firmware_message) == FAIL) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, firmware_message);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
|
||||
// check firmware check result
|
||||
if (ret == OK) {
|
||||
char *firmware_message = NULL;
|
||||
if (getInitResult(&firmware_message) == FAIL) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, firmware_message);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4120,65 +4139,15 @@ int digital_io_delay(int file_des) {
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int copy_detector_server(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
char args[2][MAX_STR_LENGTH];
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
memset(args, 0, sizeof(args));
|
||||
memset(retvals, 0, sizeof(retvals));
|
||||
|
||||
if (receiveData(file_des, args, sizeof(args), OTHER) < 0)
|
||||
return printSocketReadError();
|
||||
|
||||
#ifdef VIRTUAL
|
||||
functionNotImplemented();
|
||||
#else
|
||||
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
char *sname = args[0];
|
||||
char *hostname = args[1];
|
||||
LOG(logINFOBLUE, ("Copying server %s from host %s\n", sname, hostname));
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
|
||||
#ifdef BLACKFIN_DEFINED
|
||||
// check update is allowed (Non Amd OR AMD + current kernel)
|
||||
ret = allowUpdate(mess, "copy detector server");
|
||||
#endif
|
||||
|
||||
// tftp server
|
||||
if (ret == OK) {
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "tftp %s -r %s -g", hostname,
|
||||
sname) >= MAX_STR_LENGTH) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not copy detector server. Command to copy "
|
||||
"server too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
ret = FAIL;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (tftp). %s\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
} else {
|
||||
LOG(logINFO, ("\tServer copied\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == OK) {
|
||||
ret = setupDetectorServer(mess, sname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, OTHER, retvals, sizeof(retvals));
|
||||
}
|
||||
|
||||
int reboot_controller(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
|
||||
#ifdef EIGERD
|
||||
functionNotImplemented();
|
||||
#elif VIRTUAL
|
||||
ret = GOODBYE;
|
||||
#elif defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
if (getHardwareVersionNumber() == 0) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Old board version, reboot by yourself please!\n");
|
||||
@ -4186,20 +4155,11 @@ int reboot_controller(int file_des) {
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
return GOODBYE;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
ret = GOODBYE;
|
||||
ret = REBOOT;
|
||||
#else
|
||||
ret = REBOOT;
|
||||
#endif
|
||||
#elif EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
#ifdef VIRTUAL
|
||||
ret = GOODBYE;
|
||||
#else
|
||||
ret = REBOOT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
return ret;
|
||||
}
|
||||
@ -4643,11 +4603,17 @@ int set_read_n_rows(int file_des) {
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
#ifdef EIGERD
|
||||
int dr = setDynamicRange(GET_FLAG);
|
||||
int dr = 0;
|
||||
ret = getDynamicRange(&dr);
|
||||
int isTenGiga = enableTenGigabitEthernet(GET_FLAG);
|
||||
unsigned int maxnl = MAX_ROWS_PER_READOUT;
|
||||
unsigned int maxnp = (isTenGiga ? 4 : 16) * dr;
|
||||
if ((arg * maxnp) % maxnl) {
|
||||
// get dr fail
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess,
|
||||
"Could not read n rows (failed to get dynamic range)\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else if ((arg * maxnp) % maxnl) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not set number of rows to %d. For %d bit "
|
||||
@ -4722,7 +4688,7 @@ int get_read_n_rows(int file_des) {
|
||||
}
|
||||
|
||||
void calculate_and_set_position() {
|
||||
if (maxydet == -1 || detectorId == -1) {
|
||||
if (maxYMods == -1 || moduleIndex == -1) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not set detector position (did not get multi size).\n");
|
||||
@ -4731,21 +4697,20 @@ void calculate_and_set_position() {
|
||||
}
|
||||
|
||||
// calculating new position
|
||||
int modulePorts[2] = {1, 1};
|
||||
int pos[2] = {0, 0};
|
||||
|
||||
int portGeometry[2] = {1, 1};
|
||||
// position does change for eiger and jungfrau (2 interfaces)
|
||||
#if defined(EIGERD)
|
||||
modulePorts[1] = getNumberofUDPInterfaces(); // horz
|
||||
portGeometry[X] = getNumberofUDPInterfaces(); // horz
|
||||
#elif defined(JUNGFRAUD)
|
||||
modulePorts[0] = getNumberofUDPInterfaces(); // vert
|
||||
portGeometry[Y] = getNumberofUDPInterfaces(); // vert
|
||||
#endif
|
||||
int maxy = maxydet * modulePorts[0];
|
||||
int pos[2] = {0, 0};
|
||||
// row
|
||||
pos[0] = (detectorId % maxy);
|
||||
// col for horiz. udp ports
|
||||
pos[1] = (detectorId / maxy) * modulePorts[1];
|
||||
|
||||
LOG(logDEBUG, ("Setting Positions (%d,%d)\n", pos[0], pos[1]));
|
||||
LOG(logDEBUG1, ("moduleIndex:%d maxymods:%d portGeo.x:%d portgeo.y:%d\n",
|
||||
moduleIndex, maxYMods, portGeometry[X], portGeometry[Y]));
|
||||
pos[Y] = (moduleIndex % maxYMods) * portGeometry[Y];
|
||||
pos[X] = (moduleIndex / maxYMods) * portGeometry[X];
|
||||
LOG(logINFO, ("Setting Positions (%d,%d) #(col, row)\n", pos[X], pos[Y]));
|
||||
if (setDetectorPosition(pos) == FAIL) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not set detector position.\n");
|
||||
@ -4757,8 +4722,8 @@ void calculate_and_set_position() {
|
||||
if (udpDetails[0].srcmac == 0) {
|
||||
char dmac[MAC_ADDRESS_SIZE];
|
||||
memset(dmac, 0, MAC_ADDRESS_SIZE);
|
||||
sprintf(dmac, "aa:bb:cc:dd:%02x:%02x", pos[0] & 0xFF,
|
||||
pos[1] & 0xFF);
|
||||
sprintf(dmac, "aa:bb:cc:dd:%02x:%02x", pos[X] & 0xFF,
|
||||
pos[Y] & 0xFF);
|
||||
LOG(logINFO, ("Udp source mac address created: %s\n", dmac));
|
||||
unsigned char a[6];
|
||||
sscanf(dmac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &a[0], &a[1], &a[2],
|
||||
@ -4777,8 +4742,8 @@ void calculate_and_set_position() {
|
||||
if (udpDetails[0].srcmac2 == 0) {
|
||||
char dmac2[MAC_ADDRESS_SIZE];
|
||||
memset(dmac2, 0, MAC_ADDRESS_SIZE);
|
||||
sprintf(dmac2, "aa:bb:cc:dd:%02x:%02x", (pos[0] + 1) & 0xFF,
|
||||
pos[1] & 0xFF);
|
||||
sprintf(dmac2, "aa:bb:cc:dd:%02x:%02x", (pos[X] + 1) & 0xFF,
|
||||
pos[Y] & 0xFF);
|
||||
LOG(logINFO, ("Udp source mac address2 created: %s\n", dmac2));
|
||||
unsigned char a[6];
|
||||
sscanf(dmac2, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &a[0], &a[1],
|
||||
@ -4806,15 +4771,16 @@ int set_detector_position(int file_des) {
|
||||
|
||||
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("Setting detector positions: [%u, %u]\n", args[0], args[1]));
|
||||
LOG(logDEBUG, ("Setting detector positions: [maxy:%u, modIndex:%u]\n",
|
||||
args[0], args[1]));
|
||||
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
// if in update mode, there is no need to do this (also detector not set
|
||||
// up)
|
||||
if (!updateFlag && check_detector_idle("configure mac") == OK) {
|
||||
maxydet = args[0];
|
||||
detectorId = args[1];
|
||||
maxYMods = args[0];
|
||||
moduleIndex = args[1];
|
||||
calculate_and_set_position();
|
||||
}
|
||||
}
|
||||
@ -4855,12 +4821,15 @@ int is_udp_configured() {
|
||||
LOG(logWARNING, ("%s", configureMessage));
|
||||
return FAIL;
|
||||
}
|
||||
// virtual: no check (can be eth name: lo, ip: 127.0.0.1)
|
||||
#ifndef VIRTUAL
|
||||
if (udpDetails[i].dstmac == 0) {
|
||||
sprintf(configureMessage,
|
||||
"udp destination mac not configured [entry:%d]\n", i);
|
||||
LOG(logWARNING, ("%s", configureMessage));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
#if defined(JUNGFRAUD) || defined(GOTTHARD2D)
|
||||
if (getNumberofUDPInterfaces() == 2) {
|
||||
if (udpDetails[i].srcip2 == 0) {
|
||||
@ -4881,12 +4850,14 @@ int is_udp_configured() {
|
||||
LOG(logWARNING, ("%s", configureMessage));
|
||||
return FAIL;
|
||||
}
|
||||
#ifndef VIRTUAL
|
||||
if (udpDetails[i].dstmac2 == 0) {
|
||||
sprintf(configureMessage,
|
||||
"udp destination mac2 not configured [entry:%d]\n", i);
|
||||
LOG(logWARNING, ("%s", configureMessage));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -7100,7 +7071,10 @@ int get_receiver_parameters(int file_des) {
|
||||
}
|
||||
|
||||
// dynamic range
|
||||
i32 = setDynamicRange(GET_FLAG);
|
||||
ret = getDynamicRange(&i32);
|
||||
if (ret == FAIL) {
|
||||
i32 = 0;
|
||||
}
|
||||
n += sendData(file_des, &i32, sizeof(i32), INT32);
|
||||
if (n < 0)
|
||||
return printSocketReadError();
|
||||
@ -8182,14 +8156,60 @@ int get_master(int file_des) {
|
||||
|
||||
LOG(logDEBUG1, ("Getting master\n"));
|
||||
|
||||
#if !defined(MYTHEN3D) && !defined(EIGERD) && !defined(GOTTHARDD)
|
||||
#if !defined(MYTHEN3D) && !defined(EIGERD) && !defined(GOTTHARDD) && \
|
||||
!defined(GOTTHARD2D)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
retval = isMaster();
|
||||
ret = isMaster(&retval);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not get master\n");
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_master(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = -1;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting master: %u\n", (int)arg));
|
||||
|
||||
#ifndef EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
if ((check_detector_idle("set master") == OK) &&
|
||||
(arg != 0 && arg != 1)) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not set master. Invalid argument %d.\n", arg);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
ret = setMaster(arg == 1 ? OW_MASTER : OW_SLAVE);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not set master\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = 0;
|
||||
ret = isMaster(&retval);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not get master\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
LOG(logDEBUG1, ("master retval: %u\n", retval));
|
||||
validate(&ret, mess, arg, retval, "set master", DEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_csr(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
@ -8214,33 +8234,35 @@ int set_gain_caps(int file_des) {
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting gain caps to: %u\n", arg));
|
||||
|
||||
int retval = -1;
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
if (Server_VerifyLock() == OK) {
|
||||
setGainCaps(arg);
|
||||
retval = getChipStatusRegister(); // TODO! fix
|
||||
LOG(logDEBUG1, ("gain caps retval: %u\n", retval));
|
||||
ret = setGainCaps(arg);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not set gain caps.\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getGainCaps();
|
||||
validate(&ret, mess, (int)arg, (int)retval, "set gain caps", DEC);
|
||||
LOG(logDEBUG1, ("gain caps retval: %u\n", retval));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_gain_caps(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
LOG(logINFO, ("Getting gain caps\n"));
|
||||
LOG(logDEBUG1, ("Getting gain caps\n"));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
if (Server_VerifyLock() == OK) {
|
||||
retval = getGainCaps();
|
||||
LOG(logDEBUG1, ("Gain caps: %u\n", retval));
|
||||
}
|
||||
retval = getGainCaps();
|
||||
LOG(logDEBUG1, ("Gain caps: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
@ -9361,6 +9383,23 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) {
|
||||
LOG(logINFO, ("\tServer Name: %s\n", serverName));
|
||||
}
|
||||
|
||||
#if !defined(GOTTHARD2D) && !defined(MYTHEN3D) && !defined(EIGERD)
|
||||
int forceDeleteNormalFile = 0;
|
||||
if (receiveData(file_des, &forceDeleteNormalFile,
|
||||
sizeof(forceDeleteNormalFile), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("\tForce Delete Normal File flag? %s\n",
|
||||
(forceDeleteNormalFile ? "Y" : "N")));
|
||||
#endif
|
||||
|
||||
// ensure the name is not the same as the linked name
|
||||
if (!strcmp(serverName, LINKED_SERVER_NAME)) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Server name is the same as the symbolic link. Please "
|
||||
"use a different server name\n");
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
|
||||
// in same folder as current process (will also work for virtual then
|
||||
// with write permissions)
|
||||
{
|
||||
@ -9385,7 +9424,8 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) {
|
||||
checksum, serverName);
|
||||
#else
|
||||
receive_program_via_blackfin(file_des, index, functionType,
|
||||
filesize, checksum, serverName);
|
||||
filesize, checksum, serverName,
|
||||
forceDeleteNormalFile);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -9401,7 +9441,8 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) {
|
||||
|
||||
void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
|
||||
char *functionType, uint64_t filesize,
|
||||
char *checksum, char *serverName) {
|
||||
char *checksum, char *serverName,
|
||||
int forceDeleteNormalFile) {
|
||||
|
||||
#if !defined(JUNGFRAUD) && !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && \
|
||||
!defined(GOTTHARDD)
|
||||
@ -9500,9 +9541,11 @@ void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
|
||||
case PROGRAM_FPGA:
|
||||
case PROGRAM_KERNEL:
|
||||
ret = eraseAndWriteToFlash(mess, index, functionType, checksum,
|
||||
totalsize);
|
||||
totalsize, forceDeleteNormalFile);
|
||||
break;
|
||||
case PROGRAM_SERVER:
|
||||
// a fail here is not a show stopper (just for memory)
|
||||
deleteOldServers(mess, serverName, "update detector server");
|
||||
ret = moveBinaryFile(mess, serverName, TEMP_PROG_FILE_NAME,
|
||||
"update detector server");
|
||||
if (ret == OK) {
|
||||
@ -9664,3 +9707,311 @@ int set_update_mode(int file_des) {
|
||||
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_top(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
LOG(logDEBUG1, ("Getting top\n"));
|
||||
|
||||
#ifndef EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
ret = isTop(&retval);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not get Top\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
LOG(logDEBUG1, ("retval top: %d\n", retval));
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_top(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = -1;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting top : %u\n", arg));
|
||||
|
||||
#ifndef EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
if (arg != 0 && arg != 1) {
|
||||
ret = FAIL;
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not set top mode. Invalid value: %d. Must be 0 or 1\n",
|
||||
arg);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
ret = setTop(arg == 1 ? OW_TOP : OW_BOTTOM);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set %s\n",
|
||||
(arg == 1 ? "Top" : "Bottom"));
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = -1;
|
||||
ret = isTop(&retval);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not get Top mode\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
LOG(logDEBUG1, ("retval top: %d\n", retval));
|
||||
validate(&ret, mess, arg, retval, "set top mode", DEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_polarity(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
enum polarity retval = POSITIVE;
|
||||
|
||||
LOG(logDEBUG1, ("Getting negativepolarity\n"));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
retval = getNegativePolarity() ? NEGATIVE : POSITIVE;
|
||||
LOG(logDEBUG1, ("negative polarity retval: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_polarity(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
enum polarity arg = POSITIVE;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting negative polarity: %u\n", (int)arg));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
switch (arg) {
|
||||
case POSITIVE:
|
||||
ret = setNegativePolarity(0);
|
||||
break;
|
||||
case NEGATIVE:
|
||||
ret = setNegativePolarity(1);
|
||||
break;
|
||||
default:
|
||||
modeNotImplemented("Polarity index", (int)arg);
|
||||
break;
|
||||
}
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set polarity\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
enum polarity retval = getNegativePolarity() ? NEGATIVE : POSITIVE;
|
||||
validate(&ret, mess, (int)arg, (int)retval, "set polarity", DEC);
|
||||
LOG(logDEBUG1, ("negative polarity retval: %u\n", retval));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_interpolation(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
|
||||
LOG(logDEBUG1, ("Getting interpolation\n"));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
retval = getInterpolation();
|
||||
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_interpolation(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = 0;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("Setting interpolation: %u\n", arg));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
ret = setInterpolation(arg);
|
||||
if (ret == FAIL) {
|
||||
if (arg)
|
||||
sprintf(mess, "Could not set interpolation or enable all "
|
||||
"counters for it.\n");
|
||||
else
|
||||
sprintf(mess, "Could not set interpolation\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getInterpolation();
|
||||
validate(&ret, mess, (int)arg, (int)retval, "set interpolation",
|
||||
DEC);
|
||||
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_pump_probe(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
|
||||
LOG(logDEBUG1, ("Getting pump probe\n"));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
retval = getPumpProbe();
|
||||
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_pump_probe(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = 0;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("Setting pump probe: %u\n", arg));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
ret = setPumpProbe(arg);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set pump probe\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getPumpProbe();
|
||||
validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC);
|
||||
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_analog_pulsing(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
|
||||
LOG(logDEBUG1, ("Getting analog pulsing\n"));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
retval = getAnalogPulsing();
|
||||
LOG(logDEBUG1, ("analog pulsing retval: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_analog_pulsing(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = 0;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("Setting analog pulsing: %u\n", arg));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
ret = setAnalogPulsing(arg);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set analog pulsing\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getAnalogPulsing();
|
||||
validate(&ret, mess, (int)arg, (int)retval, "set analog pulsing",
|
||||
DEC);
|
||||
LOG(logDEBUG1, ("analog pulsing retval: %u\n", retval));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
int get_digital_pulsing(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
|
||||
LOG(logDEBUG1, ("Getting digital pulsing\n"));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
retval = getDigitalPulsing();
|
||||
LOG(logDEBUG1, ("digital pulsing retval: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_digital_pulsing(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = 0;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("Setting digital pulsing: %u\n", arg));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
ret = setDigitalPulsing(arg);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set digital pulsing\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getDigitalPulsing();
|
||||
validate(&ret, mess, (int)arg, (int)retval, "set digital pulsing",
|
||||
DEC);
|
||||
LOG(logDEBUG1, ("digital pulsing retval: %u\n", retval));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
@ -7,6 +7,7 @@ set(SOURCES
|
||||
src/CmdProxy.cpp
|
||||
src/CmdParser.cpp
|
||||
src/Pattern.cpp
|
||||
src/CtbConfig.cpp
|
||||
)
|
||||
|
||||
add_library(slsDetectorObject OBJECT
|
||||
@ -16,6 +17,8 @@ add_library(slsDetectorObject OBJECT
|
||||
target_include_directories(slsDetectorObject PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
PRIVATE
|
||||
${SLS_INTERNAL_RAPIDJSON_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(slsDetectorObject
|
||||
|
@ -193,6 +193,12 @@ class Detector {
|
||||
*/
|
||||
void setFlipRows(bool value, Positions pos = {});
|
||||
|
||||
/** [Eiger][Mythen3][Gotthard1] via stop server **/
|
||||
Result<bool> getMaster(Positions pos = {}) const;
|
||||
|
||||
/** [Eiger] Set half module to master and the others to slaves */
|
||||
void setMaster(bool value, int pos);
|
||||
|
||||
Result<bool> isVirtualDetectorServer(Positions pos = {}) const;
|
||||
///@}
|
||||
|
||||
@ -284,7 +290,7 @@ class Detector {
|
||||
Result<int> getDynamicRange(Positions pos = {}) const;
|
||||
|
||||
/**
|
||||
* [Eiger] Options: 4, 8, 16, 32. If i is 32, also sets clkdivider to 2,
|
||||
* [Eiger] Options: 4, 8, 12, 16, 32. If i is 32, also sets clkdivider to 2,
|
||||
* else sets clkdivider to 1 \n [Mythen3] Options: 8, 16, 32 \n
|
||||
* [Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16
|
||||
*/
|
||||
@ -567,7 +573,7 @@ class Detector {
|
||||
/** Non blocking: start detector acquisition. Status changes to RUNNING or
|
||||
* WAITING and automatically returns to idle at the end of acquisition.
|
||||
[Mythen3] Master starts acquisition first */
|
||||
void startDetector();
|
||||
void startDetector(Positions pos = {});
|
||||
|
||||
/** [Mythen3] Non blocking: start detector readout of counters in chip.
|
||||
* Status changes to TRANSMITTING and automatically returns to idle at the
|
||||
@ -586,13 +592,16 @@ class Detector {
|
||||
/** Options: IDLE, TRANSMITTING, RUNNING */
|
||||
Result<defs::runStatus> getReceiverStatus(Positions pos = {}) const;
|
||||
|
||||
Result<int64_t> getFramesCaught(Positions pos = {}) const;
|
||||
/** Gets the number of frames caught for each port in receiver. */
|
||||
Result<std::vector<int64_t>> getFramesCaught(Positions pos = {}) const;
|
||||
|
||||
/** Gets the number of missing packets for each port in receiver.
|
||||
* Troubleshoot: If they are large numbers, convert it to signed to get
|
||||
* number of access packets received */
|
||||
Result<std::vector<uint64_t>>
|
||||
getNumMissingPackets(Positions pos = {}) const;
|
||||
/** Gets the number of missing packets for each port in receiver. Negative
|
||||
* number denotes extra packets. */
|
||||
Result<std::vector<int64_t>> getNumMissingPackets(Positions pos = {}) const;
|
||||
|
||||
/** Gets frame index for each port in receiver. */
|
||||
Result<std::vector<int64_t>>
|
||||
getRxCurrentFrameIndex(Positions pos = {}) const;
|
||||
|
||||
/** [Eiger][Jungfrau][Moench][CTB] */
|
||||
Result<uint64_t> getNextFrameNumber(Positions pos = {}) const;
|
||||
@ -878,10 +887,18 @@ class Detector {
|
||||
Result<sls::IpAddr> getRxLastClientIP(Positions pos = {}) const;
|
||||
|
||||
/** Get thread ids from the receiver in order of [parent, tcp, listener 0,
|
||||
* processor 0, streamer 0, listener 1, processor 1, streamer 1]. If no
|
||||
* streamer yet or there is no second interface, it gives 0 in its place. */
|
||||
* processor 0, streamer 0, listener 1, processor 1, streamer 1, arping]. If
|
||||
* no streamer yet or there is no second interface, it gives 0 in its place.
|
||||
*/
|
||||
Result<std::array<pid_t, NUM_RX_THREAD_IDS>>
|
||||
getRxThreadIds(Positions pos = {}) const;
|
||||
|
||||
Result<bool> getRxArping(Positions pos = {}) const;
|
||||
|
||||
/** Starts a thread in slsReceiver to arping the interface it is listening
|
||||
* every minute. Useful in 10G mode. */
|
||||
void setRxArping(bool value, Positions pos = {});
|
||||
|
||||
///@}
|
||||
|
||||
/** @name File */
|
||||
@ -1139,12 +1156,18 @@ class Detector {
|
||||
Result<bool> getDataStream(const defs::portPosition port,
|
||||
Positions pos = {}) const;
|
||||
|
||||
/** [Eiger] enable or disable data streaming from left or right of detector.
|
||||
* Default: enabled
|
||||
/** [Eiger] enable or disable data streaming from left or right of detector
|
||||
* for 10GbE. Default: enabled
|
||||
*/
|
||||
void setDataStream(const defs::portPosition port, const bool enable,
|
||||
Positions pos = {});
|
||||
|
||||
/** [Eiger] Advanced */
|
||||
Result<bool> getTop(Positions pos = {}) const;
|
||||
|
||||
/** [Eiger] Advanced. Default is hardware default */
|
||||
void setTop(bool value, Positions pos = {});
|
||||
|
||||
///@}
|
||||
|
||||
/** @name Jungfrau Specific */
|
||||
@ -1442,9 +1465,6 @@ class Detector {
|
||||
* (internal gating). Gate index: 0-2, -1 for all */
|
||||
Result<std::array<ns, 3>> getGateDelayForAllGates(Positions pos = {}) const;
|
||||
|
||||
/** [Eiger][Mythen3][Gotthard1] via stop server **/
|
||||
Result<bool> getMaster(Positions pos = {}) const;
|
||||
|
||||
// TODO! check if we really want to expose this !!!!!
|
||||
Result<int> getChipStatusRegister(Positions pos = {}) const;
|
||||
|
||||
@ -1452,6 +1472,36 @@ class Detector {
|
||||
|
||||
Result<int> getGainCaps(Positions pos = {});
|
||||
|
||||
/** [Mythen3] */
|
||||
Result<defs::polarity> getPolarity(Positions pos = {}) const;
|
||||
|
||||
/** [Mythen3] */
|
||||
void setPolarity(defs::polarity value, Positions pos = {});
|
||||
|
||||
/** [Mythen3] */
|
||||
Result<bool> getInterpolation(Positions pos = {}) const;
|
||||
|
||||
/** [Mythen3] Also enables all counters */
|
||||
void setInterpolation(bool value, Positions pos = {});
|
||||
|
||||
/** [Mythen3] */
|
||||
Result<bool> getPumpProbe(Positions pos = {}) const;
|
||||
|
||||
/** [Mythen3] */
|
||||
void setPumpProbe(bool value, Positions pos = {});
|
||||
|
||||
/** [Mythen3] */
|
||||
Result<bool> getAnalogPulsing(Positions pos = {}) const;
|
||||
|
||||
/** [Mythen3] */
|
||||
void setAnalogPulsing(bool value, Positions pos = {});
|
||||
|
||||
/** [Mythen3] */
|
||||
Result<bool> getDigitalPulsing(Positions pos = {}) const;
|
||||
|
||||
/** [Mythen3] */
|
||||
void setDigitalPulsing(bool value, Positions pos = {});
|
||||
|
||||
///@}
|
||||
|
||||
/** @name CTB / Moench Specific */
|
||||
@ -1593,6 +1643,13 @@ class Detector {
|
||||
|
||||
/** [CTB] Default is enabled. */
|
||||
void setLEDEnable(bool enable, Positions pos = {});
|
||||
|
||||
void setDacNames(const std::vector<std::string> names);
|
||||
|
||||
std::vector<std::string> getDacNames() const;
|
||||
|
||||
defs::dacIndex getDacIndex(const std::string &name);
|
||||
std::string getDacName(defs::dacIndex i);
|
||||
///@}
|
||||
|
||||
/** @name Pattern */
|
||||
@ -1727,31 +1784,22 @@ class Detector {
|
||||
/** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2]
|
||||
* Advanced user Function!
|
||||
* Program firmware from command line, after which detector controller is
|
||||
* rebooted. [Jungfrau][CTB][Moench] fname is a pof file (full path) \n
|
||||
* [Mythen3][Gotthard2] fname is an rbf file (full path)
|
||||
* rebooted. forceDeleteNormalFile is true, if normal file found
|
||||
* in device tree, it must be deleted, a new device drive created and
|
||||
* programming continued.[Jungfrau][CTB][Moench] fname is a pof file (full
|
||||
* path) \n [Mythen3][Gotthard2] fname is an rbf file (full path)
|
||||
*/
|
||||
void programFPGA(const std::string &fname, Positions pos = {});
|
||||
void programFPGA(const std::string &fname, const bool forceDeleteNormalFile,
|
||||
Positions pos = {});
|
||||
|
||||
/** [Jungfrau][CTB][Moench] Advanced user Function! */
|
||||
void resetFPGA(Positions pos = {});
|
||||
|
||||
/** [[deprecated ("Replaced by updateDetectorServer, which does not require
|
||||
* tftp")]] [Jungfrau][Eiger][Gotthard][CTB][Moench][Mythen3][Gotthard2]
|
||||
* Advanced user Function! \n
|
||||
* Copy detector server fname from tftp folder of hostname to detector. Also
|
||||
* creates a symbolic link to a shorter name (without vx.x.x). Then the
|
||||
* detector controller reboots (except eiger) \n
|
||||
* [Jungfrau][Gotthard][CTB][Moench] Also changes respawn server (to the
|
||||
* link), which is effective after a reboot.
|
||||
*/
|
||||
void copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname, Positions pos = {});
|
||||
|
||||
/** [Jungfrau][Eiger][Ctb][Moench][Mythen3][Gotthard2] Copies detector
|
||||
* server via TCP (without tftp).\nMakes a symbolic link with a shorter
|
||||
* name (without vx.x.x).\nThen, detector controller reboots (except
|
||||
* Eiger).\n[Jungfrau][Ctb][Moench]Also changes respawn server to the
|
||||
* link, which is effective after a reboot.
|
||||
* Eiger).\n[Jungfrau][Ctb][Moench] Also deletes old server binary and
|
||||
* changes respawn server to the link, which is effective after a reboot.
|
||||
*/
|
||||
void updateDetectorServer(const std::string &fname, Positions pos = {});
|
||||
|
||||
@ -1766,19 +1814,6 @@ class Detector {
|
||||
* Function! */
|
||||
void rebootController(Positions pos = {});
|
||||
|
||||
/** [[deprecated ("Replaced by overloaded updateDetectorServer, which does
|
||||
* not require tftp and has one less argument")]] Advanced user Function!\n
|
||||
* [Jungfrau][Gotthard][CTB][Moench] Updates the firmware, detector server,
|
||||
* make a soft link and then reboots detector controller. \n
|
||||
* [Mythen3][Gotthard2] Will require a script to start up the shorter named
|
||||
* server link at start up \n sname is name of detector server binary found
|
||||
* on tftp folder of host pc \n hostname is name of pc to tftp from \n fname
|
||||
* is programming file name with full path to it
|
||||
*/
|
||||
void updateFirmwareAndServer(const std::string &sname,
|
||||
const std::string &hostname,
|
||||
const std::string &fname, Positions pos = {});
|
||||
|
||||
/**
|
||||
* Advanced user Function!\n [Jungfrau][Gotthard][CTB][Moench] Updates the
|
||||
* firmware, detector server, make a soft link and then reboots detector
|
||||
@ -1896,7 +1931,6 @@ class Detector {
|
||||
*/
|
||||
std::string getUserDetails() const;
|
||||
|
||||
Result<uint64_t> getRxCurrentFrameIndex(Positions pos = {}) const;
|
||||
///@}
|
||||
|
||||
private:
|
||||
|
@ -1057,27 +1057,38 @@ std::string CmdProxy::Dac(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
|
||||
// dac indices only for ctb
|
||||
if (args.size() > 0 && action != defs::HELP_ACTION) {
|
||||
if (is_int(args[0]) &&
|
||||
det->getDetectorType().squash() != defs::CHIPTESTBOARD) {
|
||||
throw sls::RuntimeError(
|
||||
"Dac indices can only be used for chip test board. Use daclist "
|
||||
"to get list of dac names for current detector.");
|
||||
}
|
||||
}
|
||||
|
||||
if (action == defs::HELP_ACTION) {
|
||||
if (args.size() == 0) {
|
||||
os << GetHelpDac(std::to_string(0)) << '\n';
|
||||
} else {
|
||||
os << args[0] << ' ' << GetHelpDac(args[0]) << '\n';
|
||||
}
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
auto type = det->getDetectorType().squash();
|
||||
|
||||
// dac indices only for ctb
|
||||
if (args.size() > 0 && action != defs::HELP_ACTION) {
|
||||
if (is_int(args[0]) && type != defs::CHIPTESTBOARD) {
|
||||
throw sls::RuntimeError(
|
||||
"Dac indices can only be used for chip test board. Use daclist "
|
||||
"to get list of dac names for current detector.");
|
||||
}
|
||||
}
|
||||
|
||||
if (action == defs::GET_ACTION) {
|
||||
if (args.empty())
|
||||
WrongNumberOfParameters(1); // This prints slightly wrong
|
||||
|
||||
defs::dacIndex dacIndex = StringTo<defs::dacIndex>(args[0]);
|
||||
defs::dacIndex dacIndex{};
|
||||
//TODO! Remove if
|
||||
if (type == defs::CHIPTESTBOARD && !is_int(args[0])) {
|
||||
dacIndex = det->getDacIndex(args[0]);
|
||||
} else {
|
||||
dacIndex = StringTo<defs::dacIndex>(args[0]);
|
||||
}
|
||||
|
||||
bool mV = false;
|
||||
|
||||
if (args.size() == 2) {
|
||||
@ -1095,7 +1106,11 @@ std::string CmdProxy::Dac(int action) {
|
||||
if (args.empty())
|
||||
WrongNumberOfParameters(1); // This prints slightly wrong
|
||||
|
||||
defs::dacIndex dacIndex = StringTo<defs::dacIndex>(args[0]);
|
||||
defs::dacIndex dacIndex{};
|
||||
if (type == defs::CHIPTESTBOARD && !is_int(args[0]))
|
||||
dacIndex = det->getDacIndex(args[0]);
|
||||
else
|
||||
dacIndex = StringTo<defs::dacIndex>(args[0]);
|
||||
bool mV = false;
|
||||
if (args.size() == 3) {
|
||||
if ((args[2] != "mv") && (args[2] != "mV")) {
|
||||
@ -1115,6 +1130,41 @@ std::string CmdProxy::Dac(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::DacList(const int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << "\n\t[dacname1 dacname2 .. dacname18] \n\t\t[ChipTestBoard] Set "
|
||||
"the list of dac names for this detector.\n\t\t[All] Gets the "
|
||||
"list "
|
||||
"of "
|
||||
"dac names for every dac for this detector."
|
||||
<< '\n';
|
||||
} else if (action == slsDetectorDefs::GET_ACTION) {
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getDacNames();
|
||||
os << sls::ToString(t) << '\n';
|
||||
} else if (action == slsDetectorDefs::PUT_ACTION) {
|
||||
if (det->getDetectorType().squash() != defs::CHIPTESTBOARD) {
|
||||
throw sls::RuntimeError("This detector already has fixed dac "
|
||||
"names. Cannot change them.");
|
||||
}
|
||||
if (det_id != -1) {
|
||||
throw sls::RuntimeError("Cannot configure dacnames at module level");
|
||||
}
|
||||
if (args.size() != 18) {
|
||||
WrongNumberOfParameters(18);
|
||||
}
|
||||
det->setDacNames(args);
|
||||
os << ToString(args) << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::DacValues(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
@ -1134,13 +1184,15 @@ std::string CmdProxy::DacValues(int action) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
auto t = det->getDacList();
|
||||
auto names = det->getDacNames();
|
||||
auto name_it = names.begin();
|
||||
os << '[';
|
||||
auto it = t.cbegin();
|
||||
os << ToString(*it) << ' ';
|
||||
os << ToString(*name_it++) << ' ';
|
||||
os << OutString(det->getDAC(*it++, mv, std::vector<int>{det_id}))
|
||||
<< (!args.empty() ? " mV" : "");
|
||||
while (it != t.cend()) {
|
||||
os << ", " << ToString(*it) << ' ';
|
||||
os << ", " << ToString(*name_it++) << ' ';
|
||||
os << OutString(det->getDAC(*it++, mv, std::vector<int>{det_id}))
|
||||
<< (!args.empty() ? " mV" : "");
|
||||
}
|
||||
@ -1274,40 +1326,6 @@ std::string CmdProxy::DetectorStatus(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::RxMissingPackets(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "Number of missing packets for each port in receiver. If "
|
||||
"negative, they are packets in excess. "
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto mp = det->getNumMissingPackets(std::vector<int>{det_id});
|
||||
/*
|
||||
auto tmp = det->getNumMissingPackets(std::vector<int>{det_id});
|
||||
// convert to signed missing packets (to get excess)
|
||||
Result<std::vector<int64_t>> mp(tmp.size());
|
||||
for (unsigned int i = 0; i < mp.size(); ++i) {
|
||||
mp[i] = static_cast<int64_t>(tmp[i]);
|
||||
}
|
||||
OR
|
||||
Result<std::vector<int64_t>> tmp;
|
||||
for (auto val : tmp) {
|
||||
mp.push_back(static_cast<int64_t>(val));
|
||||
}
|
||||
*/
|
||||
os << OutString(mp) << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
throw sls::RuntimeError("Cannot put");
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::Scan(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
@ -1804,7 +1822,9 @@ std::string CmdProxy::DataStream(int action) {
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[left|right] [0, 1]\n\t[Eiger] Enables or disables data "
|
||||
"streaming from left or/and right side of detector. 1 (enabled) "
|
||||
"streaming from left or/and right side of detector for 10 GbE "
|
||||
"mode. "
|
||||
"1 (enabled) "
|
||||
"by default."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
@ -2864,48 +2884,31 @@ std::string CmdProxy::ProgramFpga(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[fname.pof | fname.rbf (full path)]\n\t[Jungfrau][Ctb][Moench] "
|
||||
"Programs FPGA from pof file (full path). Then, detector "
|
||||
"controller is rebooted \n\t[Mythen3][Gotthard2] Programs FPGA "
|
||||
"from rbf file (full path). Then, detector controller is "
|
||||
"rebooted."
|
||||
os << "[fname.pof | fname.rbf (full "
|
||||
"path)][(opitonal)--force-delete-normal-file]\n\t[Jungfrau][Ctb]["
|
||||
"Moench] Programs FPGA from pof file (full path). Then, detector "
|
||||
"controller is rebooted. \n\t\tUse --force-delete-normal-file "
|
||||
"argument, if normal file found in device tree, it must be "
|
||||
"deleted, a new device drive created and programming "
|
||||
"continued.\n\t[Mythen3][Gotthard2] Programs FPGA from rbf file "
|
||||
"(full path). Then, detector controller is rebooted."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
bool forceDeteleNormalFile = false;
|
||||
if (args.size() == 2) {
|
||||
if (args[1] != "--force-delete-normal-file") {
|
||||
throw sls::RuntimeError(
|
||||
"Could not scan second argument. Did you "
|
||||
"mean --force-delete-normal-file?");
|
||||
}
|
||||
forceDeteleNormalFile = true;
|
||||
} else if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
det->programFPGA(args[0], std::vector<int>{det_id});
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::CopyDetectorServer(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
LOG(logWARNING) << "Deprecated! Replaced by updatedetectorserver that "
|
||||
"requires no tftp.\n";
|
||||
os << "[server_name (in tftp folder)] "
|
||||
"[pc_host_name]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
|
||||
"Gotthard2] Copies detector server via TFTP from pc. Ensure that "
|
||||
"server is in the pc's tftp folder. Makes a symbolic link with a "
|
||||
"shorter name (without vx.x.x). Then, detector controller "
|
||||
"reboots (except "
|
||||
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
|
||||
"to the link, which is effective after a reboot."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
det->copyDetectorServer(args[0], args[1], std::vector<int>{det_id});
|
||||
det->programFPGA(args[0], forceDeteleNormalFile,
|
||||
std::vector<int>{det_id});
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
@ -2969,23 +2972,21 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "\n\tUsing tftp: Deprecated!! [server_name"
|
||||
" (in tftp folder)] [pc_host_name] [fname.pof (incl full path)]"
|
||||
"\n\tWithout tftp: Recommended [server_name (incl fullpath)] "
|
||||
os << "\n\tWithout tftp: [server_name (incl fullpath)] "
|
||||
"[fname.pof (incl full path)] "
|
||||
"This does not use tftp."
|
||||
"\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
|
||||
"firmware, detector server, creates the symbolic link and then "
|
||||
"firmware, detector server, deletes old server, creates the symbolic link and then "
|
||||
"reboots detector controller. \n\t\t[Mythen3][Gotthard2] will "
|
||||
"require a script to start up the shorter named server link at "
|
||||
"start up. \n\t\tsname is full path name of detector server "
|
||||
"start up. \n\t\tserver_name is full path name of detector server "
|
||||
"binary"
|
||||
"\n\t\tfname is full path of programming file"
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 3 && args.size() != 2) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
|
||||
@ -2994,17 +2995,8 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||
args[fpos].find(".rbf") == std::string::npos) {
|
||||
throw sls::RuntimeError("Programming file must be a pof/rbf file.");
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
LOG(logWARNING)
|
||||
<< "Deprecated! Recommend to use same command without tftp (no "
|
||||
"pc name) and using full path to the server binary";
|
||||
det->updateFirmwareAndServer(args[0], args[1], args[2],
|
||||
det->updateFirmwareAndServer(args[0], args[1],
|
||||
std::vector<int>{det_id});
|
||||
} else {
|
||||
det->updateFirmwareAndServer(args[0], args[1],
|
||||
std::vector<int>{det_id});
|
||||
}
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
|
@ -743,7 +743,11 @@ class CmdProxy {
|
||||
|
||||
/* Pattern */
|
||||
/* Moench */
|
||||
|
||||
/* Advanced */
|
||||
{"copydetectorserver", "updatedetectorserver"},
|
||||
|
||||
|
||||
/* Insignificant */
|
||||
{"nframes", "framecounter"},
|
||||
{"now", "runtime"},
|
||||
@ -784,6 +788,7 @@ class CmdProxy {
|
||||
{"trimen", &CmdProxy::TrimEnergies},
|
||||
{"gappixels", &CmdProxy::GapPixels},
|
||||
{"fliprows", &CmdProxy::fliprows},
|
||||
{"master", &CmdProxy::master},
|
||||
|
||||
/* acquisition parameters */
|
||||
{"acquire", &CmdProxy::Acquire},
|
||||
@ -836,7 +841,7 @@ class CmdProxy {
|
||||
|
||||
/* dacs */
|
||||
{"dac", &CmdProxy::Dac},
|
||||
{"daclist", &CmdProxy::daclist},
|
||||
{"daclist", &CmdProxy::DacList},
|
||||
{"dacvalues", &CmdProxy::DacValues},
|
||||
{"resetdacs", &CmdProxy::ResetDacs},
|
||||
{"defaultdac", &CmdProxy::DefaultDac},
|
||||
@ -859,7 +864,8 @@ class CmdProxy {
|
||||
{"rx_status", &CmdProxy::ReceiverStatus},
|
||||
{"status", &CmdProxy::DetectorStatus},
|
||||
{"rx_framescaught", &CmdProxy::rx_framescaught},
|
||||
{"rx_missingpackets", &CmdProxy::RxMissingPackets},
|
||||
{"rx_missingpackets", &CmdProxy::rx_missingpackets},
|
||||
{"rx_frameindex", &CmdProxy::rx_frameindex},
|
||||
{"nextframenumber", &CmdProxy::nextframenumber},
|
||||
{"trigger", &CmdProxy::Trigger},
|
||||
{"scan", &CmdProxy::Scan},
|
||||
@ -903,6 +909,7 @@ class CmdProxy {
|
||||
{"rx_lock", &CmdProxy::rx_lock},
|
||||
{"rx_lastclient", &CmdProxy::rx_lastclient},
|
||||
{"rx_threads", &CmdProxy::rx_threads},
|
||||
{"rx_arping", &CmdProxy::rx_arping},
|
||||
|
||||
/* File */
|
||||
{"fformat", &CmdProxy::fformat},
|
||||
@ -941,6 +948,7 @@ class CmdProxy {
|
||||
{"pulsechip", &CmdProxy::PulseChip},
|
||||
{"quad", &CmdProxy::Quad},
|
||||
{"datastream", &CmdProxy::DataStream},
|
||||
{"top", &CmdProxy::top},
|
||||
|
||||
/* Jungfrau Specific */
|
||||
{"chipversion", &CmdProxy::chipversion},
|
||||
@ -988,6 +996,11 @@ class CmdProxy {
|
||||
{"gatedelay2", &CmdProxy::GateDelay},
|
||||
{"gatedelay3", &CmdProxy::GateDelay},
|
||||
{"gaincaps", &CmdProxy::GainCaps},
|
||||
{"polarity", &CmdProxy::polarity},
|
||||
{"interpolation", &CmdProxy::interpolation},
|
||||
{"pumpprobe", &CmdProxy::pumpprobe},
|
||||
{"apulse", &CmdProxy::apulse},
|
||||
{"dpulse", &CmdProxy::dpulse},
|
||||
|
||||
/* CTB/ Moench Specific */
|
||||
{"samples", &CmdProxy::Samples},
|
||||
@ -1058,7 +1071,6 @@ class CmdProxy {
|
||||
/* Advanced */
|
||||
{"programfpga", &CmdProxy::ProgramFpga},
|
||||
{"resetfpga", &CmdProxy::resetfpga},
|
||||
{"copydetectorserver", &CmdProxy::CopyDetectorServer},
|
||||
{"updatedetectorserver", &CmdProxy::UpdateDetectorServer},
|
||||
{"updatekernel", &CmdProxy::UpdateKernel},
|
||||
{"rebootcontroller", &CmdProxy::rebootcontroller},
|
||||
@ -1083,8 +1095,7 @@ class CmdProxy {
|
||||
{"framecounter", &CmdProxy::framecounter},
|
||||
{"runtime", &CmdProxy::runtime},
|
||||
{"frametime", &CmdProxy::frametime},
|
||||
{"user", &CmdProxy::UserDetails},
|
||||
{"rx_frameindex", &CmdProxy::rx_frameindex}
|
||||
{"user", &CmdProxy::UserDetails}
|
||||
|
||||
};
|
||||
|
||||
@ -1108,7 +1119,6 @@ class CmdProxy {
|
||||
/* acquisition parameters */
|
||||
std::string Acquire(int action);
|
||||
std::string Exptime(int action);
|
||||
std::string DynamicRange(int action);
|
||||
std::string ReadoutSpeed(int action);
|
||||
std::string Adcphase(int action);
|
||||
std::string Dbitphase(int action);
|
||||
@ -1122,6 +1132,7 @@ class CmdProxy {
|
||||
std::string TemperatureValues(int action);
|
||||
/* dacs */
|
||||
std::string Dac(int action);
|
||||
std::string DacList(int action);
|
||||
std::string DacValues(int action);
|
||||
std::string ResetDacs(int action);
|
||||
std::string DefaultDac(int action);
|
||||
@ -1186,7 +1197,6 @@ class CmdProxy {
|
||||
std::string JsonParameter(int action);
|
||||
/* Advanced */
|
||||
std::string ProgramFpga(int action);
|
||||
std::string CopyDetectorServer(int action);
|
||||
std::string UpdateDetectorServer(int action);
|
||||
std::string UpdateKernel(int action);
|
||||
std::string UpdateFirmwareAndDetectorServer(int action);
|
||||
@ -1280,6 +1290,12 @@ class CmdProxy {
|
||||
"interfaces must be set to 2. slsReceiver and slsDetectorGui "
|
||||
"does not handle.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID_GET(
|
||||
master, getMaster, setMaster, StringTo<int>,
|
||||
"[0, 1]\n\t[Eiger] Sets half module to master and "
|
||||
"others to slaves.\n\t[Gotthard][Gotthard2][Mythen3][Eiger] "
|
||||
"Gets if the current module/ half module is master.");
|
||||
|
||||
/* acquisition parameters */
|
||||
|
||||
INTEGER_COMMAND_SET_NOID_GET_ID(
|
||||
@ -1327,7 +1343,7 @@ class CmdProxy {
|
||||
dr, getDynamicRange, setDynamicRange, StringTo<int>,
|
||||
"[value]\n\tDynamic Range or number of bits per "
|
||||
"pixel in detector.\n\t"
|
||||
"[Eiger] Options: 4, 8, 16, 32. If set to 32, also sets "
|
||||
"[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets "
|
||||
"clkdivider to 2, else to 0.\n\t"
|
||||
"[Mythen3] Options: 8, 16, 32\n\t"
|
||||
"[Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16");
|
||||
@ -1457,10 +1473,6 @@ class CmdProxy {
|
||||
|
||||
/* dacs */
|
||||
|
||||
GET_COMMAND_NOID(
|
||||
daclist, getDacList,
|
||||
"\n\tGets the list of commands for every dac for this detector.");
|
||||
|
||||
/* on chip dacs */
|
||||
INTEGER_USER_IND_COMMAND(
|
||||
vchip_comp_fe, getOnChipDAC, setOnChipDAC, StringTo<int>,
|
||||
@ -1515,7 +1527,7 @@ class CmdProxy {
|
||||
"\n\tStops receiver listener for detector data packets and closes "
|
||||
"current data file (if file write enabled).");
|
||||
|
||||
EXECUTE_SET_COMMAND_NOID(
|
||||
EXECUTE_SET_COMMAND(
|
||||
start, startDetector,
|
||||
"\n\tStarts detector acquisition. Status changes to RUNNING or WAITING "
|
||||
"and automatically returns to idle at the end of acquisition. If the "
|
||||
@ -1532,10 +1544,15 @@ class CmdProxy {
|
||||
"to IDLE or STOPPED. Goes to stop server.");
|
||||
|
||||
GET_COMMAND(rx_framescaught, getFramesCaught,
|
||||
"\n\tNumber of frames caught by receiver.");
|
||||
"\n\tNumber of frames caught by each port in receiver.");
|
||||
|
||||
GET_COMMAND(rx_missingpackets, getNumMissingPackets,
|
||||
"\n\tNumber of missing packets for each port in receiver.");
|
||||
"\n\tNumber of missing packets for each port in receiver. If "
|
||||
"negative, they are packets in excess. ");
|
||||
|
||||
GET_COMMAND(rx_frameindex, getRxCurrentFrameIndex,
|
||||
"\n\tCurrent frame index received for each port in receiver "
|
||||
"during acquisition.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
nextframenumber, getNextFrameNumber, setNextFrameNumber,
|
||||
@ -1738,13 +1755,16 @@ class CmdProxy {
|
||||
rx_lastclient, getRxLastClientIP,
|
||||
"\n\tClient IP Address that last communicated with the receiver.");
|
||||
|
||||
GET_COMMAND(
|
||||
rx_threads, getRxThreadIds,
|
||||
"\n\tGet thread ids from the receiver in order of [parent, tcp, "
|
||||
"listener 0, "
|
||||
"processor 0, streamer 0, listener 1, processor 1, streamer 1]. If no "
|
||||
"streamer yet or there is no second interface, it gives 0 in its "
|
||||
"place.");
|
||||
GET_COMMAND(rx_threads, getRxThreadIds,
|
||||
"\n\tGet thread ids from the receiver in order of [parent, "
|
||||
"tcp, listener 0, processor 0, streamer 0, listener 1, "
|
||||
"processor 1, streamer 1, arping]. If no streamer yet or there "
|
||||
"is no second interface, it gives 0 in its place.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(rx_arping, getRxArping, setRxArping, StringTo<int>,
|
||||
"[0, 1]\n\tStarts a thread in slsReceiver to arping "
|
||||
"the interface it is "
|
||||
"listening to every minute. Useful in 10G mode.");
|
||||
|
||||
/* File */
|
||||
|
||||
@ -1896,6 +1916,10 @@ class CmdProxy {
|
||||
"start of acquisition. 0 complete reset, 1 partial reset. Default is "
|
||||
"complete reset. Advanced function!");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
top, getTop, setTop, StringTo<int>,
|
||||
"[0, 1]\n\t[Eiger] Sets half module to top (1), else bottom.");
|
||||
|
||||
/* Jungfrau Specific */
|
||||
|
||||
GET_COMMAND(chipversion, getChipVersion,
|
||||
@ -2015,6 +2039,31 @@ class CmdProxy {
|
||||
"[n_gates]\n\t[Mythen3] Number of external gates in gating "
|
||||
"or trigger_gating mode (external gating).");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(polarity, getPolarity, setPolarity,
|
||||
StringTo<defs::polarity>,
|
||||
"[pos|neg]\n\t[Mythen3] Sets negative or positive "
|
||||
"polarity. Default is positive");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(interpolation, getInterpolation, setInterpolation,
|
||||
StringTo<int>,
|
||||
"[0, 1]\n\t[Mythen3] Enables or disables "
|
||||
"interpolation. Default is disabled. Enabling also "
|
||||
"enables all counters. ");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(pumpprobe, getPumpProbe, setPumpProbe, StringTo<int>,
|
||||
"[0, 1]\n\t[Mythen3] Enables or disables pump probe "
|
||||
"mode. Default is disabled");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(apulse, getAnalogPulsing, setAnalogPulsing,
|
||||
StringTo<int>,
|
||||
"[0, 1]\n\t[Mythen3] Enables or disables analog "
|
||||
"pulsing. Default is disabled");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(dpulse, getDigitalPulsing, setDigitalPulsing,
|
||||
StringTo<int>,
|
||||
"[0, 1]\n\t[Mythen3] Enables or disables digital "
|
||||
"pulsing. Default is disabled");
|
||||
|
||||
/* CTB/ Moench Specific */
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
@ -2246,10 +2295,6 @@ class CmdProxy {
|
||||
"ns|us|ms|s]\n\t[Jungfrau][Mythen3][Gotthard2][Moench]["
|
||||
"CTB] Timestamp at a frame start."
|
||||
"\n\t[Gotthard2] not in burst and auto mode.");
|
||||
|
||||
GET_COMMAND(
|
||||
rx_frameindex, getRxCurrentFrameIndex,
|
||||
"\n\tCurrent frame index received in receiver during acquisition.");
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
|
72
slsDetectorSoftware/src/CtbConfig.cpp
Normal file
72
slsDetectorSoftware/src/CtbConfig.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
|
||||
#include "CtbConfig.h"
|
||||
#include "SharedMemory.h"
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/string_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace sls {
|
||||
|
||||
CtbConfig::CtbConfig(){
|
||||
for (size_t i=0; i!=num_dacs; ++i){
|
||||
setDacName(i, "dac"+ToString(i));
|
||||
}
|
||||
}
|
||||
|
||||
void CtbConfig::check_index(size_t i) const {
|
||||
if (!(i < num_dacs)) {
|
||||
std::ostringstream oss;
|
||||
oss << "DAC index is too large needs to be below " << num_dacs;
|
||||
throw RuntimeError(oss.str());
|
||||
}
|
||||
}
|
||||
|
||||
void CtbConfig::check_size(const std::string &name) const {
|
||||
|
||||
if (name.empty())
|
||||
throw RuntimeError("Name needs to be at least one character");
|
||||
|
||||
// dacname_length -1 to account for \0 termination
|
||||
if (!(name.size() < (name_length - 1))) {
|
||||
std::ostringstream oss;
|
||||
oss << "Length of name needs to be less than " << name_length - 1
|
||||
<< " chars";
|
||||
throw RuntimeError(oss.str());
|
||||
}
|
||||
}
|
||||
|
||||
void CtbConfig::setDacName(size_t index, const std::string &name) {
|
||||
|
||||
check_index(index);
|
||||
check_size(name);
|
||||
|
||||
char *dst = &dacnames[index * name_length];
|
||||
memset(dst, '\0', name_length);
|
||||
memcpy(dst, &name[0], name.size());
|
||||
}
|
||||
|
||||
void CtbConfig::setDacNames(const std::vector<std::string>& names){
|
||||
for (size_t i = 0; i!=num_dacs; ++i){
|
||||
setDacName(i, names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CtbConfig::getDacName(size_t index) const {
|
||||
return dacnames + index * name_length;
|
||||
}
|
||||
|
||||
std::vector<std::string> CtbConfig::getDacNames() const {
|
||||
std::vector<std::string> names;
|
||||
for (size_t i = 0; i != num_dacs; ++i)
|
||||
names.push_back(getDacName(i));
|
||||
return names;
|
||||
}
|
||||
|
||||
const char* CtbConfig::shm_tag(){
|
||||
return shm_tag_;
|
||||
}
|
||||
|
||||
} // namespace sls
|
31
slsDetectorSoftware/src/CtbConfig.h
Normal file
31
slsDetectorSoftware/src/CtbConfig.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
namespace sls {
|
||||
|
||||
|
||||
class CtbConfig {
|
||||
static constexpr size_t name_length = 20;
|
||||
static constexpr size_t num_dacs = 18;
|
||||
static constexpr const char* shm_tag_ = "ctbdacs";
|
||||
char dacnames[name_length * num_dacs]{};
|
||||
|
||||
void check_index(size_t i) const;
|
||||
void check_size(const std::string &name) const;
|
||||
|
||||
public:
|
||||
CtbConfig();
|
||||
CtbConfig(const CtbConfig&) = default;
|
||||
CtbConfig(CtbConfig&&) = default;
|
||||
CtbConfig& operator=(const CtbConfig&) = default;
|
||||
~CtbConfig() = default;
|
||||
|
||||
void setDacNames(const std::vector<std::string> &names);
|
||||
void setDacName(size_t index, const std::string &name);
|
||||
std::string getDacName(size_t index) const;
|
||||
std::vector<std::string> getDacNames() const;
|
||||
static const char* shm_tag();
|
||||
};
|
||||
|
||||
|
||||
} // namespace sls
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "CmdParser.h"
|
||||
#include "CmdProxy.h"
|
||||
#include "CtbConfig.h"
|
||||
#include "DetectorImpl.h"
|
||||
#include "Module.h"
|
||||
#include "sls/Pattern.h"
|
||||
@ -21,11 +22,12 @@
|
||||
namespace sls {
|
||||
|
||||
void freeSharedMemory(int detectorIndex, int moduleIndex) {
|
||||
|
||||
// single module
|
||||
if (moduleIndex >= 0) {
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, moduleIndex);
|
||||
if (moduleShm.IsExisting()) {
|
||||
moduleShm.RemoveSharedMemory();
|
||||
if (moduleShm.exists()) {
|
||||
moduleShm.removeSharedMemory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -34,16 +36,21 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
|
||||
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
|
||||
int numDetectors = 0;
|
||||
|
||||
if (detectorShm.IsExisting()) {
|
||||
detectorShm.OpenSharedMemory();
|
||||
if (detectorShm.exists()) {
|
||||
detectorShm.openSharedMemory();
|
||||
numDetectors = detectorShm()->numberOfModules;
|
||||
detectorShm.RemoveSharedMemory();
|
||||
detectorShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < numDetectors; ++i) {
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
|
||||
moduleShm.RemoveSharedMemory();
|
||||
moduleShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
// Ctb configuration
|
||||
SharedMemory<CtbConfig> ctbShm(detectorIndex, -1, CtbConfig::shm_tag());
|
||||
if (ctbShm.exists())
|
||||
ctbShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
using defs = slsDetectorDefs;
|
||||
@ -298,6 +305,23 @@ void Detector::setFlipRows(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setFlipRows, pos, value);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getMaster(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::isMaster, pos);
|
||||
}
|
||||
|
||||
void Detector::setMaster(bool master, int pos) {
|
||||
// multi mod, set slaves first
|
||||
if (master && size() > 1) {
|
||||
if (pos == -1) {
|
||||
throw RuntimeError("Master can be set only to a single module");
|
||||
}
|
||||
pimpl->Parallel(&Module::setMaster, {}, false);
|
||||
pimpl->Parallel(&Module::setMaster, {pos}, master);
|
||||
} else {
|
||||
pimpl->Parallel(&Module::setMaster, {pos}, master);
|
||||
}
|
||||
}
|
||||
|
||||
Result<bool> Detector::isVirtualDetectorServer(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::isVirtualDetectorServer, pos);
|
||||
}
|
||||
@ -387,7 +411,7 @@ void Detector::setDynamicRange(int value) {
|
||||
std::vector<int> Detector::getDynamicRangeList() const {
|
||||
switch (getDetectorType().squash()) {
|
||||
case defs::EIGER:
|
||||
return std::vector<int>{4, 8, 16, 32};
|
||||
return std::vector<int>{4, 8, 12, 16, 32};
|
||||
case defs::MYTHEN3:
|
||||
return std::vector<int>{8, 16, 32};
|
||||
default:
|
||||
@ -756,23 +780,8 @@ void Detector::startReceiver() { pimpl->Parallel(&Module::startReceiver, {}); }
|
||||
|
||||
void Detector::stopReceiver() { pimpl->Parallel(&Module::stopReceiver, {}); }
|
||||
|
||||
void Detector::startDetector() {
|
||||
auto detector_type = getDetectorType().squash();
|
||||
if (detector_type == defs::MYTHEN3 && size() > 1) {
|
||||
auto is_master = getMaster();
|
||||
int masterPosition = 0;
|
||||
std::vector<int> slaves;
|
||||
for (int i = 0; i < size(); ++i) {
|
||||
if (is_master[i])
|
||||
masterPosition = i;
|
||||
else
|
||||
slaves.push_back(i);
|
||||
}
|
||||
pimpl->Parallel(&Module::startAcquisition, slaves);
|
||||
pimpl->Parallel(&Module::startAcquisition, {masterPosition});
|
||||
} else {
|
||||
pimpl->Parallel(&Module::startAcquisition, {});
|
||||
}
|
||||
void Detector::startDetector(Positions pos) {
|
||||
pimpl->startAcquisition(false, pos);
|
||||
}
|
||||
|
||||
void Detector::startDetectorReadout() {
|
||||
@ -781,6 +790,25 @@ void Detector::startDetectorReadout() {
|
||||
|
||||
void Detector::stopDetector(Positions pos) {
|
||||
pimpl->Parallel(&Module::stopAcquisition, pos);
|
||||
|
||||
// validate consistent frame numbers
|
||||
switch (getDetectorType().squash()) {
|
||||
case defs::EIGER:
|
||||
case defs::JUNGFRAU:
|
||||
case defs::MOENCH:
|
||||
case defs::CHIPTESTBOARD: {
|
||||
auto res = getNextFrameNumber(pos);
|
||||
if (!res.equal()) {
|
||||
uint64_t maxVal = 0;
|
||||
for (auto it : res) {
|
||||
maxVal = std::max(maxVal, it);
|
||||
}
|
||||
setNextFrameNumber(maxVal + 1);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {
|
||||
@ -791,15 +819,20 @@ Result<defs::runStatus> Detector::getReceiverStatus(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getReceiverStatus, pos);
|
||||
}
|
||||
|
||||
Result<int64_t> Detector::getFramesCaught(Positions pos) const {
|
||||
Result<std::vector<int64_t>> Detector::getFramesCaught(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getFramesCaughtByReceiver, pos);
|
||||
}
|
||||
|
||||
Result<std::vector<uint64_t>>
|
||||
Result<std::vector<int64_t>>
|
||||
Detector::getNumMissingPackets(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getNumMissingPackets, pos);
|
||||
}
|
||||
|
||||
Result<std::vector<int64_t>>
|
||||
Detector::getRxCurrentFrameIndex(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getReceiverCurrentFrameIndex, pos);
|
||||
}
|
||||
|
||||
Result<uint64_t> Detector::getNextFrameNumber(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getNextFrameNumber, pos);
|
||||
}
|
||||
@ -833,7 +866,7 @@ Result<std::string> Detector::getScanErrorMessage(Positions pos) const {
|
||||
|
||||
Result<int> Detector::getNumberofUDPInterfaces(Positions pos) const {
|
||||
// also called by vetostream (for gotthard2)
|
||||
return pimpl->getNumberofUDPInterfaces(pos);
|
||||
return pimpl->Parallel(&Module::getNumberofUDPInterfacesFromShm, pos);
|
||||
}
|
||||
|
||||
void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
|
||||
@ -1170,6 +1203,14 @@ Detector::getRxThreadIds(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getReceiverThreadIds, pos);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getRxArping(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getRxArping, pos);
|
||||
}
|
||||
|
||||
void Detector::setRxArping(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setRxArping, pos, value);
|
||||
}
|
||||
|
||||
// File
|
||||
|
||||
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {
|
||||
@ -1478,6 +1519,14 @@ void Detector::setDataStream(const defs::portPosition port, const bool enable,
|
||||
pimpl->Parallel(&Module::setDataStream, pos, port, enable);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getTop(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getTop, pos);
|
||||
}
|
||||
|
||||
void Detector::setTop(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setTop, pos, value);
|
||||
}
|
||||
|
||||
// Jungfrau Specific
|
||||
Result<double> Detector::getChipVersion(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getChipVersion, pos);
|
||||
@ -1553,7 +1602,6 @@ std::vector<defs::gainMode> Detector::getGainModeList() const {
|
||||
return std::vector<defs::gainMode>{
|
||||
defs::DYNAMIC, defs::FORCE_SWITCH_G1, defs::FORCE_SWITCH_G2,
|
||||
defs::FIX_G1, defs::FIX_G2, defs::FIX_G0};
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Gain mode is not implemented for this detector.");
|
||||
}
|
||||
@ -1686,7 +1734,7 @@ Result<defs::streamingInterface> Detector::getVetoStream(Positions pos) const {
|
||||
// 3gbe
|
||||
auto r3 = pimpl->Parallel(&Module::getVetoStream, pos);
|
||||
// 10gbe (debugging interface) opens 2nd udp interface in receiver
|
||||
auto r10 = pimpl->getNumberofUDPInterfaces(pos);
|
||||
auto r10 = getNumberofUDPInterfaces(pos);
|
||||
|
||||
Result<defs::streamingInterface> res(r3.size());
|
||||
for (unsigned int i = 0; i < res.size(); ++i) {
|
||||
@ -1708,7 +1756,7 @@ void Detector::setVetoStream(defs::streamingInterface interface,
|
||||
pimpl->Parallel(&Module::setVetoStream, pos, LOW_LATENCY_LINK);
|
||||
|
||||
// 10gbe (debugging interface) opens 2nd udp interface in receiver
|
||||
int old_numinterfaces = pimpl->getNumberofUDPInterfaces(pos).tsquash(
|
||||
int old_numinterfaces = getNumberofUDPInterfaces(pos).tsquash(
|
||||
"retrieved inconsistent number of udp interfaces");
|
||||
int numinterfaces =
|
||||
(((interface & defs::streamingInterface::ETHERNET_10GB) ==
|
||||
@ -1798,10 +1846,6 @@ Detector::getGateDelayForAllGates(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getGateDelayForAllGates, pos);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getMaster(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::isMaster, pos);
|
||||
}
|
||||
|
||||
Result<int> Detector::getChipStatusRegister(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getChipStatusRegister, pos);
|
||||
}
|
||||
@ -1814,6 +1858,46 @@ Result<int> Detector::getGainCaps(Positions pos) {
|
||||
return pimpl->Parallel(&Module::getGainCaps, pos);
|
||||
}
|
||||
|
||||
Result<defs::polarity> Detector::getPolarity(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getPolarity, pos);
|
||||
}
|
||||
|
||||
void Detector::setPolarity(defs::polarity value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setPolarity, pos, value);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getInterpolation(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getInterpolation, pos);
|
||||
}
|
||||
|
||||
void Detector::setInterpolation(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setInterpolation, pos, value);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getPumpProbe(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getPumpProbe, pos);
|
||||
}
|
||||
|
||||
void Detector::setPumpProbe(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setPumpProbe, pos, value);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getAnalogPulsing(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getAnalogPulsing, pos);
|
||||
}
|
||||
|
||||
void Detector::setAnalogPulsing(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setAnalogPulsing, pos, value);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getDigitalPulsing(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getDigitalPulsing, pos);
|
||||
}
|
||||
|
||||
void Detector::setDigitalPulsing(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setDigitalPulsing, pos, value);
|
||||
}
|
||||
|
||||
// CTB/ Moench Specific
|
||||
|
||||
Result<int> Detector::getNumberOfAnalogSamples(Positions pos) const {
|
||||
@ -2013,6 +2097,42 @@ void Detector::setLEDEnable(bool enable, Positions pos) {
|
||||
pimpl->Parallel(&Module::setLEDEnable, pos, enable);
|
||||
}
|
||||
|
||||
void Detector::setDacNames(const std::vector<std::string> names) {
|
||||
if (getDetectorType().squash() != defs::CHIPTESTBOARD)
|
||||
throw RuntimeError("Named dacs only for CTB");
|
||||
pimpl->setCtbDacNames(names);
|
||||
}
|
||||
|
||||
std::vector<std::string> Detector::getDacNames() const {
|
||||
std::vector<std::string> names;
|
||||
auto type = getDetectorType().squash();
|
||||
if (type == defs::CHIPTESTBOARD)
|
||||
return pimpl->getCtbDacNames();
|
||||
|
||||
for (const auto &index : getDacList())
|
||||
names.push_back(ToString(index));
|
||||
return names;
|
||||
}
|
||||
|
||||
defs::dacIndex Detector::getDacIndex(const std::string &name) {
|
||||
auto type = getDetectorType().squash();
|
||||
if (type == defs::CHIPTESTBOARD) {
|
||||
auto names = getDacNames();
|
||||
auto it = std::find(names.begin(), names.end(), name);
|
||||
if (it == names.end())
|
||||
throw RuntimeError("Dacname not found");
|
||||
return static_cast<defs::dacIndex>(it - names.begin());
|
||||
}
|
||||
return StringTo<defs::dacIndex>(name);
|
||||
}
|
||||
|
||||
std::string Detector::getDacName(defs::dacIndex i) {
|
||||
auto type = getDetectorType().squash();
|
||||
if (type == defs::CHIPTESTBOARD)
|
||||
return pimpl->getCtbDacName(i);
|
||||
return ToString(i);
|
||||
}
|
||||
|
||||
// Pattern
|
||||
|
||||
void Detector::setPattern(const std::string &fname, Positions pos) {
|
||||
@ -2133,10 +2253,11 @@ void Detector::setAdditionalJsonParameter(const std::string &key,
|
||||
|
||||
// Advanced
|
||||
|
||||
void Detector::programFPGA(const std::string &fname, Positions pos) {
|
||||
void Detector::programFPGA(const std::string &fname,
|
||||
const bool forceDeleteNormalFile, Positions pos) {
|
||||
LOG(logINFO) << "Updating Firmware...";
|
||||
std::vector<char> buffer = pimpl->readProgrammingFile(fname);
|
||||
pimpl->Parallel(&Module::programFPGA, pos, buffer);
|
||||
pimpl->Parallel(&Module::programFPGA, pos, buffer, forceDeleteNormalFile);
|
||||
rebootController(pos);
|
||||
}
|
||||
|
||||
@ -2144,15 +2265,6 @@ void Detector::resetFPGA(Positions pos) {
|
||||
pimpl->Parallel(&Module::resetFPGA, pos);
|
||||
}
|
||||
|
||||
void Detector::copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname, Positions pos) {
|
||||
LOG(logINFO) << "Updating Detector Server (via tftp)...";
|
||||
pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname);
|
||||
if (getDetectorType().squash() != defs::EIGER) {
|
||||
rebootController(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void Detector::updateDetectorServer(const std::string &fname, Positions pos) {
|
||||
LOG(logINFO) << "Updating Detector Server (no tftp)...";
|
||||
std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server");
|
||||
@ -2174,16 +2286,6 @@ void Detector::rebootController(Positions pos) {
|
||||
pimpl->Parallel(&Module::rebootController, pos);
|
||||
}
|
||||
|
||||
void Detector::updateFirmwareAndServer(const std::string &sname,
|
||||
const std::string &hostname,
|
||||
const std::string &fname,
|
||||
Positions pos) {
|
||||
LOG(logINFO) << "Updating Firmware and Detector Server (with tftp)...";
|
||||
LOG(logINFO) << "Updating Detector Server (via tftp)...";
|
||||
pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname);
|
||||
programFPGA(fname, pos);
|
||||
}
|
||||
|
||||
void Detector::updateFirmwareAndServer(const std::string &sname,
|
||||
const std::string &fname,
|
||||
Positions pos) {
|
||||
@ -2192,7 +2294,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname,
|
||||
std::vector<char> buffer = readBinaryFile(sname, "Update Detector Server");
|
||||
std::string filename = sls::getFileNameFromFilePath(sname);
|
||||
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename);
|
||||
programFPGA(fname, pos);
|
||||
programFPGA(fname, false, pos);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getUpdateMode(Positions pos) const {
|
||||
@ -2301,12 +2403,8 @@ Result<ns> Detector::getMeasurementTime(Positions pos) const {
|
||||
|
||||
std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); }
|
||||
|
||||
Result<uint64_t> Detector::getRxCurrentFrameIndex(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getReceiverCurrentFrameIndex, pos);
|
||||
}
|
||||
|
||||
std::vector<int> Detector::getPortNumbers(int start_port) {
|
||||
int num_sockets_per_detector = pimpl->getNumberofUDPInterfaces({}).tsquash(
|
||||
int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash(
|
||||
"Number of UDP Interfaces is not consistent among modules");
|
||||
std::vector<int> res;
|
||||
res.reserve(size());
|
||||
|
@ -32,7 +32,8 @@
|
||||
namespace sls {
|
||||
|
||||
DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update)
|
||||
: detectorIndex(detector_index), shm(detector_index, -1) {
|
||||
: detectorIndex(detector_index), shm(detector_index, -1),
|
||||
ctb_shm(detector_index, -1, CtbConfig::shm_tag()) {
|
||||
setupDetector(verify, update);
|
||||
}
|
||||
|
||||
@ -44,6 +45,9 @@ void DetectorImpl::setupDetector(bool verify, bool update) {
|
||||
if (update) {
|
||||
updateUserdetails();
|
||||
}
|
||||
|
||||
if (ctb_shm.exists())
|
||||
ctb_shm.openSharedMemory();
|
||||
}
|
||||
|
||||
void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
|
||||
@ -54,8 +58,8 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, detPos);
|
||||
if (moduleShm.IsExisting()) {
|
||||
moduleShm.RemoveSharedMemory();
|
||||
if (moduleShm.exists()) {
|
||||
moduleShm.removeSharedMemory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -64,16 +68,20 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
|
||||
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
|
||||
int numModules = 0;
|
||||
|
||||
if (detectorShm.IsExisting()) {
|
||||
detectorShm.OpenSharedMemory();
|
||||
if (detectorShm.exists()) {
|
||||
detectorShm.openSharedMemory();
|
||||
numModules = detectorShm()->numberOfModules;
|
||||
detectorShm.RemoveSharedMemory();
|
||||
detectorShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < numModules; ++i) {
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
|
||||
moduleShm.RemoveSharedMemory();
|
||||
moduleShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
SharedMemory<CtbConfig> ctbShm(detectorIndex, -1, CtbConfig::shm_tag());
|
||||
if (ctbShm.exists())
|
||||
ctbShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
void DetectorImpl::freeSharedMemory() {
|
||||
@ -84,8 +92,11 @@ void DetectorImpl::freeSharedMemory() {
|
||||
modules.clear();
|
||||
|
||||
// clear detector shm
|
||||
shm.RemoveSharedMemory();
|
||||
shm.removeSharedMemory();
|
||||
client_downstream = false;
|
||||
|
||||
if (ctb_shm.exists())
|
||||
ctb_shm.removeSharedMemory();
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getUserDetails() {
|
||||
@ -129,11 +140,11 @@ void DetectorImpl::setInitialChecks(const bool value) {
|
||||
}
|
||||
|
||||
void DetectorImpl::initSharedMemory(bool verify) {
|
||||
if (!shm.IsExisting()) {
|
||||
shm.CreateSharedMemory();
|
||||
if (!shm.exists()) {
|
||||
shm.createSharedMemory();
|
||||
initializeDetectorStructure();
|
||||
} else {
|
||||
shm.OpenSharedMemory();
|
||||
shm.openSharedMemory();
|
||||
if (verify && shm()->shmversion != DETECTOR_SHMVERSION) {
|
||||
LOG(logERROR) << "Detector shared memory (" << detectorIndex
|
||||
<< ") version mismatch "
|
||||
@ -144,6 +155,8 @@ void DetectorImpl::initSharedMemory(bool verify) {
|
||||
throw SharedMemoryError("Shared memory version mismatch!");
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout <<
|
||||
}
|
||||
|
||||
void DetectorImpl::initializeDetectorStructure() {
|
||||
@ -246,13 +259,14 @@ void DetectorImpl::setHostname(const std::vector<std::string> &name) {
|
||||
}
|
||||
updateDetectorSize();
|
||||
|
||||
// update zmq port (especially for eiger)
|
||||
int numInterfaces = modules[0]->getNumberofUDPInterfaces();
|
||||
if (numInterfaces == 2) {
|
||||
for (size_t i = 0; i < modules.size(); ++i) {
|
||||
modules[i]->setClientStreamingPort(DEFAULT_ZMQ_CL_PORTNO +
|
||||
i * numInterfaces);
|
||||
}
|
||||
// Here we know the detector type and can add ctb shared memory
|
||||
// if needed, CTB dac names are only on detector level
|
||||
|
||||
if (shm()->detType == defs::CHIPTESTBOARD) {
|
||||
if (ctb_shm.exists())
|
||||
ctb_shm.openSharedMemory();
|
||||
else
|
||||
ctb_shm.createSharedMemory();
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,6 +295,13 @@ void DetectorImpl::addModule(const std::string &hostname) {
|
||||
|
||||
// get type by connecting
|
||||
detectorType type = Module::getTypeFromDetector(host, port);
|
||||
|
||||
// gotthard cannot have more than 2 modules (50um=1, 25um=2
|
||||
if ((type == GOTTHARD || type == GOTTHARD2) && modules.size() > 2) {
|
||||
freeSharedMemory();
|
||||
throw sls::RuntimeError("Gotthard cannot have more than 2 modules");
|
||||
}
|
||||
|
||||
auto pos = modules.size();
|
||||
modules.emplace_back(
|
||||
sls::make_unique<Module>(type, detectorIndex, pos, false));
|
||||
@ -288,11 +309,20 @@ void DetectorImpl::addModule(const std::string &hostname) {
|
||||
modules[pos]->setControlPort(port);
|
||||
modules[pos]->setStopPort(port + 1);
|
||||
modules[pos]->setHostname(host, shm()->initialChecks);
|
||||
|
||||
// module type updated by now
|
||||
shm()->detType = Parallel(&Module::getDetectorType, {})
|
||||
.tsquash("Inconsistent detector types.");
|
||||
// for moench and ctb
|
||||
modules[pos]->updateNumberOfChannels();
|
||||
|
||||
// for eiger, jungfrau, gotthard2
|
||||
modules[pos]->updateNumberofUDPInterfaces();
|
||||
|
||||
// update zmq port in case numudpinterfaces changed
|
||||
int numInterfaces = modules[pos]->getNumberofUDPInterfacesFromShm();
|
||||
modules[pos]->setClientStreamingPort(DEFAULT_ZMQ_CL_PORTNO +
|
||||
pos * numInterfaces);
|
||||
}
|
||||
|
||||
void DetectorImpl::updateDetectorSize() {
|
||||
@ -572,14 +602,12 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
currentSubFrameIndex = zHeader.expLength;
|
||||
coordY = zHeader.row;
|
||||
coordX = zHeader.column;
|
||||
if (eiger) {
|
||||
coordY = (nY - 1) - coordY;
|
||||
}
|
||||
flipRows = zHeader.flipRows;
|
||||
if (zHeader.completeImage == 0) {
|
||||
completeImage = false;
|
||||
}
|
||||
LOG(logDEBUG1)
|
||||
<< zmqSocket[isocket]->GetPortNumber() << " "
|
||||
<< "Header Info:"
|
||||
"\n\tcurrentFileName: "
|
||||
<< currentFileName << "\n\tcurrentAcquisitionIndex: "
|
||||
@ -1096,25 +1124,7 @@ int DetectorImpl::acquire() {
|
||||
|
||||
// start and read all
|
||||
try {
|
||||
if (detector_type == defs::MYTHEN3 && modules.size() > 1) {
|
||||
// Multi module mythen
|
||||
std::vector<int> master;
|
||||
std::vector<int> slaves;
|
||||
auto is_master = Parallel(&Module::isMaster, {});
|
||||
slaves.reserve(modules.size() - 1); // check this one!!
|
||||
for (size_t i = 0; i < modules.size(); ++i) {
|
||||
if (is_master[i])
|
||||
master.push_back(i);
|
||||
else
|
||||
slaves.push_back(i);
|
||||
}
|
||||
Parallel(&Module::startAcquisition, slaves);
|
||||
Parallel(&Module::startAndReadAll, master);
|
||||
} else {
|
||||
// Normal acquire
|
||||
Parallel(&Module::startAndReadAll, {});
|
||||
}
|
||||
|
||||
startAcquisition(true, {});
|
||||
} catch (...) {
|
||||
if (receiver)
|
||||
Parallel(&Module::stopReceiver, {});
|
||||
@ -1142,7 +1152,7 @@ int DetectorImpl::acquire() {
|
||||
if (acquisition_finished != nullptr) {
|
||||
int status = Parallel(&Module::getRunStatus, {}).squash(ERROR);
|
||||
auto a = Parallel(&Module::getReceiverProgress, {});
|
||||
double progress = (*std::min_element(a.begin(), a.end()));
|
||||
double progress = (*std::max_element(a.begin(), a.end()));
|
||||
acquisition_finished(progress, status, acqFinished_p);
|
||||
}
|
||||
|
||||
@ -1163,6 +1173,44 @@ int DetectorImpl::acquire() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
|
||||
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
|
||||
std::vector<int> master;
|
||||
std::vector<int> slaves;
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(modules.size());
|
||||
std::iota(begin(positions), end(positions), 0);
|
||||
}
|
||||
// could be all slaves in positions
|
||||
slaves.reserve(positions.size());
|
||||
auto is_master = Parallel(&Module::isMaster, positions);
|
||||
for (size_t i : positions) {
|
||||
if (is_master[i])
|
||||
master.push_back(i);
|
||||
else
|
||||
slaves.push_back(i);
|
||||
}
|
||||
|
||||
if (!slaves.empty()) {
|
||||
Parallel(&Module::startAcquisition, slaves);
|
||||
}
|
||||
if (!master.empty()) {
|
||||
if (blocking) {
|
||||
Parallel(&Module::startAndReadAll, master);
|
||||
} else {
|
||||
Parallel(&Module::startAcquisition, master);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (blocking) {
|
||||
Parallel(&Module::startAndReadAll, positions);
|
||||
} else {
|
||||
Parallel(&Module::startAcquisition, positions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorImpl::printProgress(double progress) {
|
||||
// spaces for python printout
|
||||
std::cout << " " << std::fixed << std::setprecision(2) << std::setw(6)
|
||||
@ -1258,8 +1306,13 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
throw RuntimeError("Programming file must be an rbf file.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case EIGER:
|
||||
case GOTTHARD:
|
||||
throw RuntimeError("programfpga not implemented for this detector");
|
||||
default:
|
||||
throw RuntimeError(
|
||||
"Unknown detector type. Did the 'hostname' command execute "
|
||||
"successfully? Or use update mode in the detector server side.");
|
||||
}
|
||||
|
||||
LOG(logINFO) << "This can take awhile. Please be patient.";
|
||||
@ -1361,10 +1414,6 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
sls::Result<int> DetectorImpl::getNumberofUDPInterfaces(Positions pos) const {
|
||||
return Parallel(&Module::getNumberofUDPInterfaces, pos);
|
||||
}
|
||||
|
||||
sls::Result<int> DetectorImpl::getDefaultDac(defs::dacIndex index,
|
||||
defs::detectorSettings sett,
|
||||
Positions pos) {
|
||||
@ -1376,4 +1425,16 @@ void DetectorImpl::setDefaultDac(defs::dacIndex index, int defaultValue,
|
||||
Parallel(&Module::setDefaultDac, pos, index, defaultValue, sett);
|
||||
}
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbDacNames() const {
|
||||
return ctb_shm()->getDacNames();
|
||||
}
|
||||
|
||||
void DetectorImpl::setCtbDacNames(const std::vector<std::string> &names) {
|
||||
ctb_shm()->setDacNames(names);
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getCtbDacName(defs::dacIndex i) const {
|
||||
return ctb_shm()->getDacName(static_cast<int>(i));
|
||||
}
|
||||
|
||||
} // namespace sls
|
@ -7,6 +7,8 @@
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
|
||||
#include "CtbConfig.h"
|
||||
class ZmqSocket;
|
||||
class detectorData;
|
||||
|
||||
@ -276,6 +278,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int acquire();
|
||||
|
||||
/** also takes care of master and slave for multi module mythen */
|
||||
void startAcquisition(bool blocking, std::vector<int> positions);
|
||||
|
||||
/**
|
||||
* Combines data from all readouts and gives it to the gui
|
||||
* or just gives progress of acquisition by polling receivers
|
||||
@ -291,7 +296,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
*/
|
||||
std::vector<char> readProgrammingFile(const std::string &fname);
|
||||
|
||||
sls::Result<int> getNumberofUDPInterfaces(Positions pos) const;
|
||||
void setNumberofUDPInterfaces(int n, Positions pos);
|
||||
sls::Result<int> getDefaultDac(defs::dacIndex index,
|
||||
defs::detectorSettings sett,
|
||||
@ -299,6 +303,11 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
void setDefaultDac(defs::dacIndex index, int defaultValue,
|
||||
defs::detectorSettings sett, Positions pos);
|
||||
|
||||
|
||||
std::vector<std::string> getCtbDacNames() const;
|
||||
std::string getCtbDacName(defs::dacIndex i) const;
|
||||
void setCtbDacNames(const std::vector<std::string>& names);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Creates/open shared memory, initializes detector structure and members
|
||||
@ -382,6 +391,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
|
||||
const int detectorIndex{0};
|
||||
sls::SharedMemory<sharedDetector> shm{0, -1};
|
||||
sls::SharedMemory<CtbConfig> ctb_shm{0, -1, CtbConfig::shm_tag()};
|
||||
std::vector<std::unique_ptr<sls::Module>> modules;
|
||||
|
||||
/** data streaming (down stream) enabled in client (zmq sckets created) */
|
||||
|
@ -33,11 +33,11 @@ Module::Module(detectorType type, int det_id, int module_index, bool verify)
|
||||
: moduleIndex(module_index), shm(det_id, module_index) {
|
||||
|
||||
// ensure shared memory was not created before
|
||||
if (shm.IsExisting()) {
|
||||
if (shm.exists()) {
|
||||
LOG(logWARNING) << "This shared memory should have been "
|
||||
"deleted before! "
|
||||
<< shm.GetName() << ". Freeing it again";
|
||||
shm.RemoveSharedMemory();
|
||||
<< shm.getName() << ". Freeing it again";
|
||||
shm.removeSharedMemory();
|
||||
}
|
||||
|
||||
initSharedMemory(type, det_id, verify);
|
||||
@ -55,8 +55,8 @@ Module::Module(int det_id, int module_index, bool verify)
|
||||
Module::~Module() = default;
|
||||
|
||||
void Module::freeSharedMemory() {
|
||||
if (shm.IsExisting()) {
|
||||
shm.RemoveSharedMemory();
|
||||
if (shm.exists()) {
|
||||
shm.removeSharedMemory();
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,9 +214,21 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
|
||||
myMod.iodelay = myMod1.iodelay;
|
||||
myMod.tau =
|
||||
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
|
||||
// m3, reg is used for gaincaps
|
||||
if (shm()->detType == MYTHEN3) {
|
||||
if (myMod1.reg != myMod2.reg) {
|
||||
throw RuntimeError(
|
||||
"setThresholdEnergyAndSettings: gaincaps do not "
|
||||
"match between files");
|
||||
}
|
||||
myMod.reg = myMod1.reg;
|
||||
}
|
||||
}
|
||||
// m3, reg is used for gaincaps
|
||||
if (shm()->detType != MYTHEN3) {
|
||||
myMod.reg = isettings;
|
||||
}
|
||||
|
||||
myMod.reg = isettings;
|
||||
myMod.eV[0] = e_eV;
|
||||
setModule(myMod, trimbits);
|
||||
if (getSettings() != isettings) {
|
||||
@ -231,6 +243,7 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
|
||||
|
||||
void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
|
||||
detectorSettings isettings, bool trimbits) {
|
||||
// only mythen3
|
||||
if (shm()->trimEnergies.empty()) {
|
||||
throw RuntimeError(
|
||||
"Trim energies have not been defined for this module yet!");
|
||||
@ -311,6 +324,13 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
|
||||
|
||||
myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1,
|
||||
trim2, trimbits);
|
||||
// gaincaps
|
||||
if (myMod1.reg != myMod2.reg) {
|
||||
throw RuntimeError("setAllThresholdEnergy: gaincaps do not "
|
||||
"match between files for energy (eV) " +
|
||||
std::to_string(energy[i]));
|
||||
}
|
||||
myMods[i].reg = myMod1.reg;
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,6 +377,11 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
|
||||
for (int i = 0; i < myMod.nchan; ++i) {
|
||||
myMod.chanregs[i] = myMods[i % 3].chanregs[i];
|
||||
}
|
||||
// gain caps
|
||||
if (myMods[0].reg != myMods[1].reg || myMods[1].reg != myMods[2].reg) {
|
||||
throw RuntimeError("setAllThresholdEnergy: gaincaps do not "
|
||||
"match between files for all energies");
|
||||
}
|
||||
}
|
||||
|
||||
myMod.reg = isettings;
|
||||
@ -484,6 +509,13 @@ void Module::setFlipRows(bool value) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::isMaster() const { return sendToDetectorStop<int>(F_GET_MASTER); }
|
||||
|
||||
void Module::setMaster(const bool master) {
|
||||
sendToDetector(F_SET_MASTER, static_cast<int>(master), nullptr);
|
||||
sendToDetectorStop(F_SET_MASTER, static_cast<int>(master), nullptr);
|
||||
}
|
||||
|
||||
bool Module::isVirtualDetectorServer() const {
|
||||
return sendToDetector<int>(F_IS_VIRTUAL);
|
||||
}
|
||||
@ -841,11 +873,29 @@ double Module::getReceiverProgress() const {
|
||||
return sendToReceiver<double>(F_GET_RECEIVER_PROGRESS);
|
||||
}
|
||||
|
||||
int64_t Module::getFramesCaughtByReceiver() const {
|
||||
return sendToReceiver<int64_t>(F_GET_RECEIVER_FRAMES_CAUGHT);
|
||||
std::vector<int64_t> Module::getFramesCaughtByReceiver() const {
|
||||
// TODO!(Erik) Refactor
|
||||
LOG(logDEBUG1) << "Getting frames caught";
|
||||
if (shm()->useReceiverFlag) {
|
||||
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
|
||||
client.Send(F_GET_RECEIVER_FRAMES_CAUGHT);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
throw ReceiverError(
|
||||
"Receiver " + std::to_string(moduleIndex) +
|
||||
" returned error: " + client.readErrorMessage());
|
||||
} else {
|
||||
auto nports = client.Receive<int>();
|
||||
std::vector<int64_t> retval(nports);
|
||||
client.Receive(retval);
|
||||
LOG(logDEBUG1) << "Frames caught of Receiver" << moduleIndex << ": "
|
||||
<< sls::ToString(retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
throw RuntimeError("No receiver to get frames caught.");
|
||||
}
|
||||
|
||||
std::vector<uint64_t> Module::getNumMissingPackets() const {
|
||||
std::vector<int64_t> Module::getNumMissingPackets() const {
|
||||
// TODO!(Erik) Refactor
|
||||
LOG(logDEBUG1) << "Getting num missing packets";
|
||||
if (shm()->useReceiverFlag) {
|
||||
@ -857,7 +907,7 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
|
||||
" returned error: " + client.readErrorMessage());
|
||||
} else {
|
||||
auto nports = client.Receive<int>();
|
||||
std::vector<uint64_t> retval(nports);
|
||||
std::vector<int64_t> retval(nports);
|
||||
client.Receive(retval);
|
||||
LOG(logDEBUG1) << "Missing packets of Receiver" << moduleIndex
|
||||
<< ": " << sls::ToString(retval);
|
||||
@ -867,6 +917,28 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
|
||||
throw RuntimeError("No receiver to get missing packets.");
|
||||
}
|
||||
|
||||
std::vector<int64_t> Module::getReceiverCurrentFrameIndex() const {
|
||||
// TODO!(Erik) Refactor
|
||||
LOG(logDEBUG1) << "Getting frame index";
|
||||
if (shm()->useReceiverFlag) {
|
||||
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
|
||||
client.Send(F_GET_RECEIVER_FRAME_INDEX);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
throw ReceiverError(
|
||||
"Receiver " + std::to_string(moduleIndex) +
|
||||
" returned error: " + client.readErrorMessage());
|
||||
} else {
|
||||
auto nports = client.Receive<int>();
|
||||
std::vector<int64_t> retval(nports);
|
||||
client.Receive(retval);
|
||||
LOG(logDEBUG1) << "Frame index of Receiver" << moduleIndex << ": "
|
||||
<< sls::ToString(retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
throw RuntimeError("No receiver to get frame index.");
|
||||
}
|
||||
|
||||
uint64_t Module::getNextFrameNumber() const {
|
||||
return sendToDetector<uint64_t>(F_GET_NEXT_FRAME_NUMBER);
|
||||
}
|
||||
@ -904,9 +976,8 @@ int Module::getNumberofUDPInterfacesFromShm() const {
|
||||
return shm()->numUDPInterfaces;
|
||||
}
|
||||
|
||||
int Module::getNumberofUDPInterfaces() const {
|
||||
void Module::updateNumberofUDPInterfaces() {
|
||||
shm()->numUDPInterfaces = sendToDetector<int>(F_GET_NUM_INTERFACES);
|
||||
return shm()->numUDPInterfaces;
|
||||
}
|
||||
|
||||
void Module::setNumberofUDPInterfaces(int n) {
|
||||
@ -1021,6 +1092,10 @@ void Module::setDestinationUDPIP(const IpAddr ip) {
|
||||
if (ip == 0) {
|
||||
throw RuntimeError("Invalid destination udp ip address");
|
||||
}
|
||||
if (ip.str() == LOCALHOST_IP && !isVirtualDetectorServer()) {
|
||||
throw RuntimeError("Invalid destination udp ip. Change rx_hostname "
|
||||
"from localhost or change udp_dstip from auto?");
|
||||
}
|
||||
sendToDetector(F_SET_DEST_UDP_IP, ip, nullptr);
|
||||
if (shm()->useReceiverFlag) {
|
||||
sls::MacAddr retval(0LU);
|
||||
@ -1040,7 +1115,10 @@ void Module::setDestinationUDPIP2(const IpAddr ip) {
|
||||
if (ip == 0) {
|
||||
throw RuntimeError("Invalid destination udp ip address2");
|
||||
}
|
||||
|
||||
if (ip.str() == LOCALHOST_IP && !isVirtualDetectorServer()) {
|
||||
throw RuntimeError("Invalid destination udp ip2. Change rx_hostname "
|
||||
"from localhost or change udp_dstip from auto?");
|
||||
}
|
||||
sendToDetector(F_SET_DEST_UDP_IP2, ip, nullptr);
|
||||
if (shm()->useReceiverFlag) {
|
||||
sls::MacAddr retval(0LU);
|
||||
@ -1107,7 +1185,7 @@ std::string Module::printReceiverConfiguration() {
|
||||
<< getReceiverHostname();
|
||||
|
||||
if (shm()->detType == JUNGFRAU) {
|
||||
os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfaces()
|
||||
os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfacesFromShm()
|
||||
<< "\nSelected Interface:\t" << getSelectedUDPInterface();
|
||||
}
|
||||
|
||||
@ -1318,6 +1396,14 @@ std::array<pid_t, NUM_RX_THREAD_IDS> Module::getReceiverThreadIds() const {
|
||||
F_GET_RECEIVER_THREAD_IDS);
|
||||
}
|
||||
|
||||
bool Module::getRxArping() const {
|
||||
return sendToReceiver<int>(F_GET_RECEIVER_ARPING);
|
||||
}
|
||||
|
||||
void Module::setRxArping(bool enable) {
|
||||
sendToReceiver(F_SET_RECEIVER_ARPING, static_cast<int>(enable), nullptr);
|
||||
}
|
||||
|
||||
// File
|
||||
slsDetectorDefs::fileFormat Module::getFileFormat() const {
|
||||
return sendToReceiver<fileFormat>(F_GET_RECEIVER_FILE_FORMAT);
|
||||
@ -1633,6 +1719,14 @@ void Module::setDataStream(const portPosition port, const bool enable) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::getTop() const {
|
||||
return (static_cast<bool>(sendToDetector<int>(F_GET_TOP)));
|
||||
}
|
||||
|
||||
void Module::setTop(bool value) {
|
||||
sendToDetector(F_SET_TOP, static_cast<int>(value), nullptr);
|
||||
}
|
||||
|
||||
// Jungfrau Specific
|
||||
double Module::getChipVersion() const {
|
||||
return (sendToDetector<int>(F_GET_CHIP_VERSION)) / 10.00;
|
||||
@ -2157,18 +2251,57 @@ std::array<time::ns, 3> Module::getGateDelayForAllGates() const {
|
||||
return sendToDetector<std::array<time::ns, 3>>(F_GET_GATE_DELAY_ALL_GATES);
|
||||
}
|
||||
|
||||
bool Module::isMaster() const { return sendToDetectorStop<int>(F_GET_MASTER); }
|
||||
|
||||
int Module::getChipStatusRegister() const {
|
||||
return sendToDetector<int>(F_GET_CSR);
|
||||
}
|
||||
|
||||
void Module::setGainCaps(int caps) {
|
||||
sendToDetector<int>(F_SET_GAIN_CAPS, caps);
|
||||
sendToDetector(F_SET_GAIN_CAPS, caps, nullptr);
|
||||
}
|
||||
|
||||
int Module::getGainCaps() { return sendToDetector<int>(F_GET_GAIN_CAPS); }
|
||||
|
||||
defs::polarity Module::getPolarity() const {
|
||||
return sendToDetector<defs::polarity>(F_GET_POLARITY);
|
||||
}
|
||||
|
||||
void Module::setPolarity(const defs::polarity value) {
|
||||
sendToDetector(F_SET_POLARITY, static_cast<int>(value), nullptr);
|
||||
}
|
||||
|
||||
bool Module::getInterpolation() const {
|
||||
return sendToDetector<int>(F_GET_INTERPOLATION);
|
||||
}
|
||||
|
||||
void Module::setInterpolation(const bool enable) {
|
||||
sendToDetector(F_SET_INTERPOLATION, static_cast<int>(enable), nullptr);
|
||||
setCounterMask(getCounterMask());
|
||||
}
|
||||
|
||||
bool Module::getPumpProbe() const {
|
||||
return sendToDetector<int>(F_GET_PUMP_PROBE);
|
||||
}
|
||||
|
||||
void Module::setPumpProbe(const bool enable) {
|
||||
sendToDetector(F_SET_PUMP_PROBE, static_cast<int>(enable), nullptr);
|
||||
}
|
||||
|
||||
bool Module::getAnalogPulsing() const {
|
||||
return sendToDetector<int>(F_GET_ANALOG_PULSING);
|
||||
}
|
||||
|
||||
void Module::setAnalogPulsing(const bool enable) {
|
||||
sendToDetector(F_SET_ANALOG_PULSING, static_cast<int>(enable), nullptr);
|
||||
}
|
||||
|
||||
bool Module::getDigitalPulsing() const {
|
||||
return sendToDetector<int>(F_GET_DIGITAL_PULSING);
|
||||
}
|
||||
|
||||
void Module::setDigitalPulsing(const bool enable) {
|
||||
sendToDetector(F_SET_DIGITAL_PULSING, static_cast<int>(enable), nullptr);
|
||||
}
|
||||
|
||||
// CTB / Moench Specific
|
||||
int Module::getNumberOfAnalogSamples() const {
|
||||
return sendToDetector<int>(F_GET_NUM_ANALOG_SAMPLES);
|
||||
@ -2498,12 +2631,14 @@ void Module::setAdditionalJsonParameter(const std::string &key,
|
||||
}
|
||||
|
||||
// Advanced
|
||||
void Module::programFPGA(std::vector<char> buffer) {
|
||||
void Module::programFPGA(std::vector<char> buffer,
|
||||
const bool forceDeleteNormalFile) {
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware");
|
||||
sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware", "",
|
||||
forceDeleteNormalFile);
|
||||
break;
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
@ -2517,28 +2652,6 @@ void Module::programFPGA(std::vector<char> buffer) {
|
||||
|
||||
void Module::resetFPGA() { sendToDetector(F_RESET_FPGA); }
|
||||
|
||||
void Module::copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname) {
|
||||
char args[2][MAX_STR_LENGTH]{};
|
||||
sls::strcpy_safe(args[0], fname.c_str());
|
||||
sls::strcpy_safe(args[1], hostname.c_str());
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Sending detector server " << args[0] << " from host "
|
||||
<< args[1];
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_COPY_DET_SERVER);
|
||||
client.Send(args);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::cout << '\n';
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Detector server copied";
|
||||
}
|
||||
|
||||
void Module::updateDetectorServer(std::vector<char> buffer,
|
||||
const std::string &serverName) {
|
||||
switch (shm()->detType) {
|
||||
@ -2703,10 +2816,6 @@ int64_t Module::getMeasurementTime() const {
|
||||
return sendToDetectorStop<int64_t>(F_GET_MEASUREMENT_TIME);
|
||||
}
|
||||
|
||||
uint64_t Module::getReceiverCurrentFrameIndex() const {
|
||||
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAME_INDEX);
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
void Module::checkArgs(const void *args, size_t args_size, void *retval,
|
||||
@ -3081,20 +3190,20 @@ Ret Module::sendToReceiver(int fnum, const Arg &args) {
|
||||
|
||||
slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
|
||||
bool verify) {
|
||||
if (!shm.IsExisting()) {
|
||||
throw SharedMemoryError("Shared memory " + shm.GetName() +
|
||||
if (!shm.exists()) {
|
||||
throw SharedMemoryError("Shared memory " + shm.getName() +
|
||||
"does not exist.\n Corrupted Multi Shared "
|
||||
"memory. Please free shared memory.");
|
||||
}
|
||||
|
||||
shm.OpenSharedMemory();
|
||||
shm.openSharedMemory();
|
||||
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
|
||||
std::ostringstream ss;
|
||||
ss << "Single shared memory (" << det_id << "-" << moduleIndex
|
||||
<< ":)version mismatch (expected 0x" << std::hex << MODULE_SHMVERSION
|
||||
<< " but got 0x" << shm()->shmversion << ")" << std::dec
|
||||
<< ". Clear Shared memory to continue.";
|
||||
shm.UnmapSharedMemory();
|
||||
shm.unmapSharedMemory();
|
||||
throw SharedMemoryError(ss.str());
|
||||
}
|
||||
return shm()->detType;
|
||||
@ -3102,11 +3211,11 @@ slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
|
||||
|
||||
void Module::initSharedMemory(detectorType type, int det_id, bool verify) {
|
||||
shm = SharedMemory<sharedModule>(det_id, moduleIndex);
|
||||
if (!shm.IsExisting()) {
|
||||
shm.CreateSharedMemory();
|
||||
if (!shm.exists()) {
|
||||
shm.createSharedMemory();
|
||||
initializeModuleStructure(type);
|
||||
} else {
|
||||
shm.OpenSharedMemory();
|
||||
shm.openSharedMemory();
|
||||
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
|
||||
std::ostringstream ss;
|
||||
ss << "Single shared memory (" << det_id << "-" << moduleIndex
|
||||
@ -3130,10 +3239,10 @@ void Module::initializeModuleStructure(detectorType type) {
|
||||
sls::strcpy_safe(shm()->rxHostname, "none");
|
||||
shm()->rxTCPPort = DEFAULT_PORTNO + 2;
|
||||
shm()->useReceiverFlag = false;
|
||||
shm()->numUDPInterfaces = 1;
|
||||
shm()->zmqport =
|
||||
DEFAULT_ZMQ_CL_PORTNO + moduleIndex * shm()->numUDPInterfaces;
|
||||
shm()->zmqip = IpAddr{};
|
||||
shm()->numUDPInterfaces = 1;
|
||||
shm()->stoppedFlag = false;
|
||||
|
||||
// get the Module parameters based on type
|
||||
@ -3322,9 +3431,9 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
|
||||
dacs_to_copy.end(),
|
||||
{E_SVP, E_SVN, E_VTGSTV, E_RXB_RB, E_RXB_LB, E_VCN, E_VIS});
|
||||
// interpolate vrf, vcmp, vcp
|
||||
dacs_to_interpolate.insert(
|
||||
dacs_to_interpolate.end(),
|
||||
{E_VTR, E_VRF, E_VCMP_LL, E_VCMP_LR, E_VCMP_RL, E_VCMP_RR, E_VCP, E_VRS});
|
||||
dacs_to_interpolate.insert(dacs_to_interpolate.end(),
|
||||
{E_VTR, E_VRF, E_VCMP_LL, E_VCMP_LR,
|
||||
E_VCMP_RL, E_VCMP_RR, E_VCP, E_VRS});
|
||||
} else {
|
||||
dacs_to_copy.insert(dacs_to_copy.end(),
|
||||
{M_VCASSH, M_VRSHAPER, M_VRSHAPER_N, M_VIPRE_OUT,
|
||||
@ -3494,7 +3603,8 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
|
||||
void Module::sendProgram(bool blackfin, std::vector<char> buffer,
|
||||
const int functionEnum,
|
||||
const std::string &functionType,
|
||||
const std::string serverName) {
|
||||
const std::string serverName,
|
||||
const bool forceDeleteNormalFile) {
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Sending " << functionType;
|
||||
|
||||
@ -3518,6 +3628,11 @@ void Module::sendProgram(bool blackfin, std::vector<char> buffer,
|
||||
client.Send(sname);
|
||||
}
|
||||
|
||||
// send forceDeleteNormalFile flag
|
||||
if (blackfin) {
|
||||
client.Send(static_cast<int>(forceDeleteNormalFile));
|
||||
}
|
||||
|
||||
// validate memory allocation etc in detector
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
|
@ -120,6 +120,9 @@ class Module : public virtual slsDetectorDefs {
|
||||
int setTrimEn(const std::vector<int> &energies = {});
|
||||
bool getFlipRows() const;
|
||||
void setFlipRows(bool value);
|
||||
bool isMaster() const;
|
||||
void setMaster(const bool master);
|
||||
|
||||
bool isVirtualDetectorServer() const;
|
||||
|
||||
/**************************************************
|
||||
@ -184,6 +187,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
void setDBITPipeline(int value);
|
||||
int getReadNRows() const;
|
||||
void setReadNRows(const int value);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Acquisition *
|
||||
@ -199,8 +203,9 @@ class Module : public virtual slsDetectorDefs {
|
||||
runStatus getRunStatus() const;
|
||||
runStatus getReceiverStatus() const;
|
||||
double getReceiverProgress() const;
|
||||
int64_t getFramesCaughtByReceiver() const;
|
||||
std::vector<uint64_t> getNumMissingPackets() const;
|
||||
std::vector<int64_t> getFramesCaughtByReceiver() const;
|
||||
std::vector<int64_t> getNumMissingPackets() const;
|
||||
std::vector<int64_t> getReceiverCurrentFrameIndex() const;
|
||||
uint64_t getNextFrameNumber() const;
|
||||
void setNextFrameNumber(uint64_t value);
|
||||
void sendSoftwareTrigger(const bool block);
|
||||
@ -214,7 +219,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
* *
|
||||
* ************************************************/
|
||||
int getNumberofUDPInterfacesFromShm() const;
|
||||
int getNumberofUDPInterfaces() const;
|
||||
void updateNumberofUDPInterfaces();
|
||||
void setNumberofUDPInterfaces(int n);
|
||||
int getSelectedUDPInterface() const;
|
||||
void selectUDPInterface(int n);
|
||||
@ -283,6 +288,8 @@ class Module : public virtual slsDetectorDefs {
|
||||
void setReceiverLock(bool lock);
|
||||
sls::IpAddr getReceiverLastClientIP() const;
|
||||
std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const;
|
||||
bool getRxArping() const;
|
||||
void setRxArping(bool enable);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
@ -363,6 +370,8 @@ class Module : public virtual slsDetectorDefs {
|
||||
void setQuad(const bool enable);
|
||||
bool getDataStream(const portPosition port) const;
|
||||
void setDataStream(const portPosition port, const bool enable);
|
||||
bool getTop() const;
|
||||
void setTop(bool value);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
@ -454,10 +463,19 @@ class Module : public virtual slsDetectorDefs {
|
||||
int64_t getGateDelay(int gateIndex) const;
|
||||
void setGateDelay(int gateIndex, int64_t value);
|
||||
std::array<time::ns, 3> getGateDelayForAllGates() const;
|
||||
bool isMaster() const;
|
||||
int getChipStatusRegister() const;
|
||||
void setGainCaps(int caps);
|
||||
int getGainCaps();
|
||||
defs::polarity getPolarity() const;
|
||||
void setPolarity(const defs::polarity enable);
|
||||
bool getInterpolation() const;
|
||||
void setInterpolation(const bool enable);
|
||||
bool getPumpProbe() const;
|
||||
void setPumpProbe(const bool enable);
|
||||
bool getAnalogPulsing() const;
|
||||
void setAnalogPulsing(const bool enable);
|
||||
bool getDigitalPulsing() const;
|
||||
void setDigitalPulsing(const bool enable);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
@ -537,10 +555,9 @@ class Module : public virtual slsDetectorDefs {
|
||||
* Advanced *
|
||||
* *
|
||||
* ************************************************/
|
||||
void programFPGA(std::vector<char> buffer);
|
||||
void programFPGA(std::vector<char> buffer,
|
||||
const bool forceDeleteNormalFile);
|
||||
void resetFPGA();
|
||||
void copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname);
|
||||
void updateDetectorServer(std::vector<char> buffer,
|
||||
const std::string &serverName);
|
||||
void updateKernel(std::vector<char> buffer);
|
||||
@ -574,7 +591,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
int64_t getNumberOfFramesFromStart() const;
|
||||
int64_t getActualTime() const;
|
||||
int64_t getMeasurementTime() const;
|
||||
uint64_t getReceiverCurrentFrameIndex() const;
|
||||
|
||||
private:
|
||||
void checkArgs(const void *args, size_t args_size, void *retval,
|
||||
@ -753,7 +769,8 @@ class Module : public virtual slsDetectorDefs {
|
||||
bool trimbits = true);
|
||||
void sendProgram(bool blackfin, std::vector<char> buffer,
|
||||
const int functionEnum, const std::string &functionType,
|
||||
const std::string serverName = "");
|
||||
const std::string serverName = "",
|
||||
const bool forceDeleteNormalFile = false);
|
||||
void simulatingActivityinDetector(const std::string &functionType,
|
||||
const int timeRequired);
|
||||
|
||||
|
@ -13,13 +13,13 @@
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
|
||||
#include "stdlib.h"
|
||||
// #include "stdlib.h"
|
||||
#include <cstdlib>
|
||||
#include <cerrno> // errno
|
||||
#include <cstring> // strerror
|
||||
#include <fcntl.h> // O_CREAT, O_TRUNC..
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
// #include <stdio.h> // printf
|
||||
#include <sys/mman.h> // shared memory
|
||||
#include <sys/stat.h> // fstat
|
||||
#include <unistd.h>
|
||||
@ -34,275 +34,178 @@
|
||||
namespace sls {
|
||||
|
||||
template <typename T> class SharedMemory {
|
||||
static constexpr int NAME_MAX_LENGTH = 255;
|
||||
std::string name;
|
||||
T *shared_struct{};
|
||||
|
||||
public:
|
||||
/**
|
||||
* moduleid of -1 creates a detector only shared memory
|
||||
*/
|
||||
SharedMemory(int detectorId, int moduleIndex) {
|
||||
name = ConstructSharedMemoryName(detectorId, moduleIndex);
|
||||
// moduleid of -1 creates a detector only shared memory
|
||||
SharedMemory(int detectorId, int moduleIndex, const std::string &tag = "") {
|
||||
name = constructSharedMemoryName(detectorId, moduleIndex, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the copy constructor and copy assignment since we don't want two
|
||||
* objects managing the same resource
|
||||
*/
|
||||
// Disable copy, since we refer to a unique location
|
||||
SharedMemory(const SharedMemory &) = delete;
|
||||
SharedMemory &operator=(const SharedMemory &other) = delete;
|
||||
|
||||
// Move constructor
|
||||
SharedMemory(SharedMemory &&other)
|
||||
: name(other.name), fd(other.fd), shmSize(other.shmSize),
|
||||
shared_struct(other.shared_struct) {
|
||||
|
||||
other.fd = -1;
|
||||
: name(other.name), shared_struct(other.shared_struct) {
|
||||
other.shared_struct = nullptr;
|
||||
other.shmSize = 0;
|
||||
}
|
||||
|
||||
// Move assignment
|
||||
SharedMemory &operator=(SharedMemory &&other) {
|
||||
name = other.name;
|
||||
if (fd) {
|
||||
close(fd);
|
||||
}
|
||||
fd = other.fd;
|
||||
other.fd = -1;
|
||||
|
||||
if (shared_struct != nullptr) {
|
||||
UnmapSharedMemory();
|
||||
}
|
||||
if (shared_struct != nullptr)
|
||||
unmapSharedMemory();
|
||||
shared_struct = other.shared_struct;
|
||||
other.shared_struct = nullptr;
|
||||
|
||||
shmSize = other.shmSize;
|
||||
other.shmSize = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SharedMemory() {
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
if (shared_struct) {
|
||||
UnmapSharedMemory();
|
||||
}
|
||||
if (shared_struct)
|
||||
unmapSharedMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if it exists
|
||||
* @return true if exists, else false
|
||||
*/
|
||||
bool IsExisting() {
|
||||
bool ret = true;
|
||||
T *operator()() { return shared_struct; }
|
||||
const T *operator()() const { return shared_struct; }
|
||||
std::string getName() const { return name; }
|
||||
|
||||
bool exists() {
|
||||
int tempfd = shm_open(name.c_str(), O_RDWR, 0);
|
||||
if ((tempfd < 0) && (errno == ENOENT)) {
|
||||
ret = false;
|
||||
return false;
|
||||
}
|
||||
close(tempfd);
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shared memory name
|
||||
*/
|
||||
std::string GetName() const { return name; }
|
||||
|
||||
size_t size() const { return shmSize; }
|
||||
|
||||
/**
|
||||
* Create Shared memory and call MapSharedMemory to map it to an address
|
||||
* throws a SharedMemoryError exception on failure to create, ftruncate or
|
||||
* map
|
||||
*/
|
||||
void CreateSharedMemory() {
|
||||
fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR,
|
||||
S_IRUSR | S_IWUSR);
|
||||
void createSharedMemory() {
|
||||
int fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR,
|
||||
S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
std::string msg =
|
||||
"Create shared memory " + name + " failed: " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
if (ftruncate(fd, sizeof(T)) < 0) {
|
||||
std::string msg = "Create shared memory " + name +
|
||||
" failed at ftruncate: " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
RemoveSharedMemory();
|
||||
removeSharedMemory();
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
shared_struct = MapSharedMemory();
|
||||
shared_struct = mapSharedMemory(fd);
|
||||
new (shared_struct) T{};
|
||||
LOG(logINFO) << "Shared memory created " << name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open existing Shared memory and call MapSharedMemory to map it to an
|
||||
* address throws a SharedMemoryError exception on failure to open or map
|
||||
*/
|
||||
void OpenSharedMemory() {
|
||||
fd = shm_open(name.c_str(), O_RDWR, 0);
|
||||
void openSharedMemory() {
|
||||
int fd = shm_open(name.c_str(), O_RDWR, 0);
|
||||
if (fd < 0) {
|
||||
std::string msg = "Open existing shared memory " + name +
|
||||
" failed: " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
shared_struct = MapSharedMemory();
|
||||
checkSize(fd);
|
||||
shared_struct = mapSharedMemory(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap shared memory from an address
|
||||
* throws a SharedMemoryError exception on failure
|
||||
*/
|
||||
void UnmapSharedMemory() {
|
||||
void unmapSharedMemory() {
|
||||
if (shared_struct != nullptr) {
|
||||
if (munmap(shared_struct, shmSize) < 0) {
|
||||
if (munmap(shared_struct, sizeof(T)) < 0) {
|
||||
std::string msg = "Unmapping shared memory " + name +
|
||||
" failed: " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
shared_struct = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove existing Shared memory
|
||||
*/
|
||||
void RemoveSharedMemory() {
|
||||
UnmapSharedMemory();
|
||||
void removeSharedMemory() {
|
||||
unmapSharedMemory();
|
||||
if (shm_unlink(name.c_str()) < 0) {
|
||||
// silent exit if shm did not exist anyway
|
||||
if (errno == ENOENT)
|
||||
return;
|
||||
std::string msg =
|
||||
"Free Shared Memory " + name + " Failed: " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
LOG(logINFO) << "Shared memory deleted " << name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum length of name as from man pages
|
||||
*/
|
||||
static const int NAME_MAX_LENGTH = 255;
|
||||
|
||||
/**
|
||||
*Using the call operator to access the pointer
|
||||
*/
|
||||
T *operator()() { return shared_struct; }
|
||||
|
||||
/**
|
||||
*Using the call operator to access the pointer, const overload
|
||||
*/
|
||||
const T *operator()() const { return shared_struct; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Create Shared memory name
|
||||
* throws exception if name created is longer than required 255(manpages)
|
||||
* @param detectorId detector id
|
||||
* @param moduleIndex module id, -1 if a detector shared memory
|
||||
* @returns shared memory name
|
||||
*/
|
||||
std::string ConstructSharedMemoryName(int detectorId, int moduleIndex) {
|
||||
std::string constructSharedMemoryName(int detectorId, int moduleIndex,
|
||||
const std::string &tag) {
|
||||
|
||||
// using environment path
|
||||
std::string sEnvPath;
|
||||
// using environment variable
|
||||
std::string slsdetname;
|
||||
char *envpath = getenv(SHM_ENV_NAME);
|
||||
if (envpath != nullptr) {
|
||||
sEnvPath.assign(envpath);
|
||||
sEnvPath.insert(0, "_");
|
||||
slsdetname = envpath;
|
||||
slsdetname.insert(0, "_");
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
if (moduleIndex < 0)
|
||||
ss << SHM_DETECTOR_PREFIX << detectorId << sEnvPath;
|
||||
else
|
||||
if (moduleIndex < 0) {
|
||||
ss << SHM_DETECTOR_PREFIX << detectorId << slsdetname;
|
||||
if (!tag.empty())
|
||||
ss << "_" << tag;
|
||||
} else {
|
||||
ss << SHM_DETECTOR_PREFIX << detectorId << SHM_MODULE_PREFIX
|
||||
<< moduleIndex << sEnvPath;
|
||||
<< moduleIndex << slsdetname;
|
||||
}
|
||||
|
||||
std::string temp = ss.str();
|
||||
if (temp.length() > NAME_MAX_LENGTH) {
|
||||
std::string shm_name = ss.str();
|
||||
if (shm_name.length() > NAME_MAX_LENGTH) {
|
||||
std::string msg =
|
||||
"Shared memory initialization failed. " + temp + " has " +
|
||||
std::to_string(temp.length()) + " characters. \n" +
|
||||
"Shared memory initialization failed. " + shm_name + " has " +
|
||||
std::to_string(shm_name.length()) + " characters. \n" +
|
||||
"Maximum is " + std::to_string(NAME_MAX_LENGTH) +
|
||||
". Change the environment variable " + SHM_ENV_NAME;
|
||||
LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
return temp;
|
||||
return shm_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map shared memory to an address
|
||||
* throws a SharedMemoryException exception on failure
|
||||
*/
|
||||
|
||||
T *MapSharedMemory() {
|
||||
// from the Linux manual:
|
||||
// After the mmap() call has returned, the file descriptor, fd, can
|
||||
// be closed immediately without invalidating the mapping.
|
||||
T *mapSharedMemory(int fd) {
|
||||
void *addr =
|
||||
mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
close(fd);
|
||||
if (addr == MAP_FAILED) {
|
||||
std::string msg =
|
||||
"Mapping shared memory " + name + " failed: " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
shmSize = sizeof(T);
|
||||
close(fd);
|
||||
return (T *)addr;
|
||||
return static_cast<T *>(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if existing shared memory size matches expected size
|
||||
* @param expectedSize expected size of shared memory, replaced with smaller
|
||||
* size if size does not match
|
||||
* @return 0 for success, 1 for fail
|
||||
*/
|
||||
int VerifySizeMatch(size_t expectedSize) {
|
||||
void checkSize(int fd) {
|
||||
struct stat sb;
|
||||
// could not fstat
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
std::string msg = "Could not verify existing shared memory " +
|
||||
name + " size match " +
|
||||
"(could not fstat): " + strerror(errno);
|
||||
LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
// size does not match
|
||||
auto sz = static_cast<size_t>(sb.st_size);
|
||||
if (sz != expectedSize) {
|
||||
std::string msg = "Existing shared memory " + name +
|
||||
" size does not match" + "Expected " +
|
||||
std::to_string(expectedSize) + ", found " +
|
||||
std::to_string(sz);
|
||||
LOG(logERROR) << msg;
|
||||
auto actual_size = static_cast<size_t>(sb.st_size);
|
||||
auto expected_size = sizeof(T);
|
||||
if (actual_size != expected_size) {
|
||||
std::string msg =
|
||||
"Existing shared memory " + name + " size does not match. " +
|
||||
"Expected " + std::to_string(expected_size) + ", found " +
|
||||
std::to_string(actual_size) +
|
||||
". Detector software mismatch? Try freeing shared memory.";
|
||||
throw SharedMemoryError(msg);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Shared memory name */
|
||||
std::string name;
|
||||
|
||||
/** File descriptor */
|
||||
int fd{-1};
|
||||
|
||||
/** shm size */
|
||||
size_t shmSize{0};
|
||||
|
||||
T *shared_struct{nullptr};
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
|
@ -18,6 +18,7 @@ target_sources(tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Module.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Pattern.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-CtbConfig.cpp
|
||||
)
|
||||
|
||||
target_include_directories(tests PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../src>")
|
@ -630,3 +630,31 @@ TEST_CASE("datastream", "[.cmd]") {
|
||||
REQUIRE_THROWS(proxy.Call("datastream", {"left", "1"}, -1, PUT));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("top", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::EIGER) {
|
||||
auto prev_val = det.getTop();
|
||||
int numModulesTested = 1;
|
||||
if (det.size() > 1) {
|
||||
numModulesTested = 2;
|
||||
}
|
||||
for (int i = 0; i != numModulesTested; ++i) {
|
||||
std::ostringstream oss1, oss2, oss3;
|
||||
proxy.Call("top", {"1"}, i, PUT, oss1);
|
||||
REQUIRE(oss1.str() == "top 1\n");
|
||||
proxy.Call("top", {}, i, GET, oss2);
|
||||
REQUIRE(oss2.str() == "top 1\n");
|
||||
proxy.Call("top", {"0"}, i, PUT, oss3);
|
||||
REQUIRE(oss3.str() == "top 0\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setTop(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("top", {}, -1, GET));
|
||||
REQUIRE_THROWS(proxy.Call("top", {"1"}, -1, PUT));
|
||||
}
|
||||
}
|
@ -463,3 +463,151 @@ TEST_CASE("gatedelay3", "[.cmd]") {
|
||||
REQUIRE_THROWS(proxy.Call("gatedelay3", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("polarity", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
if (det.getDetectorType().squash() == defs::MYTHEN3) {
|
||||
auto prev_val = det.getPolarity();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("polarity", {"pos"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "polarity pos\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("polarity", {"neg"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "polarity neg\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("polarity", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "polarity neg\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setPolarity(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("polarity", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("interpolation", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
if (det.getDetectorType().squash() == defs::MYTHEN3) {
|
||||
auto prev_val = det.getInterpolation();
|
||||
auto mask = det.getCounterMask();
|
||||
{
|
||||
proxy.Call("counters", {"0", "1"}, -1, PUT);
|
||||
std::ostringstream oss;
|
||||
proxy.Call("interpolation", {"1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "interpolation 1\n");
|
||||
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
|
||||
7);
|
||||
}
|
||||
{
|
||||
proxy.Call("counters", {"0", "1"}, -1, PUT);
|
||||
std::ostringstream oss;
|
||||
proxy.Call("interpolation", {"0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "interpolation 0\n");
|
||||
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
|
||||
3);
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("interpolation", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "interpolation 0\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setCounterMask(mask[i], {i});
|
||||
det.setInterpolation(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("interpolation", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("pumpprobe", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
if (det.getDetectorType().squash() == defs::MYTHEN3) {
|
||||
auto prev_val = det.getPumpProbe();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("pumpprobe", {"1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "pumpprobe 1\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("pumpprobe", {"0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "pumpprobe 0\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("pumpprobe", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "pumpprobe 0\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setPumpProbe(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("pumpprobe", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("apulse", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
if (det.getDetectorType().squash() == defs::MYTHEN3) {
|
||||
auto prev_val = det.getAnalogPulsing();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("apulse", {"1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "apulse 1\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("apulse", {"0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "apulse 0\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("apulse", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "apulse 0\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setAnalogPulsing(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("apulse", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("dpulse", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
if (det.getDetectorType().squash() == defs::MYTHEN3) {
|
||||
auto prev_val = det.getDigitalPulsing();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("dpulse", {"1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dpulse 1\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("dpulse", {"0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "dpulse 0\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("dpulse", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "dpulse 0\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setDigitalPulsing(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("dpulse", {}, -1, GET));
|
||||
}
|
||||
}
|
@ -93,13 +93,19 @@ TEST_CASE("rx_framescaught", "[.cmd][.rx]") {
|
||||
CmdProxy proxy(&det);
|
||||
|
||||
// This ensures 0 caught frames
|
||||
auto prev_val = det.getFileWrite();
|
||||
det.setFileWrite(false); // avoid writing or error on file creation
|
||||
det.startReceiver();
|
||||
det.stopReceiver();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_framescaught", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_framescaught 0\n");
|
||||
if (det.getNumberofUDPInterfaces().tsquash(
|
||||
"inconsistent number of interfaces") == 1) {
|
||||
REQUIRE(oss.str() == "rx_framescaught [0]\n");
|
||||
} else {
|
||||
REQUIRE(oss.str() == "rx_framescaught [0, 0]\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Currently disabled may activate if we have a stable env
|
||||
@ -111,10 +117,15 @@ TEST_CASE("rx_framescaught", "[.cmd][.rx]") {
|
||||
// proxy.Call("rx_framescaught", {}, -1, GET, oss);
|
||||
// REQUIRE(oss.str() == "rx_framescaught 1\n");
|
||||
// }
|
||||
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setFileWrite(prev_val[i], {i});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rx_missingpackets", "[.cmd][.rx]") {
|
||||
Detector det;
|
||||
auto prev_val = det.getFileWrite();
|
||||
det.setFileWrite(false); // avoid writing or error on file creation
|
||||
CmdProxy proxy(&det);
|
||||
{
|
||||
@ -123,8 +134,12 @@ TEST_CASE("rx_missingpackets", "[.cmd][.rx]") {
|
||||
det.stopReceiver();
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_missingpackets", {}, -1, GET, oss);
|
||||
std::string s = (oss.str()).erase(0, strlen("rx_missingpackets ["));
|
||||
REQUIRE(std::stoi(s) > 0);
|
||||
if (det.getNumberofUDPInterfaces().tsquash(
|
||||
"inconsistent number of interfaces") == 1) {
|
||||
REQUIRE(oss.str() != "rx_missingpackets [0]\n");
|
||||
} else {
|
||||
REQUIRE(oss.str() != "rx_missingpackets [0, 0]\n");
|
||||
}
|
||||
}
|
||||
{
|
||||
// 0 missing packets (takes into account that acquisition is stopped)
|
||||
@ -133,9 +148,25 @@ TEST_CASE("rx_missingpackets", "[.cmd][.rx]") {
|
||||
det.stopReceiver();
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_missingpackets", {}, -1, GET, oss);
|
||||
std::string s = (oss.str()).erase(0, strlen("rx_missingpackets ["));
|
||||
REQUIRE(std::stoi(s) == 0);
|
||||
if (det.getNumberofUDPInterfaces().tsquash(
|
||||
"inconsistent number of interfaces") == 1) {
|
||||
REQUIRE(oss.str() == "rx_missingpackets [0]\n");
|
||||
} else {
|
||||
REQUIRE(oss.str() == "rx_missingpackets [0, 0]\n");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setFileWrite(prev_val[i], {i});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rx_frameindex", "[.cmd][.rx]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
proxy.Call("rx_frameindex", {}, -1, GET);
|
||||
|
||||
// This is a get only command
|
||||
REQUIRE_THROWS(proxy.Call("rx_frameindex", {"2"}, -1, PUT));
|
||||
}
|
||||
|
||||
/* Network Configuration (Detector<->Receiver) */
|
||||
@ -385,6 +416,30 @@ TEST_CASE("rx_threads", "[.cmd][.rx]") {
|
||||
REQUIRE_NOTHROW(proxy.Call("rx_threads", {}, -1, GET, oss));
|
||||
}
|
||||
|
||||
TEST_CASE("rx_arping", "[.cmd][.rx]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto prev_val = det.getRxArping();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_arping", {"1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_arping 1\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_arping", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_arping 1\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_arping", {"0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_arping 0\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRxArping(prev_val[i], {i});
|
||||
}
|
||||
}
|
||||
|
||||
/* File */
|
||||
|
||||
TEST_CASE("fformat", "[.cmd]") {
|
||||
@ -860,16 +915,3 @@ TEST_CASE("rx_jsonpara", "[.cmd][.rx]") {
|
||||
}
|
||||
|
||||
/* Insignificant */
|
||||
|
||||
TEST_CASE("rx_frameindex", "[.cmd][.rx]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
proxy.Call("rx_frameindex", {}, -1, GET);
|
||||
|
||||
// This is a get only command
|
||||
REQUIRE_THROWS(proxy.Call("rx_frameindex", {"2"}, -1, PUT));
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_frameindex", {}, 0, GET, oss);
|
||||
std::string s = (oss.str()).erase(0, strlen("rx_frameindex "));
|
||||
REQUIRE(std::stoi(s) >= 0);
|
||||
}
|
||||
|
@ -16,6 +16,17 @@ using sls::Detector;
|
||||
using test::GET;
|
||||
using test::PUT;
|
||||
|
||||
TEST_CASE("Calling help doesn't throw or cause segfault"){
|
||||
//Dont add [.cmd] tag this should run with normal tests
|
||||
CmdProxy proxy(nullptr);
|
||||
auto commands = proxy.GetProxyCommands();
|
||||
std::ostringstream os;
|
||||
for (const auto &cmd : commands)
|
||||
REQUIRE_NOTHROW(proxy.Call(cmd, {}, -1, slsDetectorDefs::HELP_ACTION, os));
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Unknown command", "[.cmd]") {
|
||||
|
||||
Detector det;
|
||||
@ -570,6 +581,46 @@ TEST_CASE("fliprows", "[.cmd]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("master", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::EIGER || det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD || det_type == defs::GOTTHARD2) {
|
||||
REQUIRE_NOTHROW(proxy.Call("master", {}, -1, GET));
|
||||
if (det_type == defs::EIGER) {
|
||||
// get previous master
|
||||
int prevMaster = 0;
|
||||
{
|
||||
auto previous = det.getMaster();
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
if (previous[i] == 1) {
|
||||
prevMaster = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
std::ostringstream oss1;
|
||||
proxy.Call("master", {"0"}, 0, PUT, oss1);
|
||||
REQUIRE(oss1.str() == "master 0\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss1;
|
||||
proxy.Call("master", {"1"}, 0, PUT, oss1);
|
||||
REQUIRE(oss1.str() == "master 1\n");
|
||||
}
|
||||
REQUIRE_THROWS(proxy.Call("master", {"1"}, -1, PUT));
|
||||
// set all to slaves, and then master
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setMaster(0, {i});
|
||||
}
|
||||
det.setMaster(1, prevMaster);
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("master", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
/* acquisition parameters */
|
||||
|
||||
// acquire: not testing
|
||||
@ -2126,6 +2177,41 @@ TEST_CASE("nextframenumber", "[.cmd]") {
|
||||
proxy.Call("nextframenumber", {"1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "nextframenumber 1\n");
|
||||
}
|
||||
|
||||
auto prev_timing =
|
||||
det.getTimingMode().tsquash("inconsistent timing mode in test");
|
||||
auto prev_frames =
|
||||
det.getNumberOfFrames().tsquash("inconsistent #frames in test");
|
||||
auto prev_exptime =
|
||||
det.getExptime().tsquash("inconsistent exptime in test");
|
||||
auto prev_period =
|
||||
det.getPeriod().tsquash("inconsistent period in test");
|
||||
det.setTimingMode(defs::AUTO_TIMING);
|
||||
det.setNumberOfFrames(1);
|
||||
det.setExptime(std::chrono::microseconds(200));
|
||||
det.setPeriod(std::chrono::milliseconds(1));
|
||||
det.startDetector();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
auto currentfnum =
|
||||
det.getNextFrameNumber().tsquash("inconsistent frame nr in test");
|
||||
REQUIRE(currentfnum == 2);
|
||||
if (det_type == defs::EIGER) {
|
||||
auto prev_tengiga =
|
||||
det.getTenGiga().tsquash("inconsistent ten giga enable");
|
||||
det.setTenGiga(true);
|
||||
det.setNextFrameNumber(1);
|
||||
det.startDetector();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
auto currentfnum = det.getNextFrameNumber().tsquash(
|
||||
"inconsistent frame nr in test");
|
||||
REQUIRE(currentfnum == 2);
|
||||
det.setTenGiga(prev_tengiga);
|
||||
}
|
||||
|
||||
det.setTimingMode(prev_timing);
|
||||
det.setNumberOfFrames(prev_frames);
|
||||
det.setExptime(prev_exptime);
|
||||
det.setPeriod(prev_period);
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setNextFrameNumber(prev_sfnum[i], {i});
|
||||
}
|
||||
@ -2701,25 +2787,6 @@ TEST_CASE("resetfpga", "[.cmd]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("copydetectorserver", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::MOENCH || det_type == defs::MYTHEN3 ||
|
||||
det_type == defs::GOTTHARD2) {
|
||||
// TODO: send real server?
|
||||
// std::ostringstream oss;
|
||||
// proxy.Call("copydetectorserver",{"jungfrauDetectorServerv4.0.1.0",
|
||||
// "pc13784"}, -1, PUT, oss);
|
||||
// REQUIRE(oss.str() == "copydetectorserver successful\n");
|
||||
REQUIRE_THROWS(proxy.Call("copydetectorserver", {}, -1, GET));
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("copydetectorserver", {}, -1, GET));
|
||||
REQUIRE_THROWS(proxy.Call("copydetectorserver", {}, -1, PUT));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("updatekernel", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
|
59
slsDetectorSoftware/tests/test-CtbConfig.cpp
Normal file
59
slsDetectorSoftware/tests/test-CtbConfig.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "catch.hpp"
|
||||
#include <string>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SharedMemory.h"
|
||||
#include "CtbConfig.h"
|
||||
using namespace sls;
|
||||
#include <fstream>
|
||||
|
||||
|
||||
TEST_CASE("Default construction"){
|
||||
static_assert(sizeof(CtbConfig) == 360); // 18*20
|
||||
|
||||
CtbConfig c;
|
||||
auto names = c.getDacNames();
|
||||
REQUIRE(names.size() == 18);
|
||||
REQUIRE(names[0] == "dac0");
|
||||
REQUIRE(names[1] == "dac1");
|
||||
REQUIRE(names[2] == "dac2");
|
||||
REQUIRE(names[3] == "dac3");
|
||||
}
|
||||
|
||||
TEST_CASE("Set and get a single dac name"){
|
||||
CtbConfig c;
|
||||
c.setDacName(3, "vrf");
|
||||
auto names = c.getDacNames();
|
||||
|
||||
REQUIRE(c.getDacName(3) == "vrf");
|
||||
REQUIRE(names[3] == "vrf");
|
||||
}
|
||||
|
||||
TEST_CASE("Set a name that is too large throws"){
|
||||
CtbConfig c;
|
||||
REQUIRE_THROWS(c.setDacName(3, "somestringthatisreallytolongforadatac"));
|
||||
}
|
||||
|
||||
TEST_CASE("Length of dac name cannot be 0"){
|
||||
CtbConfig c;
|
||||
REQUIRE_THROWS(c.setDacName(1, ""));
|
||||
}
|
||||
|
||||
TEST_CASE("Copy a CTB config"){
|
||||
CtbConfig c1;
|
||||
c1.setDacName(5, "somename");
|
||||
|
||||
auto c2 = c1;
|
||||
//change the name on the first object
|
||||
//to detecto shallow copy
|
||||
c1.setDacName(5, "someothername");
|
||||
REQUIRE(c2.getDacName(5) == "somename");
|
||||
}
|
||||
|
||||
TEST_CASE("Move CtbConfig "){
|
||||
CtbConfig c1;
|
||||
c1.setDacName(3, "yetanothername");
|
||||
CtbConfig c2(std::move(c1));
|
||||
REQUIRE(c2.getDacName(3) == "yetanothername");
|
||||
}
|
@ -32,8 +32,8 @@ TEST_CASE("Is shm fixed pattern shm compatible") {
|
||||
|
||||
// Set shm version to 0
|
||||
sls::SharedMemory<sls::sharedModule> shm(0, 0);
|
||||
REQUIRE(shm.IsExisting() == true);
|
||||
shm.OpenSharedMemory();
|
||||
REQUIRE(shm.exists() == true);
|
||||
shm.openSharedMemory();
|
||||
shm()->shmversion = 0;
|
||||
|
||||
// Should fail since version is set to 0
|
||||
|
@ -20,8 +20,8 @@ constexpr int shm_id = 10;
|
||||
TEST_CASE("Create SharedMemory read and write", "[detector]") {
|
||||
|
||||
SharedMemory<Data> shm(shm_id, -1);
|
||||
shm.CreateSharedMemory();
|
||||
CHECK(shm.GetName() == std::string("/slsDetectorPackage_detector_") +
|
||||
shm.createSharedMemory();
|
||||
CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") +
|
||||
std::to_string(shm_id));
|
||||
|
||||
shm()->x = 3;
|
||||
@ -32,25 +32,25 @@ TEST_CASE("Create SharedMemory read and write", "[detector]") {
|
||||
CHECK(shm()->y == 5.7);
|
||||
CHECK(std::string(shm()->mess) == "Some string");
|
||||
|
||||
shm.UnmapSharedMemory();
|
||||
shm.RemoveSharedMemory();
|
||||
shm.unmapSharedMemory();
|
||||
shm.removeSharedMemory();
|
||||
|
||||
CHECK(shm.IsExisting() == false);
|
||||
CHECK(shm.exists() == false);
|
||||
}
|
||||
|
||||
TEST_CASE("Open existing SharedMemory and read", "[detector]") {
|
||||
|
||||
{
|
||||
SharedMemory<double> shm(shm_id, -1);
|
||||
shm.CreateSharedMemory();
|
||||
shm.createSharedMemory();
|
||||
*shm() = 5.3;
|
||||
}
|
||||
|
||||
SharedMemory<double> shm2(shm_id, -1);
|
||||
shm2.OpenSharedMemory();
|
||||
shm2.openSharedMemory();
|
||||
CHECK(*shm2() == 5.3);
|
||||
|
||||
shm2.RemoveSharedMemory();
|
||||
shm2.removeSharedMemory();
|
||||
}
|
||||
|
||||
TEST_CASE("Creating a second shared memory with the same name throws",
|
||||
@ -59,24 +59,24 @@ TEST_CASE("Creating a second shared memory with the same name throws",
|
||||
SharedMemory<double> shm0(shm_id, -1);
|
||||
SharedMemory<double> shm1(shm_id, -1);
|
||||
|
||||
shm0.CreateSharedMemory();
|
||||
CHECK_THROWS(shm1.CreateSharedMemory());
|
||||
shm0.RemoveSharedMemory();
|
||||
shm0.createSharedMemory();
|
||||
CHECK_THROWS(shm1.createSharedMemory());
|
||||
shm0.removeSharedMemory();
|
||||
}
|
||||
|
||||
TEST_CASE("Open two shared memories to the same place", "[detector]") {
|
||||
|
||||
// Create the first shared memory
|
||||
SharedMemory<Data> shm(shm_id, -1);
|
||||
shm.CreateSharedMemory();
|
||||
shm.createSharedMemory();
|
||||
shm()->x = 5;
|
||||
CHECK(shm()->x == 5);
|
||||
|
||||
// Open the second shared memory with the same name
|
||||
SharedMemory<Data> shm2(shm_id, -1);
|
||||
shm2.OpenSharedMemory();
|
||||
shm2.openSharedMemory();
|
||||
CHECK(shm2()->x == 5);
|
||||
CHECK(shm.GetName() == shm2.GetName());
|
||||
CHECK(shm.getName() == shm2.getName());
|
||||
|
||||
// Check that they still point to the same place
|
||||
shm2()->x = 7;
|
||||
@ -84,31 +84,28 @@ TEST_CASE("Open two shared memories to the same place", "[detector]") {
|
||||
|
||||
// Remove only needs to be done once since they refer
|
||||
// to the same memory
|
||||
shm2.RemoveSharedMemory();
|
||||
CHECK(shm.IsExisting() == false);
|
||||
CHECK(shm2.IsExisting() == false);
|
||||
shm2.removeSharedMemory();
|
||||
CHECK(shm.exists() == false);
|
||||
CHECK(shm2.exists() == false);
|
||||
}
|
||||
|
||||
TEST_CASE("Move SharedMemory", "[detector]") {
|
||||
|
||||
SharedMemory<Data> shm(shm_id, -1);
|
||||
CHECK(shm.GetName() == std::string("/slsDetectorPackage_detector_") +
|
||||
CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") +
|
||||
std::to_string(shm_id));
|
||||
shm.CreateSharedMemory();
|
||||
shm.createSharedMemory();
|
||||
shm()->x = 9;
|
||||
|
||||
CHECK(shm.size() == sizeof(Data));
|
||||
|
||||
SharedMemory<Data> shm2(shm_id + 1, -1);
|
||||
shm2 = std::move(shm); // shm is now a moved from object!
|
||||
|
||||
CHECK(shm2()->x == 9);
|
||||
CHECK(shm() == nullptr);
|
||||
CHECK(shm.size() == 0);
|
||||
|
||||
CHECK(shm2.GetName() == std::string("/slsDetectorPackage_detector_") +
|
||||
CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") +
|
||||
std::to_string(shm_id));
|
||||
shm2.RemoveSharedMemory();
|
||||
shm2.removeSharedMemory();
|
||||
}
|
||||
|
||||
TEST_CASE("Create several shared memories", "[detector]") {
|
||||
@ -117,20 +114,62 @@ TEST_CASE("Create several shared memories", "[detector]") {
|
||||
v.reserve(N);
|
||||
for (int i = 0; i != N; ++i) {
|
||||
v.emplace_back(shm_id + i, -1);
|
||||
CHECK(v[i].IsExisting() == false);
|
||||
v[i].CreateSharedMemory();
|
||||
CHECK(v[i].exists() == false);
|
||||
v[i].createSharedMemory();
|
||||
*v[i]() = i;
|
||||
CHECK(*v[i]() == i);
|
||||
}
|
||||
|
||||
for (int i = 0; i != N; ++i) {
|
||||
CHECK(*v[i]() == i);
|
||||
CHECK(v[i].GetName() == std::string("/slsDetectorPackage_detector_") +
|
||||
CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") +
|
||||
std::to_string(i + shm_id));
|
||||
}
|
||||
|
||||
for (int i = 0; i != N; ++i) {
|
||||
v[i].RemoveSharedMemory();
|
||||
CHECK(v[i].IsExisting() == false);
|
||||
v[i].removeSharedMemory();
|
||||
CHECK(v[i].exists() == false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Create create a shared memory with a tag"){
|
||||
SharedMemory<int> shm(0, -1, "ctbdacs");
|
||||
REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs");
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set"){
|
||||
|
||||
// if SLSDETNAME is already set we unset it but
|
||||
// save the value
|
||||
std::string old_slsdetname;
|
||||
if (getenv(SHM_ENV_NAME))
|
||||
old_slsdetname = getenv(SHM_ENV_NAME);
|
||||
unsetenv(SHM_ENV_NAME);
|
||||
setenv(SHM_ENV_NAME, "myprefix", 1);
|
||||
|
||||
SharedMemory<int> shm(0, -1, "ctbdacs");
|
||||
REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs");
|
||||
|
||||
// Clean up after us
|
||||
if (old_slsdetname.empty())
|
||||
unsetenv(SHM_ENV_NAME);
|
||||
else
|
||||
setenv(SHM_ENV_NAME, old_slsdetname.c_str(), 1);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("map int64 to int32 throws"){
|
||||
SharedMemory<int32_t> shm(shm_id, -1);
|
||||
shm.createSharedMemory();
|
||||
*shm() = 7;
|
||||
|
||||
SharedMemory<int64_t> shm2(shm_id, -1);
|
||||
REQUIRE_THROWS(shm2.openSharedMemory());
|
||||
|
||||
shm.removeSharedMemory();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -6,12 +6,14 @@ set(SOURCES
|
||||
src/Receiver.cpp
|
||||
src/File.cpp
|
||||
src/BinaryDataFile.cpp
|
||||
src/BinaryMasterFile.cpp
|
||||
src/ThreadObject.cpp
|
||||
src/Listener.cpp
|
||||
src/DataProcessor.cpp
|
||||
src/DataStreamer.cpp
|
||||
src/Fifo.cpp
|
||||
src/Arping.cpp
|
||||
src/MasterAttributes.cpp
|
||||
src/MasterFileUtility.cpp
|
||||
)
|
||||
|
||||
set(PUBLICHEADERS
|
||||
@ -26,8 +28,6 @@ if (SLS_USE_HDF5)
|
||||
)
|
||||
list (APPEND SOURCES
|
||||
src/HDF5DataFile.cpp
|
||||
src/HDF5MasterFile.cpp
|
||||
src/HDF5VirtualFile.cpp
|
||||
)
|
||||
endif (SLS_USE_HDF5)
|
||||
|
||||
@ -40,6 +40,8 @@ add_library(slsReceiverObject OBJECT
|
||||
target_include_directories(slsReceiverObject PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
PRIVATE
|
||||
${SLS_INTERNAL_RAPIDJSON_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(slsReceiverObject
|
||||
|
@ -39,52 +39,50 @@ class Receiver : private virtual slsDetectorDefs {
|
||||
int64_t getReceiverVersion();
|
||||
|
||||
/**
|
||||
* Call back for start acquisition
|
||||
* callback arguments are
|
||||
* filepath
|
||||
* filename
|
||||
* fileindex
|
||||
* datasize
|
||||
*
|
||||
* return value is undefined at the moment
|
||||
* we write depending on file write enable
|
||||
* users get data to write depending on call backs registered
|
||||
* Start Acquisition Call back (slsMultiReceiver writes data if file write enabled)
|
||||
* if registerCallBackRawDataReady or registerCallBackRawDataModifyReady registered,
|
||||
* users get data
|
||||
* callback arguments are:
|
||||
* - file path
|
||||
* - file name prefix
|
||||
* - file index
|
||||
* - image size in bytes
|
||||
*/
|
||||
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
|
||||
uint64_t, uint32_t,
|
||||
void *),
|
||||
void registerCallBackStartAcquisition(int (*func)(const std::string &, const std::string &,
|
||||
uint64_t, size_t, void *),
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* total frames caught
|
||||
* callback argument is:
|
||||
* - total frames caught
|
||||
*/
|
||||
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* sls_receiver_header frame metadata,
|
||||
* dataPointer is the pointer to the data,
|
||||
* dataSize in bytes is the size of the data in bytes.
|
||||
* args to raw data ready callback are:
|
||||
* - sls_receiver_header frame metadata,
|
||||
* - pointer to data
|
||||
* - image size in bytes
|
||||
*/
|
||||
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
|
||||
void *),
|
||||
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
|
||||
char *, size_t, void *),
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Call back for raw data (modified)
|
||||
* args to raw data ready callback are
|
||||
* sls_receiver_header frame metadata,
|
||||
* dataPointer is the pointer to the data,
|
||||
* revDatasize is the reference of data size in bytes.
|
||||
* args to raw data ready callback are:
|
||||
* - sls_receiver_header frame metadata,
|
||||
* - pointer to data
|
||||
* - revDatasize is the reference of data size in bytes.
|
||||
* Can be modified to the new size to be written/streamed. (only smaller
|
||||
* value).
|
||||
* value allowed).
|
||||
*/
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
|
||||
uint32_t &, void *),
|
||||
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
|
||||
char *, size_t &,
|
||||
void *),
|
||||
void *arg);
|
||||
|
||||
private:
|
||||
|
120
slsReceiverSoftware/src/Arping.cpp
Normal file
120
slsReceiverSoftware/src/Arping.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
#include "Arping.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
// gettid added in glibc 2.30
|
||||
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
|
||||
#include <sys/syscall.h>
|
||||
#define gettid() syscall(SYS_gettid)
|
||||
#endif
|
||||
|
||||
void Arping::SetInterfacesAndIps(const int index, const std::string &interface,
|
||||
const std::string &ip) {
|
||||
|
||||
if (interface.empty() || ip.empty()) {
|
||||
throw sls::RuntimeError("Could not arping. Interface name and ip not "
|
||||
"set up for interface " +
|
||||
std::to_string(index));
|
||||
}
|
||||
// create commands to arping
|
||||
std::ostringstream os;
|
||||
os << "arping -c 1 -U -I " << interface << " " << ip;
|
||||
// to read error messages
|
||||
os << " 2>&1";
|
||||
std::string cmd = os.str();
|
||||
commands[index] = cmd;
|
||||
}
|
||||
|
||||
pid_t Arping::GetThreadId() const { return threadId; }
|
||||
|
||||
bool Arping::IsRunning() const { return runningFlag; }
|
||||
|
||||
void Arping::StartThread() {
|
||||
TestCommands();
|
||||
try {
|
||||
t = std::thread(&Arping::ThreadExecution, this);
|
||||
} catch (...) {
|
||||
throw sls::RuntimeError("Could not start arping thread");
|
||||
}
|
||||
runningFlag = true;
|
||||
}
|
||||
|
||||
void Arping::StopThread() {
|
||||
runningFlag = false;
|
||||
t.join();
|
||||
}
|
||||
|
||||
void Arping::ThreadExecution() {
|
||||
threadId = gettid();
|
||||
LOG(logINFOBLUE) << "Created [ Arping Thread, Tid: " << threadId << " ]";
|
||||
|
||||
while (runningFlag) {
|
||||
std::string error = ExecuteCommands();
|
||||
// just print (was already tested at thread start)
|
||||
if (!error.empty()) {
|
||||
LOG(logERROR) << error;
|
||||
}
|
||||
|
||||
// wait for 60s as long as thread not killed
|
||||
int nsecs = 0;
|
||||
while (runningFlag && nsecs != 60) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
++nsecs;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE) << "Exiting [ Arping Thread, Tid: " << threadId << " ]";
|
||||
threadId = 0;
|
||||
}
|
||||
|
||||
void Arping::TestCommands() {
|
||||
// atleast one interface must be set up
|
||||
if (commands[0].empty()) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not arping. Interface not set up in apring thread");
|
||||
}
|
||||
// test if arping commands throw an error
|
||||
std::string error = ExecuteCommands();
|
||||
if (!error.empty()) {
|
||||
throw sls::RuntimeError(error);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Arping::ExecuteCommands() {
|
||||
for (auto cmd : commands) {
|
||||
|
||||
// empty if 2nd interface not enabled
|
||||
if (cmd.empty())
|
||||
continue;
|
||||
|
||||
LOG(logDEBUG) << "Executing Arping Command: " << cmd;
|
||||
|
||||
// execute command
|
||||
FILE *sysFile = popen(cmd.c_str(), "r");
|
||||
if (sysFile == NULL) {
|
||||
std::ostringstream os;
|
||||
os << "Could not Arping [" << cmd << " ] : Popen fail";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// copy output
|
||||
char output[MAX_STR_LENGTH] = {0};
|
||||
fgets(output, sizeof(output), sysFile);
|
||||
output[sizeof(output) - 1] = '\0';
|
||||
|
||||
// check exit status of command
|
||||
if (pclose(sysFile)) {
|
||||
std::ostringstream os;
|
||||
os << "Could not arping[" << cmd << "] : " << output;
|
||||
return os.str();
|
||||
} else {
|
||||
LOG(logDEBUG) << output;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
35
slsReceiverSoftware/src/Arping.h
Normal file
35
slsReceiverSoftware/src/Arping.h
Normal file
@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
/**
|
||||
*@short creates/destroys an ARPing thread to arping the interfaces slsReceiver
|
||||
is listening to.
|
||||
*/
|
||||
|
||||
#include "receiver_defs.h"
|
||||
#include "sls/logger.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
class Arping {
|
||||
|
||||
public:
|
||||
void SetInterfacesAndIps(const int index, const std::string &interface,
|
||||
const std::string &ip);
|
||||
pid_t GetThreadId() const;
|
||||
bool IsRunning() const;
|
||||
void StartThread();
|
||||
void StopThread();
|
||||
|
||||
private:
|
||||
void TestCommands();
|
||||
std::string ExecuteCommands();
|
||||
void ThreadExecution();
|
||||
|
||||
std::vector<std::string> commands =
|
||||
std::vector<std::string>(MAX_NUMBER_OF_LISTENING_THREADS);
|
||||
std::atomic<bool> runningFlag{false};
|
||||
std::thread t;
|
||||
std::atomic<pid_t> threadId{0};
|
||||
};
|
@ -72,7 +72,7 @@ void BinaryDataFile::WriteToFile(char *buffer, const int buffersize,
|
||||
++subFileIndex_;
|
||||
CreateFile();
|
||||
}
|
||||
numFramesInFile_++;
|
||||
++numFramesInFile_;
|
||||
|
||||
// write to file
|
||||
int ret = 0;
|
||||
|
@ -1,60 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "BinaryMasterFile.h"
|
||||
#include "MasterAttributes.h"
|
||||
|
||||
BinaryMasterFile::BinaryMasterFile() : File(BINARY) {}
|
||||
|
||||
BinaryMasterFile::~BinaryMasterFile() { CloseFile(); }
|
||||
|
||||
void BinaryMasterFile::CloseFile() {
|
||||
if (fd_) {
|
||||
fclose(fd_);
|
||||
}
|
||||
fd_ = nullptr;
|
||||
}
|
||||
|
||||
void BinaryMasterFile::CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) {
|
||||
// create file name
|
||||
std::ostringstream os;
|
||||
os << filePath << "/" << fileNamePrefix << "_master"
|
||||
<< "_" << fileIndex << ".raw";
|
||||
fileName_ = os.str();
|
||||
|
||||
// create file
|
||||
if (!overWriteEnable) {
|
||||
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError("Could not create binary master file " +
|
||||
fileName_);
|
||||
}
|
||||
} else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite binary master file " + fileName_);
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Master File: " << fileName_;
|
||||
}
|
||||
attr->WriteMasterBinaryAttributes(fd_);
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
void BinaryMasterFile::UpdateMasterFile(MasterAttributes *attr,
|
||||
bool silentMode) {
|
||||
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "a"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError("Could not append binary master file " +
|
||||
fileName_);
|
||||
}
|
||||
attr->WriteFinalBinaryAttributes(fd_);
|
||||
CloseFile();
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Updated Master File";
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
#include "MasterAttributes.h"
|
||||
|
||||
class BinaryMasterFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
BinaryMasterFile();
|
||||
~BinaryMasterFile();
|
||||
|
||||
void CloseFile() override;
|
||||
void CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) override;
|
||||
void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override;
|
||||
|
||||
private:
|
||||
FILE *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
};
|
@ -19,7 +19,6 @@
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
@ -28,6 +27,12 @@ using sls::RuntimeError;
|
||||
using sls::SocketError;
|
||||
using Interface = sls::ServerInterface;
|
||||
|
||||
// gettid added in glibc 2.30
|
||||
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
|
||||
#include <sys/syscall.h>
|
||||
#define gettid() syscall(SYS_gettid)
|
||||
#endif
|
||||
|
||||
ClientInterface::~ClientInterface() {
|
||||
killTcpThread = true;
|
||||
LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber;
|
||||
@ -41,7 +46,7 @@ ClientInterface::ClientInterface(int portNumber)
|
||||
portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2),
|
||||
server(portNumber) {
|
||||
functionTable();
|
||||
parentThreadId = syscall(SYS_gettid);
|
||||
parentThreadId = gettid();
|
||||
tcpThread =
|
||||
sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this);
|
||||
}
|
||||
@ -50,7 +55,7 @@ int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; }
|
||||
|
||||
/***callback functions***/
|
||||
void ClientInterface::registerCallBackStartAcquisition(
|
||||
int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
|
||||
int (*func)(const std::string &, const std::string &, uint64_t, size_t, void *),
|
||||
void *arg) {
|
||||
startAcquisitionCallBack = func;
|
||||
pStartAcquisition = arg;
|
||||
@ -64,19 +69,19 @@ void ClientInterface::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
|
||||
}
|
||||
|
||||
void ClientInterface::registerCallBackRawDataReady(
|
||||
void (*func)(char *, char *, uint32_t, void *), void *arg) {
|
||||
void (*func)(sls_receiver_header *, char *, size_t, void *), void *arg) {
|
||||
rawDataReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
|
||||
void ClientInterface::registerCallBackRawDataModifyReady(
|
||||
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
|
||||
void (*func)(sls_receiver_header *, char *, size_t &, void *), void *arg) {
|
||||
rawDataModifyReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
|
||||
void ClientInterface::startTCPServer() {
|
||||
tcpThreadId = syscall(SYS_gettid);
|
||||
tcpThreadId = gettid();
|
||||
LOG(logINFOBLUE) << "Created [ TCP server Tid: " << tcpThreadId << "]";
|
||||
LOG(logINFO) << "SLS Receiver starting TCP Server on port " << portNumber
|
||||
<< '\n';
|
||||
@ -210,7 +215,8 @@ int ClientInterface::functionTable(){
|
||||
flist[F_SET_RECEIVER_STREAMING_HWM] = &ClientInterface::set_streaming_hwm;
|
||||
flist[F_RECEIVER_SET_ALL_THRESHOLD] = &ClientInterface::set_all_threshold;
|
||||
flist[F_RECEIVER_SET_DATASTREAM] = &ClientInterface::set_detector_datastream;
|
||||
|
||||
flist[F_GET_RECEIVER_ARPING] = &ClientInterface::get_arping;
|
||||
flist[F_SET_RECEIVER_ARPING] = &ClientInterface::set_arping;
|
||||
|
||||
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
|
||||
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
|
||||
@ -710,6 +716,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
|
||||
break;
|
||||
*/
|
||||
case 4:
|
||||
case 12:
|
||||
if (detType == EIGER) {
|
||||
exists = true;
|
||||
}
|
||||
@ -841,9 +848,13 @@ int ClientInterface::get_file_index(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::get_frame_index(Interface &socket) {
|
||||
uint64_t retval = impl()->getCurrentFrameIndex();
|
||||
LOG(logDEBUG1) << "frame index:" << retval;
|
||||
return socket.sendResult(retval);
|
||||
auto retval = impl()->getCurrentFrameIndex();
|
||||
LOG(logDEBUG1) << "frames index:" << sls::ToString(retval);
|
||||
auto size = static_cast<int>(retval.size());
|
||||
socket.Send(OK);
|
||||
socket.Send(size);
|
||||
socket.Send(retval);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ClientInterface::get_missing_packets(Interface &socket) {
|
||||
@ -857,9 +868,13 @@ int ClientInterface::get_missing_packets(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::get_frames_caught(Interface &socket) {
|
||||
int64_t retval = impl()->getFramesCaught();
|
||||
LOG(logDEBUG1) << "frames caught:" << retval;
|
||||
return socket.sendResult(retval);
|
||||
auto retval = impl()->getFramesCaught();
|
||||
LOG(logDEBUG1) << "frames caught:" << sls::ToString(retval);
|
||||
auto size = static_cast<int>(retval.size());
|
||||
socket.Send(OK);
|
||||
socket.Send(size);
|
||||
socket.Send(retval);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ClientInterface::set_file_write(Interface &socket) {
|
||||
@ -1398,9 +1413,13 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
|
||||
if (detType == EIGER) {
|
||||
impl()->setEthernetInterface2(eth);
|
||||
}
|
||||
|
||||
// update locally to use for arping
|
||||
udpips[0] = arg.str();
|
||||
|
||||
// get mac address
|
||||
auto retval = sls::InterfaceNameToMac(eth);
|
||||
if (retval == 0) {
|
||||
if (retval == 0 && arg.str() != LOCALHOST_IP) {
|
||||
throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" +
|
||||
eth + ", ip:" + arg.str() + ")\n");
|
||||
}
|
||||
@ -1430,9 +1449,12 @@ sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
|
||||
}
|
||||
impl()->setEthernetInterface2(eth);
|
||||
|
||||
// update locally to use for arping
|
||||
udpips[1] = arg.str();
|
||||
|
||||
// get mac address
|
||||
auto retval = sls::InterfaceNameToMac(eth);
|
||||
if (retval == 0) {
|
||||
if (retval == 0 && arg.str() != LOCALHOST_IP) {
|
||||
throw RuntimeError(
|
||||
"Failed to get udp mac adddress2 to listen to (eth:" + eth +
|
||||
", ip:" + arg.str() + ")\n");
|
||||
@ -1697,3 +1719,20 @@ int ClientInterface::set_detector_datastream(Interface &socket) {
|
||||
impl()->setDetectorDataStream(port, enable);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
int ClientInterface::get_arping(Interface &socket) {
|
||||
auto retval = static_cast<int>(impl()->getArping());
|
||||
LOG(logDEBUG1) << "arping thread status:" << retval;
|
||||
return socket.sendResult(retval);
|
||||
}
|
||||
|
||||
int ClientInterface::set_arping(Interface &socket) {
|
||||
auto value = socket.Receive<int>();
|
||||
if (value < 0) {
|
||||
throw RuntimeError("Invalid arping value: " + std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Starting/ Killing arping thread:" << value;
|
||||
impl()->setArping(value, udpips);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
@ -30,25 +30,24 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int64_t getReceiverVersion();
|
||||
|
||||
//***callback functions***
|
||||
/** params: filepath, filename, fileindex, datasize */
|
||||
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
|
||||
uint64_t, uint32_t,
|
||||
void *),
|
||||
/** params: file path, file name, file index, image size */
|
||||
void registerCallBackStartAcquisition(int (*func)(const std::string &, const std::string &,
|
||||
uint64_t, size_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 *),
|
||||
/** params: sls_receiver_header pointer, pointer to data, image size */
|
||||
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
|
||||
char *, size_t, void *),
|
||||
void *arg);
|
||||
|
||||
/** params: sls_receiver_header frame metadata, dataPointer, modified size
|
||||
*/
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
|
||||
uint32_t &, void *),
|
||||
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
|
||||
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
|
||||
char *, size_t &,
|
||||
void *),
|
||||
void *arg);
|
||||
|
||||
private:
|
||||
@ -163,6 +162,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int set_streaming_hwm(sls::ServerInterface &socket);
|
||||
int set_all_threshold(sls::ServerInterface &socket);
|
||||
int set_detector_datastream(sls::ServerInterface &socket);
|
||||
int get_arping(sls::ServerInterface &socket);
|
||||
int set_arping(sls::ServerInterface &socket);
|
||||
|
||||
Implementation *impl() {
|
||||
if (receiver != nullptr) {
|
||||
@ -178,16 +179,19 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
|
||||
//***callback parameters***
|
||||
|
||||
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
|
||||
uint32_t, void *) = nullptr;
|
||||
int (*startAcquisitionCallBack)(const std::string &, const std::string &, uint64_t, size_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 (*rawDataReadyCallBack)(sls_receiver_header *, char *, size_t,
|
||||
void *) = nullptr;
|
||||
void (*rawDataModifyReadyCallBack)(sls_receiver_header *, char *, size_t &,
|
||||
void *) = nullptr;
|
||||
void *pRawDataReady{nullptr};
|
||||
|
||||
pid_t parentThreadId{0};
|
||||
pid_t tcpThreadId{0};
|
||||
std::vector<std::string> udpips =
|
||||
std::vector<std::string>(MAX_NUMBER_OF_LISTENING_THREADS);
|
||||
};
|
||||
|
@ -9,14 +9,12 @@
|
||||
|
||||
#include "DataProcessor.h"
|
||||
#include "BinaryDataFile.h"
|
||||
#include "BinaryMasterFile.h"
|
||||
#include "Fifo.h"
|
||||
#include "GeneralData.h"
|
||||
#include "MasterAttributes.h"
|
||||
#include "MasterFileUtility.h"
|
||||
#ifdef HDF5C
|
||||
#include "HDF5DataFile.h"
|
||||
#include "HDF5MasterFile.h"
|
||||
#include "HDF5VirtualFile.h"
|
||||
#endif
|
||||
#include "DataStreamer.h"
|
||||
#include "sls/container_utils.h"
|
||||
@ -44,27 +42,11 @@ DataProcessor::DataProcessor(int index, detectorType detectorType, Fifo *fifo,
|
||||
ctbAnalogDataBytes_(ctbAnalogDataBytes), firstStreamerFrame_(false) {
|
||||
|
||||
LOG(logDEBUG) << "DataProcessor " << index << " created";
|
||||
|
||||
memset((void *)&timerbegin_, 0, sizeof(timespec));
|
||||
}
|
||||
|
||||
DataProcessor::~DataProcessor() { DeleteFiles(); }
|
||||
|
||||
/** getters */
|
||||
|
||||
bool DataProcessor::GetStartedFlag() { return startedFlag_; }
|
||||
|
||||
uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught_; }
|
||||
|
||||
uint64_t DataProcessor::GetNumCompleteFramesCaught() {
|
||||
return numCompleteFramesCaught_;
|
||||
}
|
||||
|
||||
uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex_; }
|
||||
|
||||
uint64_t DataProcessor::GetProcessedIndex() {
|
||||
return currentFrameIndex_ - firstIndex_;
|
||||
}
|
||||
bool DataProcessor::GetStartedFlag() const { return startedFlag_; }
|
||||
|
||||
void DataProcessor::SetFifo(Fifo *fifo) { fifo_ = fifo; }
|
||||
|
||||
@ -72,7 +54,6 @@ void DataProcessor::ResetParametersforNewAcquisition() {
|
||||
StopRunning();
|
||||
startedFlag_ = false;
|
||||
numFramesCaught_ = 0;
|
||||
numCompleteFramesCaught_ = 0;
|
||||
firstIndex_ = 0;
|
||||
currentFrameIndex_ = 0;
|
||||
firstStreamerFrame_ = true;
|
||||
@ -81,10 +62,8 @@ void DataProcessor::ResetParametersforNewAcquisition() {
|
||||
void DataProcessor::RecordFirstIndex(uint64_t fnum) {
|
||||
// listen to this fnum, later +1
|
||||
currentFrameIndex_ = fnum;
|
||||
|
||||
startedFlag_ = true;
|
||||
firstIndex_ = fnum;
|
||||
|
||||
LOG(logDEBUG1) << index << " First Index:" << firstIndex_;
|
||||
}
|
||||
|
||||
@ -95,53 +74,26 @@ void DataProcessor::SetGeneralData(GeneralData *generalData) {
|
||||
void DataProcessor::CloseFiles() {
|
||||
if (dataFile_)
|
||||
dataFile_->CloseFile();
|
||||
if (masterFile_)
|
||||
masterFile_->CloseFile();
|
||||
#ifdef HDF5C
|
||||
if (virtualFile_)
|
||||
virtualFile_->CloseFile();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DataProcessor::DeleteFiles() {
|
||||
CloseFiles();
|
||||
if (dataFile_) {
|
||||
delete dataFile_;
|
||||
dataFile_ = nullptr;
|
||||
}
|
||||
if (masterFile_) {
|
||||
delete masterFile_;
|
||||
masterFile_ = nullptr;
|
||||
}
|
||||
#ifdef HDF5C
|
||||
if (virtualFile_) {
|
||||
delete virtualFile_;
|
||||
virtualFile_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
delete dataFile_;
|
||||
dataFile_ = nullptr;
|
||||
}
|
||||
void DataProcessor::SetupFileWriter(const bool filewriteEnable,
|
||||
const bool masterFilewriteEnable,
|
||||
const fileFormat fileFormatType,
|
||||
const int modulePos, std::mutex *hdf5Lib) {
|
||||
std::mutex *hdf5LibMutex) {
|
||||
DeleteFiles();
|
||||
if (filewriteEnable) {
|
||||
switch (fileFormatType) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
dataFile_ = new HDF5DataFile(index, hdf5Lib);
|
||||
if (modulePos == 0 && index == 0) {
|
||||
if (masterFilewriteEnable) {
|
||||
masterFile_ = new HDF5MasterFile(hdf5Lib);
|
||||
}
|
||||
}
|
||||
dataFile_ = new HDF5DataFile(index, hdf5LibMutex);
|
||||
break;
|
||||
#endif
|
||||
case BINARY:
|
||||
dataFile_ = new BinaryDataFile(index);
|
||||
if (modulePos == 0 && index == 0 && masterFilewriteEnable) {
|
||||
masterFile_ = new BinaryMasterFile();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError(
|
||||
@ -151,23 +103,17 @@ void DataProcessor::SetupFileWriter(const bool filewriteEnable,
|
||||
}
|
||||
|
||||
void DataProcessor::CreateFirstFiles(
|
||||
MasterAttributes *attr, const std::string filePath,
|
||||
const std::string fileNamePrefix, const uint64_t fileIndex,
|
||||
const bool overWriteEnable, const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t dynamicRange, const bool detectorDataStream) {
|
||||
const std::string &filePath, const std::string &fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
|
||||
const int modulePos, const int numUnitsPerReadout,
|
||||
const uint32_t udpPortNumber, const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages, const uint32_t dynamicRange,
|
||||
const bool detectorDataStream) {
|
||||
if (dataFile_ == nullptr) {
|
||||
throw sls::RuntimeError("file object not contstructed");
|
||||
}
|
||||
CloseFiles();
|
||||
|
||||
// master file write enabled
|
||||
if (masterFile_) {
|
||||
masterFile_->CreateMasterFile(filePath, fileNamePrefix, fileIndex,
|
||||
overWriteEnable, silentMode, attr);
|
||||
}
|
||||
|
||||
// deactivated (half module/ single port), dont write file
|
||||
if ((!*activated_) || (!detectorDataStream)) {
|
||||
return;
|
||||
@ -202,98 +148,86 @@ uint32_t DataProcessor::GetFilesInAcquisition() const {
|
||||
return dataFile_->GetFilesInAcquisition();
|
||||
}
|
||||
|
||||
void DataProcessor::CreateVirtualFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
std::array<std::string, 2> DataProcessor::CreateVirtualFile(
|
||||
const std::string &filePath, const std::string &fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
|
||||
const int modulePos, const int numUnitsPerReadout,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t dynamicRange, const int numModX, const int numModY,
|
||||
std::mutex *hdf5Lib) {
|
||||
const int numModX, const int numModY, const uint32_t dynamicRange,
|
||||
std::mutex *hdf5LibMutex) {
|
||||
|
||||
if (virtualFile_) {
|
||||
delete virtualFile_;
|
||||
}
|
||||
virtualFile_ = new HDF5VirtualFile(hdf5Lib);
|
||||
bool gotthard25um =
|
||||
((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) &&
|
||||
(numModX * numModY) == 2);
|
||||
|
||||
uint64_t numImagesProcessed = GetProcessedIndex() + 1;
|
||||
// maxframesperfile = 0 for infinite files
|
||||
uint32_t framesPerFile =
|
||||
((maxFramesPerFile == 0) ? numImagesProcessed + 1 : maxFramesPerFile);
|
||||
((maxFramesPerFile == 0) ? numFramesCaught_ : maxFramesPerFile);
|
||||
|
||||
// TODO: assumption 1: create virtual file even if no data in other
|
||||
// files (they exist anyway) assumption2: virtual file max frame index
|
||||
// is from R0 P0 (difference from others when missing frames or for a
|
||||
// stop acquisition)
|
||||
virtualFile_->CreateVirtualFile(
|
||||
return masterFileUtility::CreateVirtualHDF5File(
|
||||
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
|
||||
modulePos, numUnitsPerReadout, framesPerFile, numImages,
|
||||
generalData_->nPixelsX, generalData_->nPixelsY, dynamicRange,
|
||||
numImagesProcessed, numModX, numModY, dataFile_->GetPDataType(),
|
||||
dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes());
|
||||
numFramesCaught_, numModX, numModY, dataFile_->GetPDataType(),
|
||||
dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes(),
|
||||
hdf5LibMutex, gotthard25um);
|
||||
}
|
||||
|
||||
void DataProcessor::LinkDataInMasterFile(const bool silentMode) {
|
||||
std::string fname, datasetName;
|
||||
if (virtualFile_) {
|
||||
auto res = virtualFile_->GetFileAndDatasetName();
|
||||
fname = res[0];
|
||||
datasetName = res[1];
|
||||
} else {
|
||||
void DataProcessor::LinkFileInMaster(const std::string &masterFileName,
|
||||
const std::string &virtualFileName,
|
||||
const std::string &virtualDatasetName,
|
||||
const bool silentMode,
|
||||
std::mutex *hdf5LibMutex) {
|
||||
std::string fname{virtualFileName}, datasetName{virtualDatasetName};
|
||||
// if no virtual file, link data file
|
||||
if (virtualFileName.empty()) {
|
||||
auto res = dataFile_->GetFileAndDatasetName();
|
||||
fname = res[0];
|
||||
datasetName = res[1];
|
||||
}
|
||||
// link in master
|
||||
masterFile_->LinkDataFile(fname, datasetName,
|
||||
dataFile_->GetParameterNames(), silentMode);
|
||||
masterFileUtility::LinkHDF5FileInMaster(masterFileName, fname, datasetName,
|
||||
dataFile_->GetParameterNames(),
|
||||
silentMode, hdf5LibMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
void DataProcessor::UpdateMasterFile(bool silentMode) {
|
||||
if (masterFile_) {
|
||||
// final attributes
|
||||
std::unique_ptr<MasterAttributes> masterAttributes;
|
||||
switch (detectorType_) {
|
||||
case GOTTHARD:
|
||||
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
|
||||
break;
|
||||
case JUNGFRAU:
|
||||
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
|
||||
break;
|
||||
case EIGER:
|
||||
masterAttributes = sls::make_unique<EigerMasterAttributes>();
|
||||
break;
|
||||
case MYTHEN3:
|
||||
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
|
||||
break;
|
||||
case GOTTHARD2:
|
||||
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
|
||||
break;
|
||||
case MOENCH:
|
||||
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
masterAttributes = sls::make_unique<CtbMasterAttributes>();
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError(
|
||||
"Unknown detector type to set up master file attributes");
|
||||
}
|
||||
masterAttributes->framesInFile = numFramesCaught_;
|
||||
masterFile_->UpdateMasterFile(masterAttributes.get(), silentMode);
|
||||
std::string DataProcessor::CreateMasterFile(
|
||||
const std::string &filePath, const std::string &fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, bool silentMode,
|
||||
const fileFormat fileFormatType, MasterAttributes *attr,
|
||||
std::mutex *hdf5LibMutex) {
|
||||
|
||||
attr->framesInFile = numFramesCaught_;
|
||||
|
||||
std::unique_ptr<File> masterFile{nullptr};
|
||||
switch (fileFormatType) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
return masterFileUtility::CreateMasterHDF5File(
|
||||
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
|
||||
attr, hdf5LibMutex);
|
||||
#endif
|
||||
case BINARY:
|
||||
return masterFileUtility::CreateMasterBinaryFile(
|
||||
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
|
||||
attr);
|
||||
default:
|
||||
throw sls::RuntimeError("Unknown file format (compile with hdf5 flags");
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::ThreadExecution() {
|
||||
char *buffer = nullptr;
|
||||
fifo_->PopAddress(buffer);
|
||||
LOG(logDEBUG5) << "DataProcessor " << index
|
||||
<< ", "
|
||||
"pop 0x"
|
||||
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
|
||||
LOG(logDEBUG5) << "DataProcessor " << index << ", " << std::hex
|
||||
<< static_cast<void *>(buffer) << std::dec << ":" << buffer;
|
||||
|
||||
// check dummy
|
||||
auto numBytes = (uint32_t)(*((uint32_t *)buffer));
|
||||
auto numBytes = *reinterpret_cast<uint32_t *>(buffer);
|
||||
LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes;
|
||||
if (numBytes == DUMMY_PACKET_VALUE) {
|
||||
StopProcessing(buffer);
|
||||
@ -338,15 +272,12 @@ void DataProcessor::StopProcessing(char *buf) {
|
||||
|
||||
uint64_t DataProcessor::ProcessAnImage(char *buf) {
|
||||
|
||||
auto *rheader = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
auto *rheader = reinterpret_cast<sls_receiver_header *>(buf + FIFO_HEADER_NUMBYTES);
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
uint64_t fnum = header.frameNumber;
|
||||
currentFrameIndex_ = fnum;
|
||||
numFramesCaught_++;
|
||||
uint32_t nump = header.packetNumber;
|
||||
if (nump == generalData_->packetsPerFrame) {
|
||||
numCompleteFramesCaught_++;
|
||||
}
|
||||
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum;
|
||||
|
||||
@ -375,16 +306,17 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
|
||||
try {
|
||||
// normal call back
|
||||
if (rawDataReadyCallBack != nullptr) {
|
||||
rawDataReadyCallBack((char *)rheader,
|
||||
std::size_t dsize = *reinterpret_cast<uint32_t *>(buf);
|
||||
rawDataReadyCallBack(rheader,
|
||||
buf + FIFO_HEADER_NUMBYTES +
|
||||
sizeof(sls_receiver_header),
|
||||
(uint32_t)(*((uint32_t *)buf)), pRawDataReady);
|
||||
dsize, pRawDataReady);
|
||||
}
|
||||
|
||||
// call back with modified size
|
||||
else if (rawDataModifyReadyCallBack != nullptr) {
|
||||
auto revsize = (uint32_t)(*((uint32_t *)buf));
|
||||
rawDataModifyReadyCallBack((char *)rheader,
|
||||
std::size_t revsize = *reinterpret_cast<uint32_t *>(buf);
|
||||
rawDataModifyReadyCallBack(rheader,
|
||||
buf + FIFO_HEADER_NUMBYTES +
|
||||
sizeof(sls_receiver_header),
|
||||
revsize, pRawDataReady);
|
||||
@ -428,14 +360,15 @@ bool DataProcessor::CheckTimer() {
|
||||
struct timespec end;
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
|
||||
LOG(logDEBUG1) << index << " Timer elapsed time:"
|
||||
<< ((end.tv_sec - timerbegin_.tv_sec) +
|
||||
(end.tv_nsec - timerbegin_.tv_nsec) / 1000000000.0)
|
||||
auto elapsed_s = (end.tv_sec - timerbegin_.tv_sec) +
|
||||
(end.tv_nsec - timerbegin_.tv_nsec) / 1e9;
|
||||
double timer_s = *streamingTimerInMs_ / 1e3;
|
||||
|
||||
LOG(logDEBUG1) << index << " Timer elapsed time:" << elapsed_s
|
||||
<< " seconds";
|
||||
|
||||
// still less than streaming timer, keep waiting
|
||||
if (((end.tv_sec - timerbegin_.tv_sec) +
|
||||
(end.tv_nsec - timerbegin_.tv_nsec) / 1000000000.0) <
|
||||
((double)*streamingTimerInMs_ / 1000.00))
|
||||
if (elapsed_s < timer_s)
|
||||
return false;
|
||||
|
||||
// restart timer
|
||||
@ -452,15 +385,14 @@ bool DataProcessor::CheckCount() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DataProcessor::registerCallBackRawDataReady(void (*func)(char *, char *,
|
||||
uint32_t, void *),
|
||||
void *arg) {
|
||||
void DataProcessor::registerCallBackRawDataReady(
|
||||
void (*func)(sls_receiver_header *, char *, size_t, void *), void *arg) {
|
||||
rawDataReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
|
||||
void DataProcessor::registerCallBackRawDataModifyReady(
|
||||
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
|
||||
void (*func)(sls_receiver_header *, char *, size_t &, void *), void *arg) {
|
||||
rawDataModifyReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
@ -469,7 +401,8 @@ void DataProcessor::PadMissingPackets(char *buf) {
|
||||
LOG(logDEBUG) << index << ": Padding Missing Packets";
|
||||
|
||||
uint32_t pperFrame = generalData_->packetsPerFrame;
|
||||
auto *header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
auto *header =
|
||||
reinterpret_cast<sls_receiver_header *>(buf + FIFO_HEADER_NUMBYTES);
|
||||
uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
|
||||
sls_bitset pmask = header->packetsMask;
|
||||
|
||||
@ -542,7 +475,7 @@ void DataProcessor::RearrangeDbitData(char *buf) {
|
||||
|
||||
// ceil as numResult8Bits could be decimal
|
||||
const int numResult8Bits =
|
||||
ceil((double)(numSamples * (*ctbDbitList_).size()) / 8.00);
|
||||
ceil((numSamples * (*ctbDbitList_).size()) / 8.00);
|
||||
std::vector<uint8_t> result(numResult8Bits);
|
||||
uint8_t *dest = &result[0];
|
||||
|
||||
@ -558,7 +491,7 @@ void DataProcessor::RearrangeDbitData(char *buf) {
|
||||
}
|
||||
|
||||
// loop through the frame digital data
|
||||
for (auto ptr = source; ptr < (source + numSamples);) {
|
||||
for (auto *ptr = source; ptr < (source + numSamples);) {
|
||||
// get selected bit from each 8 bit
|
||||
uint8_t bit = (*ptr++ >> bi) & 1;
|
||||
*dest |= bit << bitoffset;
|
||||
|
@ -36,13 +36,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
~DataProcessor() override;
|
||||
|
||||
bool GetStartedFlag();
|
||||
uint64_t GetNumFramesCaught();
|
||||
uint64_t GetNumCompleteFramesCaught();
|
||||
/** (-1 if no frames have been caught */
|
||||
uint64_t GetCurrentFrameIndex();
|
||||
/** (-1 if no frames have been caught) */
|
||||
uint64_t GetProcessedIndex();
|
||||
bool GetStartedFlag() const;
|
||||
|
||||
void SetFifo(Fifo *f);
|
||||
void ResetParametersforNewAcquisition();
|
||||
@ -51,12 +45,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
void CloseFiles();
|
||||
void DeleteFiles();
|
||||
void SetupFileWriter(const bool filewriteEnable,
|
||||
const bool masterFilewriteEnable,
|
||||
const fileFormat fileFormatType, const int modulePos,
|
||||
std::mutex *hdf5Lib);
|
||||
const fileFormat fileFormatType,
|
||||
std::mutex *hdf5LibMutex);
|
||||
|
||||
void CreateFirstFiles(MasterAttributes *attr, const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
void CreateFirstFiles(const std::string &filePath,
|
||||
const std::string &fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout,
|
||||
@ -66,40 +59,36 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
const bool detectorDataStream);
|
||||
#ifdef HDF5C
|
||||
uint32_t GetFilesInAcquisition() const;
|
||||
void CreateVirtualFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout,
|
||||
const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages,
|
||||
const uint32_t dynamicRange, const int numModX,
|
||||
const int numModY, std::mutex *hdf5Lib);
|
||||
void LinkDataInMasterFile(const bool silentMode);
|
||||
std::array<std::string, 2> CreateVirtualFile(
|
||||
const std::string &filePath, const std::string &fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages, const int numModX, const int numModY,
|
||||
const uint32_t dynamicRange, std::mutex *hdf5LibMutex);
|
||||
void LinkFileInMaster(const std::string &masterFileName,
|
||||
const std::string &virtualFileName,
|
||||
const std::string &virtualDatasetName,
|
||||
const bool silentMode, std::mutex *hdf5LibMutex);
|
||||
#endif
|
||||
void UpdateMasterFile(bool silentMode);
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* sls_receiver_header frame metadata
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes.
|
||||
*/
|
||||
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
|
||||
void *),
|
||||
|
||||
std::string CreateMasterFile(const std::string &filePath,
|
||||
const std::string &fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable, bool silentMode,
|
||||
const fileFormat fileFormatType,
|
||||
MasterAttributes *attr,
|
||||
std::mutex *hdf5LibMutex);
|
||||
|
||||
/** params: sls_receiver_header pointer, pointer to data, image size */
|
||||
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
|
||||
char *, size_t, void *),
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Call back for raw data (modified)
|
||||
* args to raw data ready callback are
|
||||
* sls_receiver_header frame metadata
|
||||
* dataPointer is the pointer to the data
|
||||
* revDatasize is the reference of data size in bytes.
|
||||
* Can be modified to the new size to be written/streamed. (only smaller
|
||||
* value).
|
||||
*/
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
|
||||
uint32_t &, void *),
|
||||
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
|
||||
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
|
||||
char *, size_t &,
|
||||
void *),
|
||||
void *arg);
|
||||
|
||||
private:
|
||||
@ -166,7 +155,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
uint32_t *streamingTimerInMs_;
|
||||
uint32_t *streamingStartFnum_;
|
||||
uint32_t currentFreqCount_{0};
|
||||
struct timespec timerbegin_;
|
||||
struct timespec timerbegin_{};
|
||||
bool *framePadding_;
|
||||
std::vector<int> *ctbDbitList_;
|
||||
int *ctbDbitOffset_;
|
||||
@ -178,9 +167,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** Number of frames caught */
|
||||
uint64_t numFramesCaught_{0};
|
||||
|
||||
/** Number of complete frames caught */
|
||||
uint64_t numCompleteFramesCaught_{0};
|
||||
|
||||
/** Frame Number of latest processed frame number */
|
||||
std::atomic<uint64_t> currentFrameIndex_{0};
|
||||
|
||||
@ -188,10 +174,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
bool firstStreamerFrame_{false};
|
||||
|
||||
File *dataFile_{nullptr};
|
||||
File *masterFile_{nullptr};
|
||||
#ifdef HDF5C
|
||||
File *virtualFile_{nullptr};
|
||||
#endif
|
||||
|
||||
// call back
|
||||
/**
|
||||
@ -201,7 +183,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes.
|
||||
*/
|
||||
void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr;
|
||||
void (*rawDataReadyCallBack)(sls_receiver_header *, char *, size_t,
|
||||
void *) = nullptr;
|
||||
|
||||
/**
|
||||
* Call back for raw data (modified)
|
||||
@ -211,7 +194,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* revDatasize is the reference of data size in bytes. Can be modified to
|
||||
* the new size to be written/streamed. (only smaller value).
|
||||
*/
|
||||
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
|
||||
void (*rawDataModifyReadyCallBack)(sls_receiver_header *, char *, size_t &,
|
||||
void *) = nullptr;
|
||||
|
||||
void *pRawDataReady{nullptr};
|
||||
|
@ -17,12 +17,11 @@
|
||||
const std::string DataStreamer::TypeName = "DataStreamer";
|
||||
|
||||
DataStreamer::DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi,
|
||||
bool fr, slsDetectorDefs::xy nm, bool *qe,
|
||||
bool fr, slsDetectorDefs::xy np, bool *qe,
|
||||
uint64_t *tot)
|
||||
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), roi(r),
|
||||
fileIndex(fi), flipRows(fr), quadEnable(qe), totalNumFrames(tot) {
|
||||
numMods.x = nm.x;
|
||||
numMods.y = nm.y;
|
||||
fileIndex(fi), flipRows(fr), numPorts(np), quadEnable(qe),
|
||||
totalNumFrames(tot) {
|
||||
|
||||
LOG(logDEBUG) << "DataStreamer " << ind << " created";
|
||||
}
|
||||
@ -63,10 +62,7 @@ void DataStreamer::RecordFirstIndex(uint64_t fnum, char *buf) {
|
||||
|
||||
void DataStreamer::SetGeneralData(GeneralData *g) { generalData = g; }
|
||||
|
||||
void DataStreamer::SetNumberofModules(xy nm) {
|
||||
numMods.x = nm.x;
|
||||
numMods.y = nm.y;
|
||||
}
|
||||
void DataStreamer::SetNumberofPorts(xy np) { numPorts = np; }
|
||||
|
||||
void DataStreamer::SetFlipRows(bool fd) { flipRows = fd; }
|
||||
|
||||
@ -220,8 +216,8 @@ int DataStreamer::SendHeader(sls_receiver_header *rheader, uint32_t size,
|
||||
|
||||
zHeader.dynamicRange = *dynamicRange;
|
||||
zHeader.fileIndex = *fileIndex;
|
||||
zHeader.ndetx = numMods.x;
|
||||
zHeader.ndety = numMods.y;
|
||||
zHeader.ndetx = numPorts.x;
|
||||
zHeader.ndety = numPorts.y;
|
||||
zHeader.npixelsx = nx;
|
||||
zHeader.npixelsy = ny;
|
||||
zHeader.imageSize = size;
|
||||
|
@ -33,12 +33,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* @param r roi
|
||||
* @param fi pointer to file index
|
||||
* @param fr flip rows
|
||||
* @param nm number of modules in each dimension
|
||||
* @param nm number of ports in each dimension
|
||||
* @param qe pointer to quad Enable
|
||||
* @param tot pointer to total number of frames
|
||||
*/
|
||||
DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi, bool fr,
|
||||
xy nm, bool *qe, uint64_t *tot);
|
||||
xy np, bool *qe, uint64_t *tot);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -46,39 +46,11 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
~DataStreamer();
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo *f);
|
||||
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition(const std::string &fname);
|
||||
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData *g);
|
||||
|
||||
/**
|
||||
* Set number of detectors
|
||||
* @param nm number of modules/ports in both dimensions
|
||||
*/
|
||||
void SetNumberofModules(xy nm);
|
||||
|
||||
/**
|
||||
* Set Flipped rows
|
||||
* @param fd flip rows enable
|
||||
*/
|
||||
void SetNumberofPorts(xy np);
|
||||
void SetFlipRows(bool fd);
|
||||
|
||||
/**
|
||||
* Set additional json header
|
||||
* @param json additional json header
|
||||
*/
|
||||
void
|
||||
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
|
||||
|
||||
@ -143,34 +115,16 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
int SendHeader(sls_receiver_header *rheader, uint32_t size = 0,
|
||||
uint32_t nx = 0, uint32_t ny = 0, bool dummy = true);
|
||||
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
const GeneralData *generalData{nullptr};
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo *fifo;
|
||||
|
||||
/** ZMQ Socket - Receiver to Client */
|
||||
ZmqSocket *zmqSocket{nullptr};
|
||||
|
||||
/** Pointer to dynamic range */
|
||||
uint32_t *dynamicRange;
|
||||
|
||||
/** ROI */
|
||||
ROI *roi;
|
||||
|
||||
/** adc Configured */
|
||||
int adcConfigured{-1};
|
||||
|
||||
/** Pointer to file index */
|
||||
uint64_t *fileIndex;
|
||||
|
||||
/** flip rows */
|
||||
bool flipRows;
|
||||
|
||||
/** additional json header */
|
||||
std::map<std::string, std::string> additionalJsonHeader;
|
||||
|
||||
/** Used by streamer thread to update local copy (reduce number of locks
|
||||
@ -189,18 +143,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex{0};
|
||||
|
||||
/* File name to stream */
|
||||
std::string fileNametoStream;
|
||||
|
||||
/** Complete buffer used for roi, eg. shortGotthard */
|
||||
char *completeBuffer{nullptr};
|
||||
|
||||
/** Number of Modules in X and Y dimension */
|
||||
xy numMods{1, 1};
|
||||
|
||||
/** Quad Enable */
|
||||
xy numPorts{1, 1};
|
||||
bool *quadEnable;
|
||||
|
||||
/** Total number of frames */
|
||||
uint64_t *totalNumFrames;
|
||||
};
|
||||
|
@ -60,20 +60,6 @@ class File : private virtual slsDetectorDefs {
|
||||
return std::vector<DataType>{};
|
||||
};
|
||||
|
||||
virtual void CreateVirtualFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages, const uint32_t nPixelsX,
|
||||
const uint32_t nPixelsY, const uint32_t dynamicRange,
|
||||
const uint64_t numImagesCaught, const int numModX, const int numModY,
|
||||
const DataType dataType, const std::vector<std::string> parameterNames,
|
||||
const std::vector<DataType> parameterDataTypes) {
|
||||
LOG(logERROR) << "This is a generic function CreateVirtualFile that "
|
||||
"should be overloaded by a derived class";
|
||||
}
|
||||
|
||||
virtual void CreateFirstHDF5DataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
@ -85,13 +71,6 @@ class File : private virtual slsDetectorDefs {
|
||||
LOG(logERROR) << "This is a generic function CreateFirstDataFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void LinkDataFile(std::string dataFilename, std::string dataSetname,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const bool silentMode) {
|
||||
LOG(logERROR) << "This is a generic function LinkDataFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
#endif
|
||||
virtual void CreateFirstBinaryDataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
@ -103,27 +82,9 @@ class File : private virtual slsDetectorDefs {
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) {
|
||||
LOG(logERROR) << "This is a generic function CreateMasterFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void WriteToFile(char *buffer, const int buffersize,
|
||||
const uint64_t currentFrameNumber,
|
||||
const uint32_t numPacketsCaught) {
|
||||
LOG(logERROR) << "This is a generic function WriteToFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
|
||||
LOG(logERROR) << "This is a generic function UpdateMasterFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
const uint32_t numPacketsCaught) = 0;
|
||||
|
||||
protected:
|
||||
slsDetectorDefs::fileFormat format_;
|
||||
|
@ -62,6 +62,7 @@ class GeneralData {
|
||||
uint32_t adcEnableMaskOneGiga{BIT32_MASK};
|
||||
uint32_t adcEnableMaskTenGiga{BIT32_MASK};
|
||||
slsDetectorDefs::ROI roi{};
|
||||
uint32_t counterMask{0};
|
||||
|
||||
GeneralData(){};
|
||||
virtual ~GeneralData(){};
|
||||
@ -122,8 +123,8 @@ class GeneralData {
|
||||
ThrowGenericError("SetNumberofInterfaces");
|
||||
};
|
||||
|
||||
virtual void SetNumberofCounters(const int n) {
|
||||
ThrowGenericError("SetNumberofCounters");
|
||||
virtual void SetCounterMask(const int n) {
|
||||
ThrowGenericError("setCounterMask");
|
||||
};
|
||||
|
||||
virtual int GetNumberOfAnalogDatabytes() {
|
||||
@ -359,13 +360,12 @@ class JungfrauData : public GeneralData {
|
||||
|
||||
class Mythen3Data : public GeneralData {
|
||||
private:
|
||||
int ncounters;
|
||||
int ncounters{0};
|
||||
const int NCHAN = 1280;
|
||||
|
||||
public:
|
||||
Mythen3Data() {
|
||||
myDetectorType = slsDetectorDefs::MYTHEN3;
|
||||
ncounters = 3;
|
||||
nPixelsY = 1;
|
||||
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
|
||||
maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE;
|
||||
@ -376,6 +376,7 @@ class Mythen3Data : public GeneralData {
|
||||
defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
|
||||
dynamicRange = 32;
|
||||
tengigaEnable = true;
|
||||
SetCounterMask(0x7);
|
||||
UpdateImageSize();
|
||||
};
|
||||
|
||||
@ -389,7 +390,13 @@ class Mythen3Data : public GeneralData {
|
||||
UpdateImageSize();
|
||||
};
|
||||
|
||||
virtual void SetNumberofCounters(const int n) {
|
||||
virtual void SetCounterMask(const int mask) {
|
||||
int n = __builtin_popcount(mask);
|
||||
if (n < 1 || n > 3) {
|
||||
throw sls::RuntimeError("Invalid number of counters " +
|
||||
std::to_string(n) + ". Expected 1-3.");
|
||||
}
|
||||
counterMask = mask;
|
||||
ncounters = n;
|
||||
UpdateImageSize();
|
||||
};
|
||||
|
@ -112,6 +112,7 @@ void HDF5DataFile::CreateFirstHDF5DataFile(
|
||||
udpPortNumber_ = udpPortNumber;
|
||||
|
||||
switch (dynamicRange_) {
|
||||
case 12:
|
||||
case 16:
|
||||
dataType_ = PredType::STD_U16LE;
|
||||
break;
|
||||
@ -127,7 +128,7 @@ void HDF5DataFile::CreateFirstHDF5DataFile(
|
||||
}
|
||||
|
||||
void HDF5DataFile::CreateFile() {
|
||||
|
||||
numFramesInFile_ = 0;
|
||||
numFilesInAcquisition_++;
|
||||
|
||||
std::ostringstream os;
|
||||
@ -236,7 +237,7 @@ void HDF5DataFile::WriteToFile(char *buffer, const int buffersize,
|
||||
++subFileIndex_;
|
||||
CreateFile();
|
||||
}
|
||||
numFramesInFile_++;
|
||||
++numFramesInFile_;
|
||||
|
||||
// extend dataset (when receiver start followed by many status starts
|
||||
// (jungfrau)))
|
||||
@ -248,8 +249,30 @@ void HDF5DataFile::WriteToFile(char *buffer, const int buffersize,
|
||||
WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer));
|
||||
}
|
||||
|
||||
void HDF5DataFile::Convert12to16Bit(uint16_t *dst, uint8_t *src) {
|
||||
for (int i = 0; i < EIGER_NUM_PIXELS; ++i) {
|
||||
*dst = (uint16_t)(*src++ & 0xFF);
|
||||
*dst++ |= (uint16_t)((*src & 0xF) << 8u);
|
||||
++i;
|
||||
*dst = (uint16_t)((*src++ & 0xF0) >> 4u);
|
||||
*dst++ |= (uint16_t)((*src++ & 0xFF) << 4u);
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
|
||||
char *buffer) {
|
||||
// expand 12 bit to 16 bits
|
||||
char *revBuffer = buffer;
|
||||
if (dynamicRange_ == 12) {
|
||||
revBuffer = (char *)malloc(EIGER_16_BIT_IMAGE_SIZE);
|
||||
if (revBuffer == nullptr) {
|
||||
throw sls::RuntimeError("Could not allocate memory for 12 bit to "
|
||||
"16 bit conversion in object " +
|
||||
std::to_string(index_));
|
||||
}
|
||||
Convert12to16Bit((uint16_t *)revBuffer, (uint8_t *)buffer);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
uint64_t nDimx =
|
||||
@ -266,9 +289,15 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
|
||||
|
||||
dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start);
|
||||
DataSpace memspace(2, dims2);
|
||||
dataSet_->write(buffer, dataType_, memspace, *dataSpace_);
|
||||
dataSet_->write(revBuffer, dataType_, memspace, *dataSpace_);
|
||||
memspace.close();
|
||||
if (dynamicRange_ == 12) {
|
||||
free(revBuffer);
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
if (dynamicRange_ == 12) {
|
||||
free(revBuffer);
|
||||
}
|
||||
LOG(logERROR) << "Could not write to file in object " << index_;
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError("Could not write to file in object " +
|
||||
|
@ -35,6 +35,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
private:
|
||||
void CreateFile();
|
||||
void Convert12to16Bit(uint16_t *dst, uint8_t *src);
|
||||
void WriteDataFile(const uint64_t currentFrameNumber, char *buffer);
|
||||
void WriteParameterDatasets(const uint64_t currentFrameNumber,
|
||||
sls_receiver_header *rheader);
|
||||
@ -72,4 +73,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
|
||||
int detIndex_{0};
|
||||
int numUnitsPerReadout_{0};
|
||||
uint32_t udpPortNumber_{0};
|
||||
|
||||
static const int EIGER_NUM_PIXELS{256 * 2 * 256};
|
||||
static const int EIGER_16_BIT_IMAGE_SIZE{EIGER_NUM_PIXELS * 2};
|
||||
};
|
@ -1,162 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "HDF5MasterFile.h"
|
||||
#include "MasterAttributes.h"
|
||||
|
||||
HDF5MasterFile::HDF5MasterFile(std::mutex *hdf5Lib)
|
||||
: File(HDF5), hdf5Lib_(hdf5Lib) {}
|
||||
|
||||
HDF5MasterFile::~HDF5MasterFile() { CloseFile(); }
|
||||
|
||||
void HDF5MasterFile::CloseFile() {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
if (fd_) {
|
||||
fd_->close();
|
||||
delete fd_;
|
||||
fd_ = nullptr;
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not close master HDF5 handles";
|
||||
error.printErrorStack();
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5MasterFile::LinkDataFile(std::string dataFilename,
|
||||
std::string dataSetname,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const bool silentMode) {
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
|
||||
// open master file
|
||||
H5File masterfd(fileName_.c_str(), H5F_ACC_RDWR,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// open data file
|
||||
H5File fd(dataFilename.c_str(), H5F_ACC_RDONLY,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// create link for data dataset
|
||||
DataSet dset = fd.openDataSet(dataSetname.c_str());
|
||||
std::string linkname = std::string("/entry/data/") + dataSetname;
|
||||
if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(),
|
||||
masterfd.getLocId(), linkname.c_str(),
|
||||
H5P_DEFAULT, H5P_DEFAULT) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not create link to data dataset in master");
|
||||
}
|
||||
|
||||
// create link for parameter datasets
|
||||
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
|
||||
DataSet pDset = fd.openDataSet(parameterNames[i].c_str());
|
||||
linkname = std::string("/entry/data/") + parameterNames[i];
|
||||
if (H5Lcreate_external(dataFilename.c_str(),
|
||||
parameterNames[i].c_str(),
|
||||
masterfd.getLocId(), linkname.c_str(),
|
||||
H5P_DEFAULT, H5P_DEFAULT) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not create link to parameter dataset in master");
|
||||
}
|
||||
}
|
||||
fd.close();
|
||||
masterfd.close();
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError("Could not link in master hdf5 file");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Linked in Master File: " << dataFilename;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5MasterFile::CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) {
|
||||
|
||||
std::ostringstream os;
|
||||
os << filePath << "/" << fileNamePrefix << "_master"
|
||||
<< "_" << fileIndex << ".h5";
|
||||
fileName_ = os.str();
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
fd_ = nullptr;
|
||||
if (!(overWriteEnable))
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
else
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// attributes - version
|
||||
double dValue = HDF5_WRITER_VERSION;
|
||||
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
|
||||
Attribute attribute = fd_->createAttribute(
|
||||
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
|
||||
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
|
||||
|
||||
// Create a group in the file
|
||||
Group group1(fd_->createGroup("entry"));
|
||||
Group group2(group1.createGroup("data"));
|
||||
Group group3(group1.createGroup("instrument"));
|
||||
Group group4(group3.createGroup("beam"));
|
||||
Group group5(group3.createGroup("detector"));
|
||||
Group group6(group1.createGroup("sample"));
|
||||
|
||||
// TODO find a way to get complete group link
|
||||
attrGroupName_ = "/entry/instrument/detector";
|
||||
|
||||
attr->WriteMasterHDF5Attributes(fd_, &group5);
|
||||
fd_->close();
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite master HDF5 handles");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Master File: " << fileName_;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5MasterFile::UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_RDWR,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
Group group = fd_->openGroup(attrGroupName_.c_str());
|
||||
attr->WriteFinalHDF5Attributes(fd_, &group);
|
||||
fd_->close();
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite master HDF5 handles");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Updated Master File";
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
class HDF5MasterFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
HDF5MasterFile(std::mutex *hdf5Lib);
|
||||
~HDF5MasterFile();
|
||||
|
||||
void CloseFile() override;
|
||||
void LinkDataFile(std::string dataFilename, std::string dataSetname,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const bool silentMode) override;
|
||||
void CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) override;
|
||||
void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override;
|
||||
|
||||
private:
|
||||
std::mutex *hdf5Lib_;
|
||||
H5File *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
std::string attrGroupName_;
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user